feat: enable telegram reaction notifications by default

This commit is contained in:
Peter Steinberger
2026-01-16 20:51:39 +00:00
parent e7c42884fc
commit 56efbce31e
5 changed files with 38 additions and 5 deletions

View File

@@ -16,6 +16,7 @@
- CLI: set process titles to `clawdbot-<command>` for clearer process listings.
- CLI/macOS: sync remote SSH target/identity to config and let `gateway status` auto-infer SSH targets (ssh-config aware).
- Telegram: scope inline buttons with allowlist default + callback gating in DMs/groups.
- Telegram: default reaction notifications to own.
- Heartbeat: tighten prompt guidance + suppress duplicate alerts for 24h. (#980) — thanks @voidserf.
- Repo: ignore local identity files to avoid accidental commits. (#1001) — thanks @gerardward2007.
- Sessions/Security: add `session.dmScope` for multi-user DM isolation and audit warnings. (#948) — thanks @Alphonse-arianee.

View File

@@ -411,8 +411,8 @@ The agent sees reactions as **system notifications** in the conversation history
**Configuration:**
- `channels.telegram.reactionNotifications`: Controls which reactions trigger notifications
- `"off"` — ignore all reactions (default when not set)
- `"own"` — notify when users react to bot messages (best-effort; in-memory)
- `"off"` — ignore all reactions
- `"own"` — notify when users react to bot messages (best-effort; in-memory) (default)
- `"all"` — notify for all reactions
- `channels.telegram.reactionLevel`: Controls agent's reaction capability
@@ -505,7 +505,7 @@ Provider options:
- `channels.telegram.actions.reactions`: gate Telegram tool reactions.
- `channels.telegram.actions.sendMessage`: gate Telegram tool message sends.
- `channels.telegram.actions.deleteMessage`: gate Telegram tool message deletes.
- `channels.telegram.reactionNotifications`: `off | own | all` — control which reactions trigger system events (default: `off` when not set).
- `channels.telegram.reactionNotifications`: `off | own | all` — control which reactions trigger system events (default: `own` when not set).
- `channels.telegram.reactionLevel`: `off | ack | minimal | extensive` — control agent's reaction capability (default: `minimal` when not set).
Related global options:

View File

@@ -943,6 +943,7 @@ Set `channels.telegram.configWrites: false` to block Telegram-initiated config w
breakPreference: "paragraph" // paragraph | newline | sentence
},
actions: { reactions: true, sendMessage: true }, // tool action gates (false disables)
reactionNotifications: "own", // off | own | all
mediaMaxMb: 5,
retry: { // outbound retry policy
attempts: 3,

View File

@@ -2247,6 +2247,37 @@ describe("createTelegramBot", () => {
expect(enqueueSystemEvent).not.toHaveBeenCalled();
});
it("defaults reactionNotifications to own", async () => {
onSpy.mockReset();
enqueueSystemEvent.mockReset();
wasSentByBot.mockReturnValue(true);
loadConfig.mockReturnValue({
channels: {
telegram: { dmPolicy: "open" },
},
});
createTelegramBot({ token: "tok" });
const handler = getOnHandler("message_reaction") as (
ctx: Record<string, unknown>,
) => Promise<void>;
await handler({
update: { update_id: 502 },
messageReaction: {
chat: { id: 1234, type: "private" },
message_id: 43,
user: { id: 9, first_name: "Ada" },
date: 1736380800,
old_reaction: [],
new_reaction: [{ type: "emoji", emoji: "👍" }],
},
});
expect(enqueueSystemEvent).toHaveBeenCalledTimes(1);
});
it("allows reaction in all mode regardless of message sender", async () => {
onSpy.mockReset();
enqueueSystemEvent.mockReset();

View File

@@ -322,8 +322,8 @@ export function createTelegramBot(opts: TelegramBotOptions) {
const messageId = reaction.message_id;
const user = reaction.user;
// Resolve reaction notification mode (default: "off")
const reactionMode = telegramCfg.reactionNotifications ?? "off";
// Resolve reaction notification mode (default: "own")
const reactionMode = telegramCfg.reactionNotifications ?? "own";
if (reactionMode === "off") return;
if (user?.is_bot) return;
if (reactionMode === "own" && !wasSentByBot(chatId, messageId)) return;