Skip to content

feat: add configurable Slack reaction triggers for agents #27

@geekforbrains

Description

@geekforbrains

Problem

Slack transport currently only starts listeners for app_mention and DM message events in src/operator_ai/transport/slack.py, so there is no way to trigger an agent from a reacji on an existing message or thread.

That blocks a useful Slack-native workflow: react to a message in #triage / #dev / a thread and let an agent pick it up in-place, without mentioning the bot or rewriting the request.

Proposed approach

Add an opt-in reaction trigger config for Slack transports, scoped per agent.

Example config shape for v1:

agents:
  reviewer:
    transport:
      type: slack
      bot_token_env: SLACK_BOT_TOKEN
      app_token_env: SLACK_APP_TOKEN
      reaction_triggers:
        - emoji: robot_face
          channels: ["#triage", "#dev"]
        - emoji: eyes
          roles: ["admin"]

If reaction_triggers is absent, ignore reaction events entirely.

Implementation sketch

  1. Extend TransportConfig to accept a Slack reaction trigger list.
  2. In SlackTransport.start(), add a reaction_added listener.
  3. Ignore non-message items (file, file_comment) and any reactions that do not match configured rules.
  4. Fetch the reacted-to message by channel + ts so we can recover the actual message text, author, attachments, and thread_ts.
  5. Synthesize an IncomingMessage and hand it to the existing dispatcher so auth, memory, thread context, and reply posting all work unchanged.
  6. Use a synthetic message/event ID for dedupe, e.g. reaction:<event_ts>, while setting root_message_id to the target thread root (thread_ts or ts).

Recommended v1 filters

  • emoji (required)
  • channels allowlist by name or ID
  • users and/or roles allowlist so reaction triggers still respect Operators auth model
  • Ignore bot-authored reaction events

Notes

  • Slacks reaction_added event requires the reactions:read scope.
  • The event payload only contains a lightweight item reference for messages, so an extra Web API read is required to recover the full message/thread context.
  • This adds at least one extra Slack read per trigger, so we should keep the rule matching cheap and avoid unnecessary follow-up calls.
  • Docs/setup should mention the added Slack scope and reinstall requirement for existing apps.

Acceptance criteria

  • A Slack agent can be triggered by a configured emoji reaction without an @mention.
  • Reactions are ignored unless they match configured rules.
  • The agent replies in the reacted messages thread, not an unrelated/new conversation.
  • The reacting user is treated as the requesting user for auth and memory scoping.
  • Non-message reaction items are ignored cleanly.
  • Tests cover rule matching, synthetic message construction, and dedupe/thread behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions