Skip to main content
Routing decides: for a message arriving from an IM platform, which agent handles it and which of that agent’s sessions it joins. “Which agent” decides who answers; “which session” decides which earlier messages this one shares conversation context with. Messages in the same session see each other; different sessions are isolated. A session can be scoped two ways today: one session per chat, or one session per member in a group chat. Because in a channel both chats and users only show up with their first message: the first time anyone DMs the bot, it brings a chat that was never seen before. So routing is not a lookup table written in advance, but an ordered list of rules, matched top to bottom, first match wins, with a catch-all rule to guarantee every message has a definite destination.

Routing rules

A routing rule (binding) has four fields: the first two say “which messages to match”, the last two say “what to do on a match”. match_value is an exact match (not a prefix, not a regex); only "*" is special and matches everything. When match_key points at a key in metadata, the matchable values are platform-defined: Feishu’s chat_type is group / p2p, Discord’s is guild / dm; see each platform’s page.

Session scope

session_scope decides how messages that hit the same rule are grouped into sessions. Messages in the same session share context. Even when they resolve to the same agent, per_chat and per_chat_user put messages into different sessions. So after you change the scope, later messages are regrouped under the new scheme. Different agents never share a session.

Match order

Rules are matched top to bottom, first match wins, the same way firewall rules or Nginx location blocks work. Put specific exceptions first and the catch-all last. Saving a config runs three checks so that every message has a definite, unique destination:
  • There must be exactly one catch-all rule (match_value of "*");
  • The catch-all must be last, or the rules after it would never be reached;
  • Duplicate (match_key, match_value) combinations are not allowed.

A full example

Suppose you’ve deployed two agents: a general assistant friday and a product expert product-expert. Let’s follow one real message and see which agent and session it lands in under different rules.
1

A message arrives

The bot is in a Feishu group called “Product Team” and receives a line from a member, Alice. The message looks roughly like this (only routing-relevant fields shown):
Inbound message
2

Rules decide where it goes

The same message, under different rules, goes to different agents and sessions. Each tab below is one configuration:
3

The catch-all rule

Every config must end with a catch-all rule (match_value of "*") so that a message matching none of the earlier rules still has a definite destination. The last rule in all three examples above is exactly that:
Catch-all rule
Before configuring routing, call GET /channels/{id}/chat_ids to list the chats the bot knows and their chat_id; copy them directly instead of transcribing platform IDs by hand.

Further reading

Connect Feishu

Create a Feishu bot and let agents chat in Feishu.

Connect Discord

Create a Discord bot and let agents chat in Discord.