Skip to content

Routes & Targets

Routes define which events get forwarded to which channel (Discord or Telegram). They are stored in D1 (d1_routes, seeded from the legacy KV config:routes key on first load), managed via the Web UI, the Admin API, or config.example.yaml.

There are no default routes — each route must define its own target. If no routes are configured, no events are forwarded. At most 200 routes can be saved per instance.

Route Schema

json
{
  "id": "unique-route-id",
  "name": "Human-readable name",
  "enabled": true,
  "groupId": "my-group",
  "fallback": false,
  "stop": false,
  "discordRoleIds": ["111111111111111111"],
  "filters": [
    { "type": "event", "match": "push" },
    { "type": "repo", "match": "org/repo", "exclude": false }
  ],
  "targets": [
    {
      "platform": "discord",
      "channelId": "REQUIRED_CHANNEL_ID",
      "threadId": "OPTIONAL_THREAD_ID"
    }
  ]
}

Each entry of targets is a push destination, so one route can forward to several channels at once (e.g. a Discord channel and a Telegram group). target.platform selects the platform: discord (default) or telegram. For Discord, target.channelId is required (a thread in target.threadId is optional). For Telegram, target.chatId (the group/supergroup chat id, e.g. -1001234567890) is required and target.topicId (the message_thread_id of a topic, equivalent of a Discord thread) is optional. There is no fallback to a default channel.

FieldTypeRequiredDescription
groupIdstringYesId of the group this route belongs to
fallbackbooleanNoWhen true, fires only if no non-fallback route matched the event; its own filters are ignored
stopbooleanNoWhen true and this route matches, no further routes are evaluated for this event
discordRoleIdsstring[]NoDiscord role ids to ping when this route fires; applied to Discord targets only
astobjectNoBoolean filter tree ({all:[...]} / {any:[...]} / {not:{...}}); takes precedence over filters when present

Discord Role Mentions

Set discordRoleIds on a route to ping one or more Discord roles (身份组) whenever that route fires. The mention (<@&roleId>) is prepended to the message content of every Discord target of the route; Telegram targets ignore this field. Mentions only trigger notifications when the bot has the Mention Everyone permission (or the role is marked mentionable), and the bot must be able to see the role.

json
{
  "id": "release-notify",
  "name": "Notify on Release",
  "enabled": true,
  "groupId": "default",
  "discordRoleIds": ["111111111111111111", "222222222222222222"],
  "filters": [{ "type": "event", "match": "release" }],
  "targets": [{ "platform": "discord", "channelId": "REQUIRED_CHANNEL_ID" }]
}

You can add role ids in the admin console under Discord role mentions.

Filters

Every route carries a filters array (all must match — AND logic). When the route has an ast field (a nested all/any/not tree), it is evaluated instead of filters, so it can express arbitrary boolean combinations. See the Filter Types reference and the Filter Tutorial.

Custom Route Example

json
[
  {
    "id": "backend-prs",
    "name": "Backend PRs",
    "enabled": true,
    "groupId": "backend-team",
    "filters": [
      { "type": "repo", "match": "myorg/backend" },
      { "type": "event", "match": "pull_request" },
      { "type": "actor", "match": "[bot]", "exclude": true }
    ],
    "targets": [
      {
        "platform": "telegram",
        "chatId": "-1001234567890",
        "topicId": "9876543210"
      }
    ]
  }
]

Released under the MIT License.