Text triggers

Auto-responses the Zyron bot sends when a member's message matches a phrase — plain text or an embed, optionally restricted to channels, granting roles, rate-limited, and more.

All paths are relative to https://api.zyron.pro/api/v1/guilds/:guildId.

List triggers

GET/guilds/:guildId/triggers

Returns the guild's triggers along with the limits that apply when writing them back.

json
{
  "triggers": [
    {
      "_id": "665f1c2ab8d3e14f2a9b1c00",
      "phrase": "!discord",
      "response": "Join our Discord: https://discord.gg/example",
      "matchMode": "exact",
      "enabled": true,
      "embed": null,
      "roleIds": [],
      "channelIds": [],
      "cooldownSeconds": 0,
      "replyMode": "reply",
      "deleteTrigger": false,
      "allowedRoleIds": [],
      "requiredPermission": null,
      "allowedUserIds": []
    },
    {
      "_id": "665f1c2ab8d3e14f2a9b1c01",
      "phrase": "^gg\\s+(wp|ez)$",
      "response": "",
      "matchMode": "regex",
      "enabled": true,
      "embed": {
        "author": { "name": "", "iconUrl": "", "url": "" },
        "color": "#1c3148",
        "title": "Good game!",
        "description": "See you in the next round.",
        "image": "",
        "thumbnail": "",
        "footer": ""
      },
      "roleIds": ["123456789012345678"],
      "channelIds": ["234567890123456789"],
      "cooldownSeconds": 30,
      "replyMode": "channel",
      "deleteTrigger": false,
      "allowedRoleIds": [],
      "requiredPermission": "ManageMessages",
      "allowedUserIds": []
    }
  ],
  "limits": {
    "maxTriggers": 25,
    "maxPhrase": 200,
    "maxResponse": 2000,
    "maxRoles": 10,
    "maxChannels": 25,
    "maxCooldownSeconds": 86400
  }
}

Replace triggers

PUT/guilds/:guildId/triggers

Full replacement — the body's triggers array becomes the guild's complete trigger list. Send an empty array to remove all triggers. Every field except phrase is optional; omitted fields fall back to the defaults shown below.

FieldTypeDescription
triggersrequiredobject[]The new trigger list (max 25 entries).
triggers[]._idstringEcho the id from GET to keep a trigger's identity (its cooldown state) across updates. Omit for new triggers.
triggers[].phraserequiredstringThe text to match, max 200 characters. For regex mode this is the pattern (validated on save, applied case-insensitively).
triggers[].responsestringWhat the bot sends, max 2000 characters. Optional when embed is set — but every trigger needs a response, an embed, or both.
triggers[].matchMode"exact" | "contains" | "startsWith" | "regex"exact matches the whole message, contains anywhere in it, startsWith the beginning, and regex tests the phrase as a regular expression. Defaults to contains.
triggers[].enabledbooleanDisabled triggers are kept but never fire. Defaults to true.
triggers[].embedobject | nullAn embed to send with (or instead of) the text response — see Embed responses.
triggers[].roleIdsstring[]Roles granted to the message author on match (max 10). The roles must sit below Zyron's role.
triggers[].channelIdsstring[]Channels the trigger fires in (max 25). An empty array means every channel.
triggers[].cooldownSecondsnumberMinimum seconds between responses for this trigger, 086400. While cooling down, matches are ignored. Defaults to 0 (no cooldown).
triggers[].replyMode"reply" | "channel"reply replies to the triggering message; channel posts a standalone message. Defaults to reply.
triggers[].deleteTriggerbooleanDelete the triggering message after responding (needs the Manage Messages permission). Defaults to false.
triggers[].allowedRoleIdsstring[]Roles allowed to trigger it — an access gate, distinct from roleIds (which grants roles). Empty means no role gate. See Who can trigger it.
triggers[].requiredPermissionstring | nullA single Discord permission the author must hold — one of Administrator, ManageGuild, ManageChannels, ManageRoles, ManageMessages, KickMembers, BanMembers, or ModerateMembers. Defaults to null (no permission gate).
triggers[].allowedUserIdsstring[]User IDs allowed to trigger it. Empty means no user gate. See Who can trigger it.
curl -X PUT https://api.zyron.pro/api/v1/guilds/123456789012345678/triggers \
  -H "Authorization: Bearer zyr_your_guild_key" \
  -H "Content-Type: application/json" \
  -d '{
    "triggers": [
      {
        "phrase": "!discord",
        "response": "Join our Discord: https://discord.gg/example",
        "matchMode": "exact",
        "enabled": true,
        "cooldownSeconds": 30
      }
    ]
  }'

PUT replaces the whole list

Embed responses

The embed object has the shape { author: { name, iconUrl, url }, color, title, description, image, thumbnail, footer } — all strings, all optional. An embed with no content at all is stored as null. When both response and embed are set, the bot sends them in one message.

Who can trigger it

By default a trigger fires for anyone whose message matches. Three optional gates narrow that down — allowedRoleIds, requiredPermission, and allowedUserIds. Leave all three empty (the default) and nothing changes: anyone can trigger it.

Set any of them and the message author must satisfy at least one gate for the trigger to fire — hold one of the allowedRoleIds, be listed in allowedUserIds, or hold the requiredPermission. The gates are combined with OR, not AND, so clearing any single one is enough.

Limits

Max 25 triggers per guild, 200 characters per phrase, 2000 characters per response, 10 roles and 25 channels per trigger, cooldowns up to 86400 seconds. The current limits are always echoed in the limits object on GET /triggers.

Errors

400 invalid_request when a limit is exceeded, a phrase is empty, a trigger has neither response nor embed, a regex phrase doesn't compile, an id in roleIds/channelIds/allowedRoleIds/allowedUserIds isn't a valid snowflake, or requiredPermission isn't one of the accepted values. See Errors for the shared codes.