#Control agent replies in Discord (main vs others)
1 messages · Page 1 of 1 (latest)
Yep, but only if those agents are separate Discord bot accounts.
allowBotsis per Discord accountrequireMentionis per guild/channel- so the main bot can accept bot-authored messages without a mention
- the other bot accounts can stay mention-gated
Minimal shape:
{
bindings: [
{ agentId: "main", match: { channel: "discord", accountId: "main" } },
{ agentId: "a1", match: { channel: "discord", accountId: "a1" } },
{ agentId: "a2", match: { channel: "discord", accountId: "a2" } },
{ agentId: "a3", match: { channel: "discord", accountId: "a3" } },
],
channels: {
discord: {
accounts: {
main: {
allowBots: true,
guilds: {
"GUILD_ID": {
channels: {
"CHANNEL_ID": {
enabled: true, // current key, "allow" is legacy
requireMention: false,
users: ["BOT_ID_A1", "BOT_ID_A2", "BOT_ID_A3"]
}
}
}
}
},
a1: {
allowBots: "mentions",
guilds: {
"GUILD_ID": {
channels: {
"CHANNEL_ID": { enabled: true, requireMention: true }
}
}
}
}
}
}
}
}
Important caveats:
- If all 4 agents share one Discord account, then no, not cleanly. These controls are not per-agent.
- Discord mention handling can also count reply-to-bot in some cases, so there is not a separate strict “explicit @mention only, never reply context” toggle right now.
Docs:
https://docs.openclaw.ai/channels/discord
https://docs.openclaw.ai/concepts/multi-agent
https://docs.openclaw.ai/gateway/configuration-reference
If you want, paste your current bindings and channels.discord.accounts block and I’ll turn it into the exact config.
@radiant hollow
"discord":{
"guilds": {
"148592044": {
"requireMention": true,
"ignoreOtherMentions": true,
"users": [ "14890", "14871", "780094", "78094", "149790 ","149701"
],
"channels": {
"5063": {
"enabled": true
},
"6509": {
"enabled": true,
"requireMention": true
},
"240174": {
"enabled": true,
"requireMention": true
},
"38954": {
"enabled": true,
"requireMention": true
},
"43582": {
"enabled": true,
"requireMention": true
}
}
}
},
"accounts": {
"default": {
"token": "MT..Ao",
"groupPolicy": "allowlist",
"streaming": {
"mode": "off"
},
"allowFrom": [
"14890"
]
},
"ke": {
"enabled": true,
"token": "MT...E",
"groupPolicy": "allowlist",
"streaming": {
"mode": "off"
},
"allowFrom": [
"14871"
]
},
"Co": {
"enabled": true,
"token": "M...Zg",
"groupPolicy": "allowlist",
"streaming": {
"mode": "off"
},
"allowFrom": [
"149701"
]
},
"Pi": {
"enabled": true,
"token": "MT..M",
"groupPolicy": "allowlist",
"streaming": {
"mode": "off"
},
"allowFrom": [
"149790"
]
},
"Sy": {
"enabled": true,
"token": "M..s",
"groupPolicy": "allowlist",
"streaming": {
"mode": "off"
},
"allowFrom": [
"78094"
]
}
}
}
@radiant hollow
"bindings": [
{
"type": "route",
"agentId": "dwight",
"match": {"channel": "discord","accountId": "default",
"peer": {
"kind": "channel","id": "6509"
}
}
},
{
"agentId": "main",
"match": {"channel": "discord","accountId": "default",
"peer": {
"kind": "channel","id": "43582"
}
}
},
{
"agentId": "main",
"match": {"channel": "discord","accountId": "default",
"peer": {
"kind": "channel","id": "38954"
}
}
},
{
"agentId": "ke",
"match": {"channel": "discord","accountId": "ke",
"peer": {"kind": "channel","id": "6509"
}
}
},
{
"agentId": "sy",
"match": {"channel": "discord","accountId": "Sy",
"peer": {"kind": "channel","id": "38954"
}
}
},
{
"agentId": "sy",
"match": {"channel": "discord","accountId": "Sy",
"peer": {"kind": "channel","id": "240174"
}
}
},
{
"agentId": "main",
"match": {"channel": "discord","accountId": "default",
"peer": {"kind": "channel","id": "240174"
}
}
},
{
"agentId": "pi",
"match": {"channel": "discord","accountId": "Pi",
"peer": {"kind": "channel","id": "240174"
}
}
},
{
"agentId": "co",
"match": {"channel": "discord","accountId": "Co",
"peer": {"kind": "channel","id": "240174"
}
}
}
],
Possible, but not with the config exactly as pasted.
Two key things:
- You do not set
allowBotsanywhere yet, so bot-authored messages are ignored by default. accounts.*.allowFromis not the guild-channel reply control. For Discord it is the DM/command allowlist alias. Your guild/channel reply behavior is controlled underguilds.
So for your setup, assuming default is the main agent:
discord: {
guilds: {
"148592044": {
requireMention: true, // keep global default for everyone else
ignoreOtherMentions: true,
channels: {
"5063": { enabled: true },
"6509": { enabled: true, requireMention: true },
"240174": { enabled: true, requireMention: true },
"38954": { enabled: true, requireMention: true },
"43582": { enabled: true, requireMention: true }
}
}
},
accounts: {
default: {
token: "...",
groupPolicy: "allowlist",
allowBots: true,
guilds: {
"148592044": {
channels: {
"5063": {
enabled: true,
requireMention: false,
users: ["14871", "149701", "149790", "78094"] // other agent bot IDs only
}
}
}
}
},
ke: {
enabled: true,
token: "...",
groupPolicy: "allowlist",
allowBots: "mentions"
},
Co: {
enabled: true,
token: "...",
groupPolicy: "allowlist",
allowBots: "mentions"
},
Pi: {
enabled: true,
token: "...",
groupPolicy: "allowlist",
allowBots: "mentions"
},
Sy: {
enabled: true,
token: "...",
groupPolicy: "allowlist",
allowBots: "mentions"
}
}
}
What this does:
- main/default can respond to the other bot accounts in channel
5063without a mention - the other accounts only accept bot-authored messages when mentioned (
allowBots: "mentions") - global
requireMention: truestill keeps the non-main bots mention-gated
Small caveat: Discord mention gating can also count reply-to-bot in some cases, so this is not a perfect “only literal @mention and nothing else” mode.
Docs:
https://docs.openclaw.ai/channels/discord
https://docs.openclaw.ai/concepts/multi-agent
https://docs.openclaw.ai/gateway/configuration-reference
If you want, I can rewrite your full block exactly as valid JSON5 for copy-paste.
Yep, these bindings are compatible with what you want.
The important bit is:
- bindings only route account/channel -> agent
- they do not control mention behavior
- mention behavior still comes from
accounts.*.allowBots+guilds/channels.*.requireMention
So for your layout, I’d do this:
accounts.default.allowBots: trueaccounts.ke.allowBots: "mentions"accounts.Co.allowBots: "mentions"accounts.Pi.allowBots: "mentions"accounts.Sy.allowBots: "mentions"
Then, because default is also used for dwight in channel 6509, do not make the whole guild unmentioned for default.
Instead, only override the channels where main should talk without mention:
accounts: {
default: {
allowBots: true,
guilds: {
"148592044": {
channels: {
"38954": { enabled: true, requireMention: false },
"43582": { enabled: true, requireMention: false },
"240174": { enabled: true, requireMention: false }
}
}
}
},
ke: { allowBots: "mentions" },
Co: { allowBots: "mentions" },
Pi: { allowBots: "mentions" },
Sy: { allowBots: "mentions" }
}
That gives you:
main/defaultcan answer other bot accounts in38954,43582,240174without pingdwight/defaultin6509still stays mention-gatedke,Co,Pi,Syonly wake on bot messages when mentioned
One caveat: Discord can also treat reply-to-bot as a mention in some cases, so it’s not a perfect “literal @mention only” switch.
If you want, I can merge your discord + bindings into one clean copy-paste JSON5 block.
@radiant hollow please merge discord + bindings into one clean copy-paste JSON5 block.
Here’s a cleaned-up merged block. I replaced tokens with placeholders on purpose.
{
bindings: [
{
agentId: "dwight",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "6509" },
},
},
{
agentId: "main",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "43582" },
},
},
{
agentId: "main",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "38954" },
},
},
{
agentId: "ke",
match: {
channel: "discord",
accountId: "ke",
peer: { kind: "channel", id: "6509" },
},
},
{
agentId: "sy",
match: {
channel: "discord",
accountId: "Sy",
peer: { kind: "channel", id: "38954" },
},
},
{
agentId: "sy",
match: {
channel: "discord",
accountId: "Sy",
peer: { kind: "channel", id: "240174" },
},
},
{
agentId: "main",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "240174" },
},
},
{
agentId: "pi",
match: {
channel: "discord",
accountId: "Pi",
peer: { kind: "channel", id: "240174" },
},
},
{
agentId: "co",
match: {
channel: "discord",
accountId: "Co",
peer: { kind: "channel", id: "240174" },
},
},
],
channels: {
discord: {
guilds: {
"148592044": {
requireMention: true,
ignoreOtherMentions: true,
users: ["14890", "14871", "780094", "78094", "149790", "149701"],
channels: {
"5063": { enabled: true },
"6509": { enabled: true, requireMention: true },
"240174": { enabled: true, requireMention: true },
"38954": { enabled: true, requireMention: true },
"43582": { enabled: true, requireMention: true },
},
},
},
accounts: {
default: {
token: "YOUR_DEFAULT_BOT_TOKEN",
groupPolicy: "allowlist",
streaming: { mode: "off" },
allowFrom: ["14890"],
allowBots: true,
guilds: {
"148592044": {
channels: {
// Main/default can respond to the other bot accounts here without @mention.
// Remove `users` if you also want humans to wake main without a mention.
"240174": {
enabled: true,
requireMention: false,
users: ["14871", "78094", "149790", "149701"],
},
"38954": {
enabled: true,
requireMention: false,
users: ["14871", "78094", "149790", "149701"],
},
"43582": {
enabled: true,
requireMention: false,
users: ["14871", "78094", "149790", "149701"],
},
},
},
},
},
ke: {
enabled: true,
token: "YOUR_KE_BOT_TOKEN",
groupPolicy: "allowlist",
streaming: { mode: "off" },
allowFrom: ["14871"],
allowBots: "mentions",
},
Co: {
enabled: true,
token: "YOUR_CO_BOT_TOKEN",
groupPolicy: "allowlist",
streaming: { mode: "off" },
allowFrom: ["149701"],
allowBots: "mentions",
},
Pi: {
enabled: true,
token: "YOUR_PI_BOT_TOKEN",
groupPolicy: "allowlist",
streaming: { mode: "off" },
allowFrom: ["149790"],
allowBots: "mentions",
},
Sy: {
enabled: true,
token: "YOUR_SY_BOT_TOKEN",
groupPolicy: "allowlist",
streaming: { mode: "off" },
allowFrom: ["78094"],
allowBots: "mentions",
},
},
},
},
}
If this fixed it, please right-click the solution message -> Apps -> âś… Mark Solution, so Answer Overflow can index it.
@radiant hollow agent dwight is a subagent i see you removed "type": "route",
any reason for that
No special reason, I removed it only because type is optional here, and missing type defaults to route.
So these are equivalent:
{ type: "route", agentId: "dwight", match: { ... } }
and
{ agentId: "dwight", match: { ... } }
If dwight is just another configured agent, then route is still the correct type, even if you think of it as a subagent.
Only use type: "acp" if that binding is for an ACP session/harness, which is a different thing.
So short answer:
type: "route"= totally fine- omitted
type= same behavior - I can put it back for clarity, and honestly that may be nicer
If you want, I’ll repost the merged block with type: "route" on every binding.
@radiant hollow how can i also control this: if i mention two agents at the same time. both of them will message and send at the same time, this leads the gateway to crush or restart itself. also it creates noise
Short version, not cleanly with multiple public Discord bot accounts in the same channel.
If you mention 2 bots, both accounts get a valid trigger, so both will reply.
ignoreOtherMentions does not solve that, because each bot still sees itself mentioned.
Best options:
-
Recommended: one public bot in shared channels, route internally to subagents
This is the cleanest. Only one visible reply path, much less noise. -
Separate channels/threads per agent
Keep one bot/account per channel or thread. Then only that agent can answer there. -
Keep multi-bot same channel
Then there is no real dedupe/arbitration knob today. If 2 bots are mentioned, both will wake.
Also, the gateway restarting/crashing is not expected. That part sounds like a bug, not just noisy config.
Can you paste these after reproducing it once?
openclaw --version
openclaw status --all
openclaw logs --follow
If the logs show things like:
Listener DiscordMessageListener timed out ...discord inbound worker timed out ...
then we can also tune:
channels.discord.accounts.<accountId>.eventQueue.listenerTimeoutchannels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs
But first, I’d recommend architecture-wise: one visible bot per shared channel. That’s the setup I’d trust most here.
If you want, I can sketch the “one public bot + internal subagents” layout for your exact setup.