Skip to main content

Overview

Schedule messages to be sent automatically at a future time. You can create one-time scheduled messages or set up recurring messages that repeat hourly, daily, weekly, monthly, or yearly.

One-Time Scheduled Message

Schedule a message to send once at a specific time:
import { createSDK, handleError } from "./utils";

const CHAT_GUID = process.env.CHAT_GUID || "any;-;+1234567890";

async function main() {
    const sdk = createSDK();

    sdk.on("ready", async () => {
        try {
            // Schedule message for 3 seconds from now
            const scheduledFor = Date.now() + 3 * 1000;

            const scheduled = await sdk.scheduledMessages.createScheduledMessage({
                type: "send-message",
                payload: {
                    chatGuid: CHAT_GUID,
                    message: "This is a scheduled message!",
                    method: "apple-script",
                },
                scheduledFor,
                schedule: { type: "once" },
            });

            console.log(`scheduled: ${scheduled.id}`);
            console.log(`for: ${new Date(scheduledFor).toLocaleString()}`);
        } catch (error) {
            handleError(error, "Failed to schedule message");
        }

        await sdk.close();
        process.exit(0);
    });

    await sdk.connect();
}

main().catch(console.error);

Recurring Scheduled Messages

Create messages that send automatically on a recurring schedule:
import { createSDK, handleError } from "./utils";

const CHAT_GUID = process.env.CHAT_GUID || "any;-;+1234567890";

async function main() {
    const sdk = createSDK();

    sdk.on("ready", async () => {
        try {
            const tomorrow9am = new Date();
            tomorrow9am.setDate(tomorrow9am.getDate() + 1);
            tomorrow9am.setHours(9, 0, 0, 0);

            const daily = await sdk.scheduledMessages.createScheduledMessage({
                type: "send-message",
                payload: {
                    chatGuid: CHAT_GUID,
                    message: "Good morning!",
                    method: "apple-script",
                },
                scheduledFor: tomorrow9am.getTime(),
                schedule: {
                    type: "recurring",
                    intervalType: "daily", // hourly, daily, weekly, monthly, yearly
                    interval: 1,
                },
            });

            console.log(`scheduled: ${daily.id}`);
            console.log(`first: ${tomorrow9am.toLocaleString()}`);
            console.log(`repeats: every day`);
        } catch (error) {
            handleError(error, "Failed to schedule recurring message");
        }

        await sdk.close();
        process.exit(0);
    });

    await sdk.connect();
}

main().catch(console.error);

Schedule Parameters

One-Time Schedule

type
string
required
Must be "send-message"
payload
object
required
  • chatGuid - The chat to send to
  • message - The message text
  • method - Set to "apple-script" or "private-api"
scheduledFor
number
required
Unix timestamp (milliseconds) when the message should send
schedule
object
required
{ type: "once" }

Recurring Schedule

schedule.type
string
required
Must be "recurring"
schedule.intervalType
string
required
  • "hourly" - Repeat every N hours
  • "daily" - Repeat every N days
  • "weekly" - Repeat every N weeks
  • "monthly" - Repeat every N months
  • "yearly" - Repeat every N years
schedule.interval
number
required
How many intervals between each occurrence (e.g., 2 for every 2 days)

Common Scheduling Patterns

// Send every day at 9 AM
const tomorrow9am = new Date();
tomorrow9am.setDate(tomorrow9am.getDate() + 1);
tomorrow9am.setHours(9, 0, 0, 0);

await sdk.scheduledMessages.createScheduledMessage({
    type: "send-message",
    payload: {
        chatGuid: CHAT_GUID,
        message: "Daily standup reminder!",
        method: "apple-script",
    },
    scheduledFor: tomorrow9am.getTime(),
    schedule: {
        type: "recurring",
        intervalType: "daily",
        interval: 1,
    },
});

Managing Scheduled Messages

List All Scheduled Messages

const scheduled = await sdk.scheduledMessages.getScheduledMessages();

scheduled.forEach(msg => {
    console.log(`ID: ${msg.id}`);
    console.log(`Next: ${new Date(msg.scheduledFor).toLocaleString()}`);
    console.log(`Type: ${msg.schedule.type}`);
    console.log();
});

Cancel a Scheduled Message

// Cancel by ID
await sdk.scheduledMessages.deleteScheduledMessage("message-id");

console.log("Scheduled message cancelled");

Update a Scheduled Message

// Get the scheduled message
const scheduled = await sdk.scheduledMessages.getScheduledMessage("message-id");

// Delete the old one
await sdk.scheduledMessages.deleteScheduledMessage("message-id");

// Create a new one with updated details
await sdk.scheduledMessages.createScheduledMessage({
    type: "send-message",
    payload: {
        ...scheduled.payload,
        message: "Updated message text",
    },
    scheduledFor: Date.now() + 60000, // New time
    schedule: scheduled.schedule,
});

Advanced Examples

Business Hours Reminder

// Send every weekday at 9 AM
const nextWeekday = new Date();
let daysToAdd = 1;

// Find next weekday
while (true) {
    nextWeekday.setDate(nextWeekday.getDate() + daysToAdd);
    const day = nextWeekday.getDay();
    if (day !== 0 && day !== 6) break; // Not weekend
    daysToAdd = 1;
}

nextWeekday.setHours(9, 0, 0, 0);

await sdk.scheduledMessages.createScheduledMessage({
    type: "send-message",
    payload: {
        chatGuid: CHAT_GUID,
        message: "Good morning! Ready for the workday?",
        method: "apple-script",
    },
    scheduledFor: nextWeekday.getTime(),
    schedule: {
        type: "recurring",
        intervalType: "daily",
        interval: 1,
    },
});

Medication Reminder

// Every 8 hours
const firstDose = new Date();
firstDose.setHours(firstDose.getHours() + 1, 0, 0, 0);

await sdk.scheduledMessages.createScheduledMessage({
    type: "send-message",
    payload: {
        chatGuid: CHAT_GUID,
        message: "Time to take your medication!",
        method: "apple-script",
    },
    scheduledFor: firstDose.getTime(),
    schedule: {
        type: "recurring",
        intervalType: "hourly",
        interval: 8,
    },
});

Meeting Reminder Chain

const meetingTime = new Date("2026-03-10T14:00:00");

// 1 day before
await sdk.scheduledMessages.createScheduledMessage({
    type: "send-message",
    payload: {
        chatGuid: CHAT_GUID,
        message: "Meeting tomorrow at 2 PM!",
        method: "apple-script",
    },
    scheduledFor: meetingTime.getTime() - 24 * 60 * 60 * 1000,
    schedule: { type: "once" },
});

// 1 hour before
await sdk.scheduledMessages.createScheduledMessage({
    type: "send-message",
    payload: {
        chatGuid: CHAT_GUID,
        message: "Meeting in 1 hour!",
        method: "apple-script",
    },
    scheduledFor: meetingTime.getTime() - 60 * 60 * 1000,
    schedule: { type: "once" },
});

// 5 minutes before
await sdk.scheduledMessages.createScheduledMessage({
    type: "send-message",
    payload: {
        chatGuid: CHAT_GUID,
        message: "Meeting starting in 5 minutes!",
        method: "apple-script",
    },
    scheduledFor: meetingTime.getTime() - 5 * 60 * 1000,
    schedule: { type: "once" },
});

Send Method Options

method
string
default:"apple-script"
  • "apple-script" - Uses AppleScript (more reliable, recommended)
  • "private-api" - Uses Private API (faster but requires Private API enabled)

Best Practices

Store the returned ID to manage scheduled messages later:
const scheduled = await sdk.scheduledMessages.createScheduledMessage({...});
console.log(`Created: ${scheduled.id}`);
// Store scheduled.id in your database
JavaScript Date objects use local timezone. Be explicit:
// Specific time in UTC
const utcTime = new Date("2026-03-10T14:00:00Z");

// Specific time in local timezone
const localTime = new Date("2026-03-10T14:00:00");
Ensure scheduled time is in the future:
const scheduledFor = Date.now() + 60000;

if (scheduledFor > Date.now()) {
    await sdk.scheduledMessages.createScheduledMessage({...});
} else {
    console.error("Time must be in the future");
}
Scheduled messages require the SDK server to be running. If the server is offline when a message is scheduled to send, it will be sent when the server comes back online.
For production use, implement a database to track scheduled messages and their purposes.

Next Steps

Auto-Reply Bot

Combine with auto-replies

Message Effects

Schedule messages with effects

Build docs developers (and LLMs) love