Files
openclaw/extensions/telegram/src/sequential-key.ts
Nimrod Gutman 9aac55d306 Add /btw side questions (#45444)
* feat(agent): add /btw side questions

* fix(agent): gate and log /btw reviews

* feat(btw): isolate side-question delivery

* test(reply): update route reply runtime mocks

* fix(btw): complete side-result delivery across clients

* fix(gateway): handle streamed btw side results

* fix(telegram): unblock btw side questions

* fix(reply): make external btw replies explicit

* fix(chat): keep btw side results ephemeral in internal history

* fix(btw): address remaining review feedback

* fix(chat): preserve btw history on mobile refresh

* fix(acp): keep btw replies out of prompt history

* refactor(btw): narrow side questions to live channels

* fix(btw): preserve channel typing indicators

* fix(btw): keep side questions isolated in chat

* fix(outbound): restore typed channel send deps

* fix(btw): avoid blocking replies on transcript persistence

* fix(btw): keep side questions fast

* docs(commands): document btw slash command

* docs(changelog): add btw side questions entry

* test(outbound): align session transcript mocks
2026-03-14 17:27:54 +02:00

66 lines
2.3 KiB
TypeScript

import { type Message, type UserFromGetMe } from "@grammyjs/types";
import { isAbortRequestText } from "../../../src/auto-reply/reply/abort.js";
import { isBtwRequestText } from "../../../src/auto-reply/reply/btw-command.js";
import { resolveTelegramForumThreadId } from "./bot/helpers.js";
export type TelegramSequentialKeyContext = {
chat?: { id?: number };
me?: UserFromGetMe;
message?: Message;
channelPost?: Message;
editedChannelPost?: Message;
update?: {
message?: Message;
edited_message?: Message;
channel_post?: Message;
edited_channel_post?: Message;
callback_query?: { message?: Message };
message_reaction?: { chat?: { id?: number } };
};
};
export function getTelegramSequentialKey(ctx: TelegramSequentialKeyContext): string {
const reaction = ctx.update?.message_reaction;
if (reaction?.chat?.id) {
return `telegram:${reaction.chat.id}`;
}
const msg =
ctx.message ??
ctx.channelPost ??
ctx.editedChannelPost ??
ctx.update?.message ??
ctx.update?.edited_message ??
ctx.update?.channel_post ??
ctx.update?.edited_channel_post ??
ctx.update?.callback_query?.message;
const chatId = msg?.chat?.id ?? ctx.chat?.id;
const rawText = msg?.text ?? msg?.caption;
const botUsername = ctx.me?.username;
if (isAbortRequestText(rawText, botUsername ? { botUsername } : undefined)) {
if (typeof chatId === "number") {
return `telegram:${chatId}:control`;
}
return "telegram:control";
}
if (isBtwRequestText(rawText, botUsername ? { botUsername } : undefined)) {
const messageId = msg?.message_id;
if (typeof chatId === "number" && typeof messageId === "number") {
return `telegram:${chatId}:btw:${messageId}`;
}
if (typeof chatId === "number") {
return `telegram:${chatId}:btw`;
}
return "telegram:btw";
}
const isGroup = msg?.chat?.type === "group" || msg?.chat?.type === "supergroup";
const messageThreadId = msg?.message_thread_id;
const isForum = msg?.chat?.is_forum;
const threadId = isGroup
? resolveTelegramForumThreadId({ isForum, messageThreadId })
: messageThreadId;
if (typeof chatId === "number") {
return threadId != null ? `telegram:${chatId}:topic:${threadId}` : `telegram:${chatId}`;
}
return "telegram:unknown";
}