#Discord, bind main session to channel
1 messages · Page 1 of 1 (latest)
OpenClaw canât currently âbindâ an agentâs main session to a specific Discord channel.
By design:
- DMs â collapse into the agentâs main session key
- Guild channels / threads â get their own session keys (so context doesnât bleed across unrelated rooms)
Docs: https://docs.openclaw.ai/concepts/session
FAQ note: https://docs.openclaw.ai/help/faq#do-groupsthreads-share-context-with-dms
What you can do instead
Option A (recommended): just use the Discord channel session and ignore âmainâ
Even if you never DM the bot, youâll still see a âmainâ session exist (itâs the default DM bucket + used by some background features). But your Discord channel will keep one continuous session as long as you keep talking in the same channel/thread.
Option B (blunt instrument): force everything into one session with session.scope: "global"
If you truly want one single session for all inbound messages (DMs + all channels), set:
{
session: {
scope: "global"
}
}
This will collapse everything into a single âglobalâ bucket. Itâs convenient, but itâs also very easy to accidentally mix contexts across different places/users, so use with care.
(That scope setting is in the config reference: https://docs.openclaw.ai/gateway/configuration-reference#session)
Option C: if the âextra sessionâ is coming from heartbeat/cron
Heartbeats run in main by default. You can either disable heartbeat, or point it at your Discord channel session key instead.
Heartbeat docs (see heartbeat.session): https://docs.openclaw.ai/gateway/heartbeat
If you tell me whether you mean:
- âI see two session keys (main + discord channel) and want just oneâ, or
- âit creates a new sessionId every message / very oftenâ (reset policy issue),
âŠI can point you to the exact knob.
Well, the problem is that CRONs really want to deliver summaries to "main" session. I, on the other hand am speaking on a discord channel. And it's all mixed up. 3-4 sessions pushing messages to one channel and I have no idea who. And when I ask for things in the channel, the channel's session is confised as well as it has no idea what I am talking about since the messages in discord came from eitehr main's heartbeat, or crons deliveries.
I really only want ONE session to be bound to a channel. And the crons running in their sessions pushing to the main one.
Can be done?
What youâre seeing is basically âworking as designedâ, but itâs a pretty rough UX if you want Discord to feel like the single source of truth.
Why it happens
- Your Discord channel has its own session key (e.g.
agent:<id>:discord:channel:<channelId>). - Isolated cron jobs run in their own sessions (
cron:<jobId>), and when they âannounceâ, the delivered message goes to Discord without becoming history for the Discord channel session. - Additionally,
delivery.mode="announce"also posts a brief summary to the main session, which is why âmainâ gets polluted too.
So when you later talk in the Discord channel and refer to something a cron said, the channel session legitimately doesnât have that in its transcript.
Can you bind main to a Discord channel?
Not in a âbind main to channel X onlyâ way.
But you can get the behavior you want (one shared context) by switching the whole instance to a single global session:
Option 1 (most like what you want): session.scope = "global"
{
session: {
scope: "global",
},
}
With this:
- Discord channel messages, heartbeats, and anything that targets âmainâ all share one session (
global). - The âbrief summary posted to mainâ from cron announce ends up in the same global session youâre chatting in, so your Discord conversation stops feeling âamnesiacâ.
Tradeoff: all channels/DMs share the same context. If multiple people can talk to the bot, this can leak context across users/places.
Docs: https://docs.openclaw.ai/concepts/session
How to stop cron from spamming main
If your immediate pain is âcron summaries keep going into mainâ, disable delivery on those isolated jobs:
openclaw cron edit <job-id> --no-deliver
CLI doc: https://docs.openclaw.ai/cli/cron
Cron doc: https://docs.openclaw.ai/automation/cron-jobs
(But note: --no-deliver also means it wonât post to Discord either.)
If you need cron output to actually become Discord-session history
Right now the built-in âannounceâ delivery does not backfill that message into the channel session transcript. The only clean way to make cron outputs part of âthe one conversationâ is:
- run them as main-session cron jobs (
--session main --system-event ...), or - use
session.scope="global"so the âmainâ transcript is the one youâre chatting in.
If you tell me whether youâre okay with the âglobal sessionâ tradeoff (single user / single channel), I can suggest the simplest exact config + cron style to stop the session soup.
session.scope="global" is great but it's global and I cannot set it on one specific agent. It will apply to all. That's a limitation of OpenClaw đ
Probably a feature request is needed
Yep â today session.scope is a gateway-wide setting. Thereâs no agents.list[].session.scope (or per-binding override), so you canât make just one agent use "global" while others stay "per-sender". Thatâs a real limitation.
That said, youâve got a couple of practical workarounds that get you most of the âone Discord channel = one brainâ behavior without global scope:
Workaround 1: stop heartbeats from contaminating main
Heartbeats are configurable per agent. Point them at the Discord channel session key:
{
agents: {
defaults: {
heartbeat: {
session: "agent:<agentId>:discord:channel:<channelId>",
target: "discord",
to: "channel:<channelId>"
}
}
}
}
So the heartbeat run context (and transcript) is the Discord channel session, not main.
Docs: https://docs.openclaw.ai/gateway/configuration-reference#agentsdefaultsheartbeat
Workaround 2: avoid âcron announceâ (it always posts a summary to main)
From the cron docs: when delivery.mode = "announce", it delivers to the channel and posts a brief summary to the main session. There isnât a âannounce but donât touch mainâ switch right now.
So if you donât want main polluted, use:
openclaw cron edit <job-id> --no-deliver