Feature: Message Scheduling
Relevant source files
The following files were used as context for generating this wiki page:The Message Scheduling feature is a core component of Heyme, enabling the application to send recorded video messages to users on a specified future date. This system is responsible for checking daily for scheduled messages, composing personalized emails, and dispatching them to the intended recipients. The process is handled by a dedicated API endpoint designed to be triggered by a scheduled task.
This feature allows users to "send a message to the future," which they can watch later to reflect on their past goals and progress. The key technologies involved are a MySQL database for storing message metadata, the Zeptomail service for sending transactional emails, and a Next.js API route that orchestrates the entire process.
Sources: README.md, pages/api/dispatch.ts, config/site.ts:10-11
System Architecture and Data Flow
The scheduling system is centered around the /api/dispatch API endpoint. This endpoint is designed to be called periodically (e.g., by a cron job) to initiate the email dispatch process for the current day.
The overall flow is as follows:
- A scheduled trigger invokes the
/api/dispatchendpoint. - The API handler connects to the MySQL database.
- It queries the
Videostable for all records where thesend_atdate matches the current date. - For each video found, it checks if the message has already been sent.
- If not sent, it constructs a personalized email using an HTML template.
- The email is sent to the recipient via the Zeptomail API.
- The video's record in the database is updated to mark it as sent.
- After processing all videos, the database connection is closed.
Sources: pages/api/dispatch.ts:38-100, README.md
Sequence Diagram
This diagram illustrates the sequence of interactions between the scheduler, the Heyme API, the database, and the email service.
Sources: pages/api/dispatch.ts:38-100
API Endpoint: /api/dispatch
This is the sole API endpoint responsible for the message dispatching logic. It is a Next.js API route.
| Property | Value | Description |
|---|---|---|
| Path | /api/dispatch | The endpoint that triggers the email dispatch process. |
| Method | GET (inferred) | The handler does not check for a specific HTTP method. |
| Response | 200 OK with [] | Returns an empty array upon completion, regardless of how many emails are sent. |
Sources: pages/api/dispatch.ts:38-101
Core Logic Flowchart
The handleDispatchEmails function contains the primary logic for the endpoint.
Sources: pages/api/dispatch.ts:38-100
Database Interaction
The feature relies on a MySQL database and uses the knex query builder to interact with it. The primary table involved is Videos.
*Sources: pages/api/dispatch.ts:7, package.json:39
Videos Table Schema (Inferred)
The schema for the Videos table can be inferred from its usage in pages/api/dispatch.ts and pages/watch/[id].tsx.
| Column | Type (Inferred) | Description |
|---|---|---|
id | INTEGER | Primary key for the video record. Used in the watch URL. |
send_at | DATE | The date the message is scheduled to be sent. Format: YYYY-MM-DD. |
sent | BOOLEAN / TINYINT | A flag (0 or 1) to indicate if the email has been dispatched. |
email | VARCHAR | The recipient's email address. |
send_to | VARCHAR | Indicates if the message is to "yourself" or someone else. |
created_at | DATETIME | Timestamp when the video message was created. |
video_url | VARCHAR | The URL of the stored video file. |
Sources: pages/api/dispatch.ts:29, 34, 50, 61, 70, pages/watch/[id].tsx:11, 23, 76
Key Database Functions
The dispatch.ts file defines several helper functions for database operations.
| Function | Description |
|---|---|
createMysqlConnection() | Utility function to establish a connection to the MySQL database. |
fetchAllVideosForToday(conn) | Selects all records from the Videos table where send_at is today. |
updateVideoToSent(conn, id) | Updates the sent column to 1 for a given video id. |
fetchVideoById(conn, id) | Selects a single video record by its id. Used on the watch page. |
Sources: pages/api/dispatch.ts:28-36, pages/watch/[id].tsx:69
Email Generation and Dispatch
Emails are generated from a static HTML template and sent using the Zeptomail service.
*Sources: pages/api/dispatch.ts:8, 11-23, package.json:62
Email Template
An HTML file serves as the template for the dispatched emails. Placeholders are dynamically replaced with video-specific data.
Template File: public/mails/email.html
Placeholders:
| Placeholder | Replaced With |
|---|---|
{{REPLACE_WATCH_LINK_HERE}} | The unique URL to watch the video, e.g., https://heyme.io/watch/{video.id}. |
{{REPLACE_GREETING_HERE}} | A dynamic greeting based on whether the user sent the message to themselves or someone else. |
{{REPLACE_BODY_HERE}} | A static body text linking to the Heyme website. |
{{REPLACE_OUTRO_HERE}} | A static closing message. |
Sources: public/mails/email.html:276, 283, 357, 364, pages/api/dispatch.ts:15-18
The logic for replacing these placeholders is contained in the getEmailContent function, which is also tested to ensure correctness.
Sources: pages/api/dispatch.ts:11-23, tests/api/dispatch.spec.ts:6-23
Email Content Logic
The subject and greeting of the email are customized based on the send_to field of the video record.
- If
send_tois "yourself":- Subject:
You sent yourself a message from the past. Check it out. - Greeting:
Do you still remember sending yourself a message on {creation_date}?
- Subject:
- If
send_tois not "yourself":- Subject:
Someone sent you a message from the past. Check it out. - Greeting:
Someone sent you a message on {creation_date}
- Subject:
Sources: pages/api/dispatch.ts:81-91
Summary
The Message Scheduling feature is a well-defined, automated system that reliably delivers video messages on user-specified dates. It leverages a serverless function, a relational database, and a third-party email service to create a "time capsule" experience. The logic is contained within the /api/dispatch endpoint, which handles fetching, processing, and marking video messages for daily delivery.