Description
Allow cronjob scheduled messages to target DMs (direct messages) in addition to channels/threads, and support gateway-connected platforms (Telegram, LINE, Feishu, Google Chat, etc.) as delivery targets — not just Discord and Slack.
Use Case
As an operator, I want to receive scheduled prompts (daily summaries, reminders) as a DM rather than in a shared channel. Currently channel is required and only Discord/Slack channel IDs are supported. There is no way to send a cron message to:
- A Discord DM with a specific user
- A Telegram chat, LINE conversation, or Feishu DM via the custom gateway
This forces users to create private channels as a workaround for personal scheduled messages, and completely blocks cron usage for gateway-connected platforms.
Proposed Solution
Introduce a target_type field to distinguish delivery targets. The existing channel field is repurposed as target_id (with channel kept as an alias for backward compatibility).
Field Definition
| Field |
Required |
Default |
Description |
target_type |
|
"channel" |
"channel" — post to a channel (current behavior). "thread" — post to an existing thread. "dm" — open/reuse a DM with a user. |
target_id |
✅ |
— |
The ID of the target. Interpretation depends on target_type and platform. |
channel |
|
— |
Alias for target_id (backward compat). If both are set, target_id takes precedence. |
thread_id |
|
— |
When target_type = "channel", optionally post into this thread (existing behavior). |
Examples
1. Channel (current behavior, unchanged)
Post to a Discord channel — creates a new thread for the agent reply:
[[cron.jobs]]
schedule = "0 9 * * 1-5"
platform = "discord"
target_type = "channel" # default, can be omitted
target_id = "1490282656913559673" # Discord channel ID
message = "summarize yesterday merged PRs"
sender_name = "DailyOps"
timezone = "Asia/Taipei"
2. Existing thread
Post into a specific existing thread:
[[cron.jobs]]
schedule = "0 9 * * 1-5"
platform = "discord"
target_type = "thread"
target_id = "1506450748169523282" # Discord thread ID
message = "daily standup reminder"
sender_name = "StandupBot"
timezone = "Asia/Taipei"
3. Discord DM
Send a DM to a specific Discord user:
[[cron.jobs]]
schedule = "0 8 * * 1-5"
platform = "discord"
target_type = "dm"
target_id = "845835116920307722" # Discord user ID
message = "good morning! here is your daily agenda"
sender_name = "MorningBot"
timezone = "Asia/Taipei"
OAB calls the Discord API to open (or reuse) a DM channel with the user, then sends the message there.
4. Gateway — Telegram DM
Send via the custom gateway to a Telegram user:
[[cron.jobs]]
schedule = "0 9 * * 1-5"
platform = "gateway"
target_type = "dm"
target_id = "123456789" # Telegram user/chat ID
message = "daily security scan report"
sender_name = "SecurityBot"
timezone = "UTC"
5. Gateway — LINE DM
Send via the custom gateway to a LINE user:
[[cron.jobs]]
schedule = "0 18 * * 1-5"
platform = "gateway"
target_type = "dm"
target_id = "U1234567890abcdef" # LINE user ID
message = "end of day summary"
sender_name = "EODBot"
timezone = "Asia/Taipei"
6. Gateway — Feishu group chat
Send to a Feishu group chat:
[[cron.jobs]]
schedule = "0 9 * * 1-5"
platform = "gateway"
target_type = "channel"
target_id = "oc_abcdef123456" # Feishu chat_id
message = "weekly team sync reminder"
sender_name = "TeamBot"
timezone = "Asia/Shanghai"
7. Backward compatibility (existing config still works)
[[cron.jobs]]
schedule = "0 9 * * 1-5"
channel = "1490282656913559673" # old field, treated as target_id with target_type="channel"
message = "summarize yesterday merged PRs"
Routing Logic
fire_cronjob()
│
├─ platform = "discord" or "slack"
│ ├─ target_type = "channel" → post to channel (create thread) [existing behavior]
│ ├─ target_type = "thread" → post into existing thread
│ └─ target_type = "dm" → open DM channel with user, post there
│
└─ platform = "gateway"
│ Emit GatewayEvent over WebSocket to custom gateway
├─ target_type = "channel" → gateway routes to group/channel
├─ target_type = "dm" → gateway routes to 1:1 DM
└─ target_type = "thread" → gateway routes to thread/topic
The gateway uses target_id + platform credentials to call the appropriate API (Telegram sendMessage, LINE Push API, Feishu send_message, etc.).
Prior Art
- The gateway custom webhook already supports triggering agents from external cron jobs via
curl -X POST (documented in gateway/README.md). This FR brings that capability into the native config-driven scheduler.
- Discord.js bots commonly support DM targets for scheduled messages via
user.send().
- Discord API:
POST /users/@me/channels with recipient_id to create/get a DM channel.
Related Issues
Description
Allow cronjob scheduled messages to target DMs (direct messages) in addition to channels/threads, and support gateway-connected platforms (Telegram, LINE, Feishu, Google Chat, etc.) as delivery targets — not just Discord and Slack.
Use Case
As an operator, I want to receive scheduled prompts (daily summaries, reminders) as a DM rather than in a shared channel. Currently
channelis required and only Discord/Slack channel IDs are supported. There is no way to send a cron message to:This forces users to create private channels as a workaround for personal scheduled messages, and completely blocks cron usage for gateway-connected platforms.
Proposed Solution
Introduce a
target_typefield to distinguish delivery targets. The existingchannelfield is repurposed astarget_id(withchannelkept as an alias for backward compatibility).Field Definition
target_type"channel""channel"— post to a channel (current behavior)."thread"— post to an existing thread."dm"— open/reuse a DM with a user.target_idtarget_typeandplatform.channeltarget_id(backward compat). If both are set,target_idtakes precedence.thread_idtarget_type = "channel", optionally post into this thread (existing behavior).Examples
1. Channel (current behavior, unchanged)
Post to a Discord channel — creates a new thread for the agent reply:
2. Existing thread
Post into a specific existing thread:
3. Discord DM
Send a DM to a specific Discord user:
OAB calls the Discord API to open (or reuse) a DM channel with the user, then sends the message there.
4. Gateway — Telegram DM
Send via the custom gateway to a Telegram user:
5. Gateway — LINE DM
Send via the custom gateway to a LINE user:
6. Gateway — Feishu group chat
Send to a Feishu group chat:
7. Backward compatibility (existing config still works)
Routing Logic
The gateway uses
target_id+ platform credentials to call the appropriate API (Telegram sendMessage, LINE Push API, Feishu send_message, etc.).Prior Art
curl -X POST(documented ingateway/README.md). This FR brings that capability into the native config-driven scheduler.user.send().POST /users/@me/channelswithrecipient_idto create/get a DM channel.Related Issues