發佈 0.1.10:tag 優先於回覆觸發,多 bot 同群不搶答

根本原因:
回覆 A bot 的訊息並 tag B bot 時,A 因「被回覆」觸發搶答,
B 才是使用者真正要叫的對象。

修法:
群組觸發改為 tag 優先:訊息含任何 bot tag(@xxx...bot)時,
只有第一個被 tag 的 bot 回應,被回覆的 bot 自動讓位;
沒有 bot tag 時維持原邏輯(回覆我 → 我回應)。
tag 一般使用者(非 bot username)不影響判定。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 17:27:01 +08:00
co-authored by Claude Fable 5
parent 2324347868
commit ec06c77bde
2 changed files with 14 additions and 7 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "telegram-codex-bot", "name": "telegram-codex-bot",
"version": "0.1.9", "version": "0.1.10",
"description": "Telegram bot powered by the local Codex CLI — zero-dependency, pm2-managed, with a built-in PM2 web viewer", "description": "Telegram bot powered by the local Codex CLI — zero-dependency, pm2-managed, with a built-in PM2 web viewer",
"license": "MIT", "license": "MIT",
"type": "commonjs", "type": "commonjs",
+13 -6
View File
@@ -111,14 +111,21 @@ function startBot(config) {
function shouldRespond(message) { function shouldRespond(message) {
if (message.chat.type === 'private') return true; if (message.chat.type === 'private') return true;
if (message.reply_to_message?.from?.id === botId) return true;
const text = message.text || message.caption || ''; const text = message.text || message.caption || '';
const entities = message.entities || message.caption_entities || []; const entities = message.entities || message.caption_entities || [];
return entities.some((e) => // 訊息中所有被 tag 的 botTelegram bot username 一定以 bot 結尾;
(e.type === 'mention' && // tag 到一般使用者不算,不影響回覆觸發)
text.slice(e.offset, e.offset + e.length).toLowerCase() === `@${botUsername.toLowerCase()}`) || const botMentions = entities
(e.type === 'text_mention' && e.user?.id === botId) .filter((e) => e.type === 'mention')
); .map((e) => text.slice(e.offset + 1, e.offset + e.length))
.filter((u) => /bot$/i.test(u));
if (botMentions.length > 0) {
// 有明確 tag 時以 tag 為準:只有第一個被 tag 的 bot 回應。
// 就算這則訊息是回覆我的(例如回覆我的訊息但 tag 別的 bot),我也讓位。
return botMentions[0].toLowerCase() === botUsername.toLowerCase();
}
if (message.reply_to_message?.from?.id === botId) return true;
return entities.some((e) => e.type === 'text_mention' && e.user?.id === botId);
} }
function stripMention(text) { function stripMention(text) {