Discord Action
Drives a Discord server from a flow. Seventeen operations grouped the way the panel groups them — messages, channels, threads, direct messages, and members & roles — so a flow can post a release note, open a thread for the discussion, and hand someone a role when they react.
Setup
Pick a Discord credential: a bot token (your own bot), an OAuth connection (HostWebhook's app, installed in one server with Add to Discord), or an incoming webhook. The kind you pick decides which operations are available. A webhook can post, and it can get, edit and delete the messages it posted itself — only those, and only in its own channel. It cannot react, pin, open threads, send DMs, quote-reply, answer a slash command or touch channels and roles, so the operation list narrows to match.
Mode — action or AI toolkit
The Mode selector decides who drives the node. In Action mode you pick one operation and fill its fields, and the node does that every time it runs. In AI toolkit mode the operations become tools an AI Node can call, and the model chooses which one and with what arguments.
What the agent has to say
- The server is optional. No Discord tool requires
guildId. When the model leaves it out, the tool uses the server HostWebhook's app was installed in (an OAuth connection). Your own bot can sit in several servers, so with a bot token the model still names the server when the operation needs one. - The channel comes from the trigger. When the run started from a Discord trigger, the event's
channelIdfills the tool'schannelIdif the model leaves it out. If the model picks a channel — "post it in #general" — its choice wins. - Templates never touch what the model writes. A
{{…}}in the model's text reaches Discord as is. One thing is converted: models often write a line break as a literal\n, so in toolkit mode the\n,\rand\tthe model wrote become real line breaks and tabs — the same in a message, a DM and an edit.
Operations
The Operation dropdown decides what the node does and which fields appear under it. These are the exact values the API validates against:
| Value | In the dropdown | What it does |
|---|---|---|
| sendMessage | Send message | Post text/embed to a channel or thread. Optional reply-to + threadId. |
| editMessage | Edit message | Edit content/embeds of a message the bot (or the webhook) posted. |
| deleteMessage | Delete message | Delete by id. Messages from other users need Manage Messages. |
| getMessage | Get message | Fetch a single message plus its reactions and attachments. |
| addReaction | Add reaction | React as the bot. Custom emoji format: name:id. |
| removeReaction | Remove reaction | Remove the reaction the bot itself added. |
| pinMessage | Pin message | Pin a message in its channel. Needs Pin Messages (Discord split it from Manage Messages, which no longer pins). |
| createChannel | Create channel | Create text/voice/forum/announcement/category in a guild. |
| editChannel | Edit channel | Rename, change topic, slowmode, parent category. |
| deleteChannel | Delete channel | Permanently deletes a channel — irreversible. |
| getChannel | Get channel | Fetch the full config and permissions of a channel. |
| listChannels | List channels | Iterate every channel in a guild — output is iterable. |
| createThread | Create thread | Off a message OR standalone (public/private/announcement). |
| sendDM | Send DM | Direct message a user by id. Fails with 403 if they don't accept DMs. |
| addRole | Add role to member | The role of the bot must be ABOVE the target role in the hierarchy. |
| removeRole | Remove role from member | Same hierarchy rule applies. |
| getMember | Get member | Fetch the nick, roles, joined_at and user object of a member. |
Replying to a slash command
When a Discord trigger fires on a slash command, HostWebhook answers Discord at once and the user sees Bot is thinking… while the flow runs. Send message with Reply inline to slash command on — the default — replaces that line with your message instead of posting a separate one.
- Only the command that started this run. The reply goes to the interaction in this run's own trigger event — never to another run's command, another user's or another flow's. Two people typing
/aska second apart each get their own answer. - No command, normal post. A run that did not start from a slash command — a mention, a schedule, a webhook — posts in Channel ID as usual, whatever the switch says.
- 15 minutes. Discord keeps a command open for a reply for 15 minutes. A run that reaches this node later — after a Delay or an approval, say — posts in Channel ID instead. The same happens when Discord no longer accepts the reply (it answers 401 or 404, as it does for the example event of a Test push). Keep Channel ID filled, e.g.
{{payload.channelId}}from the trigger, so there is somewhere to post. A reply Discord refuses never marks your Discord credential as failing. - If a Discord Action fails in a run started by a slash command, the Bot is thinking… line of that run's command becomes ⚠️ Pipeline error and the reason, so the user is not left waiting. It only ever touches that run's own command.
- Not with a webhook credential. Answering a command belongs to the application, so the switch is not offered there.
Text is sent as typed
Every field takes templates — {{payload.content}}, {{payload.options.question}} — and fills them in as text. What you typed is what Discord receives:
- A message that starts with
[or{stays as you wrote it. Values put into it go in as they are — quotes and line breaks are not escaped as JSON. - A
\ntyped in a field stays as those two characters, so Windows paths (C:\new\temp) and code survive. For a line break, press Enter in the field. Only text an AI agent writes in toolkit mode has its\nturned into a line break (see What the agent has to say). - Embeds go through the API. The panel has a text field only; to send an embed, pass Discord's
embedsarray in the node'soperationConfig. Templates inside it are filled in value by value, so an embed's title can be{{payload.username}}.
Permissions
Discord decides what the bot may do from its role in the server. Add to Discord asks for what the operations use: View Channels, Send Messages, Embed Links, Attach Files, Read Message History and Add Reactions to read and answer, plus the ones below. Discord's install screen lets you untick any of them; it never asks for Administrator, Kick or Ban. A server where the app was added before 3 October 2026 keeps the short list (read and answer only) until you run Add to Discord again for it. An operation whose permission the bot lacks fails until it has it:
- Create, edit or delete a channel — Manage Channels.
- Pin a message — Pin Messages. Discord split it from Manage Messages, which no longer pins.
- Delete someone else's message — Manage Messages.
- Create a thread — Create Public Threads (Create Private Threads for a private one). Posting into a thread needs Send Messages in Threads.
- Add or remove a role — Manage Roles, with the bot's role above the target role.
Grant it in Discord: Server Settings → Roles → the bot's role (it carries the bot's name) → turn the permission on. Your own bot has the permissions you picked when you invited it: edit its role the same way, or invite it again with them.
When Discord refuses for a missing permission (403 Missing Permissions, or Missing Access when the bot cannot see the channel at all), the run fails with a 403 that names the permission the operation needs and says where to grant it. A 400 keeps Discord's own explanation — a message longer than 2,000 characters, for example.
Gotchas
- Role hierarchy is enforced by Discord, not by us. The bot's own highest role has to sit above the role it is adding or removing. Same permissions, wrong order, and the call fails.
- Deleting other people's messages needs Manage Messages. The bot can always delete its own (see Permissions).
- A DM to someone who doesn't accept DMs fails. If the user turned off DMs from server members, or blocked the bot, Discord answers 403 (code 50007, Cannot send messages to this user) and the run fails at this node with a 403 that says so. If delivery matters, post in a channel instead.
- Custom emoji use the
name:idform in reactions, not the:name:you type in the client. - Deleting a channel is irreversible. There is no trash in Discord.
listChannelsreturns an iterable payload, so a Loop or Aggregator downstream fans out over the channels with no glue.