Skip to main content
The BlueBubbles SDK lets you schedule messages to be sent once at a specific future time, or repeatedly on an hourly, daily, weekly, monthly, or yearly cadence. All scheduling operations live on client.messages and communicate with the server’s built-in scheduler. Once registered, the server handles delivery autonomously — your app doesn’t need to stay connected.
Scheduled messages require BlueBubbles Server 1.4.0 or later. Upgrade your server before using any of the methods in this guide.

Schedule a one-time message

Use scheduleAMessage() to queue a message for delivery at a specific future timestamp. Set schedule.type to "once" and provide a milliseconds-since-epoch value in scheduledFor.
import { BlueBubblesClient } from "bluebubbles-sdk";

const client = new BlueBubblesClient({
  BASE: "http://your-server:1234",
  PASSWORD: "your-server-password",
});

// Schedule a message for 9:00 AM on November 14, 2024
const sendAt = new Date("2024-11-14T09:00:00").getTime();

await client.messages.scheduleAMessage({
  requestBody: {
    type: "send-message",
    payload: {
      chatGuid: "iMessage;-;+15551234567",
      message: "Good morning! Don't forget our call at 10.",
      method: "private-api",
    },
    scheduledFor: sendAt,
    schedule: {
      type: "once",
    },
  },
});
If a one-time scheduled message is missed — for example because the BlueBubbles Server was offline at the scheduled time — the message will not be sent. It will not be retried. Use recurring schedules if reliability across restarts matters for your use case.

Request body fields

FieldTypeDescription
typestringAction type. Always "send-message"
payloadobjectMessage parameters, mirroring the sendText() body (chatGuid, message, method, etc.)
scheduledFornumberDelivery time as milliseconds since Unix epoch. Must be in the future
scheduleobjectScheduling configuration. For one-time: { "type": "once" }

Schedule a recurring message

Set schedule.type to "recurring" and add intervalType and interval to repeat the message on a defined cadence.
// Send "Good morning!" every day at 8:00 AM, starting tomorrow
const firstSend = new Date();
firstSend.setDate(firstSend.getDate() + 1);
firstSend.setHours(8, 0, 0, 0);

await client.messages.scheduleAMessage({
  requestBody: {
    type: "send-message",
    payload: {
      chatGuid: "iMessage;-;+15551234567",
      message: "Good morning!",
      method: "private-api",
    },
    scheduledFor: firstSend.getTime(),
    schedule: {
      type: "recurring",
      intervalType: "daily",
      interval: 1,
    },
  },
});

Recurring schedule fields

FieldTypeDescription
typestring"recurring"
intervalTypestringHow to measure the interval. One of: hourly, daily, weekly, monthly, yearly
intervalnumberHow many units between sends. 1 means every day, 2 means every other day, etc.

Interval type examples

intervalTypeintervalBehavior
hourly2Every 2 hours
daily1Every day
weekly2Every 2 weeks
monthly1Every month
yearly1Every year
When a recurring message fires, the server calculates the next scheduled time before sending the current message. This keeps the cadence consistent even if delivery takes a moment. If a recurring message is missed because the server was offline, it will not be sent for that interval — the next fire time is rescheduled to the next occurrence in the future.

List all scheduled messages

getScheduledMessages() returns all scheduled messages, including past ones. Use this to display pending schedules or audit delivery history.
const scheduled = await client.messages.getScheduledMessages();
console.log(scheduled.data); // Array of scheduled message objects

Fetch a single scheduled message

Use getScheduledMessageById() to retrieve the details of one specific scheduled message by its numeric ID:
const schedule = await client.messages.getScheduledMessageById({
  id: "42",
});

console.log(schedule.data.scheduledFor); // The next delivery timestamp
console.log(schedule.data.schedule);     // The schedule configuration

Update a scheduled message

updateAScheduledMessageById() replaces the payload or timing of an existing scheduled message. Pass the same request body shape as scheduleAMessage():
const newTime = new Date("2024-12-01T10:00:00").getTime();

await client.messages.updateAScheduledMessageById({
  id: "42",
  requestBody: {
    type: "send-message",
    payload: {
      chatGuid: "iMessage;-;+15551234567",
      message: "Updated: our call moved to 11 AM.",
      method: "private-api",
    },
    scheduledFor: newTime,
    schedule: {
      type: "once",
    },
  },
});

Delete a scheduled message

Use deleteScheduledMessageById() to cancel and remove a scheduled message before it fires:
await client.messages.deleteScheduledMessageById({
  id: "42",
});
Once deleted, the message will not be sent. There is no way to restore a deleted schedule — create a new one with scheduleAMessage() if needed.

Full example: morning standup reminder

This example schedules a daily 9 AM standup reminder in a group chat, then verifies the schedule was created:
import { BlueBubblesClient } from "bluebubbles-sdk";

const client = new BlueBubblesClient({
  BASE: "http://your-server:1234",
  PASSWORD: "your-server-password",
});

// First send: next Monday at 9:00 AM
const nextMonday = new Date();
nextMonday.setDate(nextMonday.getDate() + ((1 + 7 - nextMonday.getDay()) % 7));
nextMonday.setHours(9, 0, 0, 0);

await client.messages.scheduleAMessage({
  requestBody: {
    type: "send-message",
    payload: {
      chatGuid: "iMessage;+;group-chat-guid",
      message: "Good morning team! Standup in 5 minutes. 🚀",
      method: "apple-script",
    },
    scheduledFor: nextMonday.getTime(),
    schedule: {
      type: "recurring",
      intervalType: "weekly",
      interval: 1,
    },
  },
});

// Confirm it was created
const all = await client.messages.getScheduledMessages();
console.log(`${all.data.length} message(s) scheduled.`);