Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion hn-monitor/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,14 @@ async function resolveRelaySender(event: AgentEvent, expandedFull: unknown): Pro
export default defineAgent({
schedules: [{ name: 'scan', cron: '0 9,17 * * *', tz: 'America/New_York' }],
triggers: {
slack: [{ on: 'app_mention' }],
// `on: 'app_mention'` never actually routes: the cloud's integration-watch
// matcher hard-excludes app_mention from generic resource matching
// (relayfileTriggerMatchesEvent short-circuits false for it), and Slack
// mentions inside an existing thread arrive to the webhook as a plain
// `message.created` event, not a literal `app_mention` eventType. Match on
// the Relayfile trigger + `@mention` text gate instead (same fix joke-bot
// already applies).
slack: [{ on: 'message.created', paths: ['/slack/channels/${SLACK_CHANNEL}/**'], match: '@mention' }],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add an in-handler Slack mention gate

This now relies on the trigger match: '@mention' to keep hn-monitor from handling ordinary Slack messages, but the repo's production joke-bot notes that this match gate is not enforced cloud-side yet and therefore checks the raw Slack text for <@...> before replying. In the inspected hn-monitor path, any slack.message.created in SLACK_CHANNEL with non-empty text reaches handleQaMessage, so a normal human reply in the digest channel/thread can trigger an HN lookup and bot reply even when the bot was not mentioned. Please add the same payload-level mention check before treating the message as Q&A.

Useful? React with 👍 / 👎.

telegram: [{ on: 'message' }]
},
handler: async (ctx, event) => {
Expand Down
18 changes: 10 additions & 8 deletions inbox-buddy/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ const THREAD_LOAD_LIMIT = 200;

export default defineAgent({
triggers: {
// Both webhook-driven: the message rides in the event PAYLOAD
// (event.expand('full').data), independent of the relayfile mount. We
// deliberately do NOT use `message.created`/relayfile watches — those fire
// only on *ingested* message records, so a stalled sync (the relayfile
// migration) silently kills them. Same shape the in-production review-agent
// (pr-reviewer) uses to reply to Slack mentions. Each transport's trigger is
// pruned at deploy when its id input is empty (persona enabledByInput).
slack: [{ on: 'app_mention' }],
// `on: 'app_mention'` never actually routes: the cloud's integration-watch
// matcher hard-excludes app_mention from generic resource matching
// (relayfileTriggerMatchesEvent short-circuits false for it), and Slack
// mentions inside an existing thread arrive to the webhook as a plain
// `message.created` event, not a literal `app_mention` eventType. Match on
// the Relayfile trigger + `@mention` text gate instead — the same pattern
// review-agent (pr-reviewer) and joke-bot actually use in production. Each
// transport's trigger is pruned at deploy when its id input is empty
// (persona enabledByInput).
slack: [{ on: 'message.created', paths: ['/slack/channels/${SLACK_CHANNEL}/**'], match: '@mention' }],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require a real Slack mention before answering

Switching to message.created makes this agent depend on match: '@mention' for mention-only behavior, but the existing joke-bot handler documents that this gate is not enforced cloud-side yet and defensively checks the raw Slack text. handleSlackMessage only runs skipReason, whose empty-text check accepts ordinary messages after stripLeadingMention, so any non-bot message in the configured Slack channel can now load Gmail, call the model, and post a reply without the user mentioning inbox-buddy. Please add a handler-level <@...>/mention check before composing the answer.

Useful? React with 👍 / 👎.

telegram: [{ on: 'message' }]
},
handler: async (ctx, event) => {
Expand Down
6 changes: 4 additions & 2 deletions tests/inbox-buddy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,10 @@ test('loadRecentThreads ignores _index.json and non-thread files', async () => {

// ── dual-transport dispatch (unified agent) ────────────────────────────────────

test('unified agent registers BOTH slack.app_mention and telegram.message triggers', () => {
assert.deepEqual(inboxBuddyAgent.triggers?.slack, [{ on: 'app_mention' }]);
test('unified agent registers BOTH slack.message.created (mention-gated) and telegram.message triggers', () => {
assert.deepEqual(inboxBuddyAgent.triggers?.slack, [
{ on: 'message.created', paths: ['/slack/channels/${SLACK_CHANNEL}/**'], match: '@mention' }
]);
assert.deepEqual(inboxBuddyAgent.triggers?.telegram, [{ on: 'message' }]);
});

Expand Down