Channels/Messaging — Ack Reactions

Focus Deep-Dive

Acknowledgement Reaction Scope Gating & WhatsApp Specialization

Ack reactions provide visual confirmation that the agent received a message. This module implements scope-based gating that considers chat type, mention status, and platform-specific behaviors (particularly WhatsApp’s unique reaction model).

5 Scopes WhatsApp Special Mention-Aware Zero-Config

📚 What is this & why does it matter?

In a busy group chat with dozens of messages, users need to know their message was received by the agent — not just ignored. Ack reactions (e.g., a 👀 emoji) provide that instant feedback. But they must be selective: reacting to every message in a group would be noisy. The scope system controls exactly when reactions fire.

💡 Real-world analogy

Think of a waiter at a restaurant. In a private dining room (DM), the waiter acknowledges every request immediately. In the main dining hall (group), the waiter only responds when called by name (@mention). The “scope” setting lets the restaurant manager decide the waiter’s response policy for each room type.

Contents

Scope Types

export type AckReactionScope =
  | "all"              // React to every message
  | "direct"           // React only in DMs
  | "group-all"        // React to all group messages
  | "group-mentions"   // React only when @mentioned in groups (default)
  | "off"              // Never react
  | "none";            // Alias for "off"

Gate Parameters

export type AckReactionGateParams = {
  scope: AckReactionScope | undefined;   // Configured scope
  isDirect: boolean;                      // Is this a DM?
  isGroup: boolean;                       // Is this a group chat?
  isMentionableGroup: boolean;            // Can this group support mentions?
  requireMention: boolean;                // Is mention required?
  canDetectMention: boolean;              // Can the platform detect mentions?
  effectiveWasMentioned: boolean;         // Was the bot effectively mentioned?
  shouldBypassMention?: boolean;          // Bypass mention for authorized commands?
};

Decision Flow

flowchart TD
    START["shouldAckReaction()"]
    START --> SCOPE{"scope?"}
    SCOPE -->|"off"/"none"| FALSE["return false"]
    SCOPE -->|"all"| TRUE["return true"]
    SCOPE -->|"direct"| IS_DM{"isDirect?"}
    IS_DM -->|Yes| TRUE
    IS_DM -->|No| FALSE
    SCOPE -->|"group-all"| IS_GRP{"isGroup?"}
    IS_GRP -->|Yes| TRUE
    IS_GRP -->|No| FALSE
    SCOPE -->|"group-mentions"| MENTIONABLE{"isMentionableGroup?"}
    MENTIONABLE -->|No| FALSE
    MENTIONABLE -->|Yes| REQ{"requireMention?"}
    REQ -->|No| FALSE
    REQ -->|Yes| DETECT{"canDetectMention?"}
    DETECT -->|No| FALSE
    DETECT -->|Yes| MENTIONED{"effectiveWasMentioned
OR shouldBypassMention?"}
    MENTIONED -->|Yes| TRUE
    MENTIONED -->|No| FALSE
export function shouldAckReaction(params: AckReactionGateParams): boolean {
  const scope = params.scope ?? "group-mentions";
  if (scope === "off" || scope === "none") return false;
  if (scope === "all") return true;
  if (scope === "direct") return params.isDirect;
  if (scope === "group-all") return params.isGroup;
  if (scope === "group-mentions") {
    if (!params.isMentionableGroup) return false;
    if (!params.requireMention) return false;
    if (!params.canDetectMention) return false;
    return params.effectiveWasMentioned || params.shouldBypassMention === true;
  }
  return false;
}

WhatsApp Specialization

WhatsApp has a dedicated ack reaction function with its own mode system:

export type WhatsAppAckReactionMode = "always" | "mentions" | "never";

export function shouldAckReactionForWhatsApp(params: {
  emoji: string;                  // Must be non-empty
  isDirect: boolean;
  isGroup: boolean;
  directEnabled: boolean;         // WhatsApp-specific DM toggle
  groupMode: WhatsAppAckReactionMode;
  wasMentioned: boolean;
  groupActivated: boolean;        // Bypass for activated groups
}): boolean
flowchart TD
    WA["shouldAckReactionForWhatsApp()"]
    WA --> EMOJI{"emoji
non-empty?"}
    EMOJI -->|No| FALSE["return false"]
    EMOJI -->|Yes| DIRECT{"isDirect?"}
    DIRECT -->|Yes| DIR_EN{"directEnabled?"}
    DIR_EN -->|Yes| TRUE["return true"]
    DIR_EN -->|No| FALSE
    DIRECT -->|No| IS_GRP{"isGroup?"}
    IS_GRP -->|No| FALSE
    IS_GRP -->|Yes| MODE{"groupMode?"}
    MODE -->|"never"| FALSE
    MODE -->|"always"| TRUE
    MODE -->|"mentions"| MENTION_CHECK["Delegate to
shouldAckReaction()"]

Decision Matrix

ScopeDMGroup (mentioned)Group (not mentioned)Group (bypass)
all✔✔✔✔
direct✔✘✘✘
group-all✘✔✔✔
group-mentions✘✔✘✔
off✘✘✘✘