Building plugins

Channel mention policy

Decide when an inbound message counts as a mention, without reimplementing the shared policy. Part of the Building channel plugins guide.

Inbound mention policy

Keep inbound mention handling split in two layers:

  • plugin-owned evidence gathering
  • shared policy evaluation

Use openclaw/plugin-sdk/channel-mention-gating for mention-policy decisions. Use openclaw/plugin-sdk/channel-inbound only when you need the broader inbound helper barrel.

Good fit for plugin-local logic:

  • reply-to-bot detection
  • quoted-bot detection
  • thread-participation checks
  • service/system-message exclusions
  • platform-native caches needed to prove bot participation

Good fit for the shared helper:

  • requireMention
  • explicit mention result
  • implicit mention allowlist
  • command bypass
  • final skip decision

Preferred flow:

  1. Compute local mention facts.
  2. Pass those facts into resolveInboundMentionDecision({ facts, policy }).
  3. Use decision.effectiveWasMentioned, decision.shouldBypassMention, and decision.shouldSkip in your inbound gate.
typescript
import {  implicitMentionKindWhen,  matchesMentionWithExplicit,  resolveInboundMentionDecision,} from "openclaw/plugin-sdk/channel-inbound";import { resolveChannelImplicitMentions } from "openclaw/plugin-sdk/channel-ingress-runtime"; const wasMentioned = matchesMentionWithExplicit({  text,  mentionRegexes,  explicit: {    hasAnyMention,    isExplicitlyMentioned,    canResolveExplicit,  },}); const facts = {  canDetectMention: true,  wasMentioned,  hasAnyMention,  implicitMentionKinds: [    ...implicitMentionKindWhen("reply_to_bot", isReplyToBot),    ...implicitMentionKindWhen("quoted_bot", isQuoteOfBot),  ],}; const implicitMentions = resolveChannelImplicitMentions({  cfg,  channel: channelId,  accountId,}); const decision = resolveInboundMentionDecision({  facts,  policy: {    isGroup,    requireMention,    implicitMentions,    allowTextCommands,    hasControlCommand,    commandAuthorized,  },}); if (decision.shouldSkip) return;

matchesMentionWithExplicit(...) returns a boolean. hasAnyMention, isExplicitlyMentioned, and canResolveExplicit come from the channel's own native mention metadata (message entities, reply-to-bot flags, and similar); supply false/undefined values when your platform cannot detect them.

api.runtime.channel.mentions exposes the same shared mention helpers for bundled channel plugins that already depend on runtime injection: buildMentionRegexes, matchesMentionPatterns, matchesMentionWithExplicit, implicitMentionKindWhen, resolveInboundMentionDecision.

If you only need implicitMentionKindWhen and resolveInboundMentionDecision,

unrelated inbound runtime helpers.

Was this useful?
On this page

On this page