mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
telegram: route dm sessions by sender id
This commit is contained in:
committed by
Peter Steinberger
parent
2c39731846
commit
317075ef3d
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { clearRuntimeConfigSnapshot, setRuntimeConfigSnapshot } from "../config/config.js";
|
||||
import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js";
|
||||
|
||||
describe("buildTelegramMessageContext dm thread sessions", () => {
|
||||
@@ -104,3 +105,45 @@ describe("buildTelegramMessageContext group sessions without forum", () => {
|
||||
expect(ctx?.ctxPayload?.MessageThreadId).toBe(99);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildTelegramMessageContext direct peer routing", () => {
|
||||
afterEach(() => {
|
||||
clearRuntimeConfigSnapshot();
|
||||
});
|
||||
|
||||
it("isolates dm sessions by sender id when chat id differs", async () => {
|
||||
const runtimeCfg = {
|
||||
agents: { defaults: { model: "anthropic/claude-opus-4-5", workspace: "/tmp/openclaw" } },
|
||||
channels: { telegram: {} },
|
||||
messages: { groupChat: { mentionPatterns: [] } },
|
||||
session: { dmScope: "per-channel-peer" as const },
|
||||
};
|
||||
setRuntimeConfigSnapshot(runtimeCfg);
|
||||
|
||||
const baseMessage = {
|
||||
chat: { id: 777777777, type: "private" as const },
|
||||
date: 1700000000,
|
||||
text: "hello",
|
||||
};
|
||||
|
||||
const first = await buildTelegramMessageContextForTest({
|
||||
cfg: runtimeCfg,
|
||||
message: {
|
||||
...baseMessage,
|
||||
message_id: 1,
|
||||
from: { id: 123456789, first_name: "Alice" },
|
||||
},
|
||||
});
|
||||
const second = await buildTelegramMessageContextForTest({
|
||||
cfg: runtimeCfg,
|
||||
message: {
|
||||
...baseMessage,
|
||||
message_id: 2,
|
||||
from: { id: 987654321, first_name: "Bob" },
|
||||
},
|
||||
});
|
||||
|
||||
expect(first?.ctxPayload?.SessionKey).toBe("agent:main:telegram:direct:123456789");
|
||||
expect(second?.ctxPayload?.SessionKey).toBe("agent:main:telegram:direct:987654321");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
buildGroupLabel,
|
||||
buildSenderLabel,
|
||||
buildSenderName,
|
||||
resolveTelegramDirectPeerId,
|
||||
buildTelegramGroupFrom,
|
||||
buildTelegramGroupPeerId,
|
||||
buildTelegramParentPeer,
|
||||
@@ -174,6 +175,7 @@ export const buildTelegramMessageContext = async ({
|
||||
const msg = primaryCtx.message;
|
||||
const chatId = msg.chat.id;
|
||||
const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup";
|
||||
const senderId = msg.from?.id ? String(msg.from.id) : "";
|
||||
const messageThreadId = (msg as { message_thread_id?: number }).message_thread_id;
|
||||
const isForum = (msg.chat as { is_forum?: boolean }).is_forum === true;
|
||||
const threadSpec = resolveTelegramThreadSpec({
|
||||
@@ -191,7 +193,9 @@ export const buildTelegramMessageContext = async ({
|
||||
!isGroup && groupConfig && "dmPolicy" in groupConfig
|
||||
? (groupConfig.dmPolicy ?? dmPolicy)
|
||||
: dmPolicy;
|
||||
const peerId = isGroup ? buildTelegramGroupPeerId(chatId, resolvedThreadId) : String(chatId);
|
||||
const peerId = isGroup
|
||||
? buildTelegramGroupPeerId(chatId, resolvedThreadId)
|
||||
: resolveTelegramDirectPeerId({ chatId, senderId });
|
||||
const parentPeer = buildTelegramParentPeer({ isGroup, resolvedThreadId, chatId });
|
||||
// Fresh config for bindings lookup; other routing inputs are payload-derived.
|
||||
const route = resolveAgentRoute({
|
||||
@@ -235,7 +239,6 @@ export const buildTelegramMessageContext = async ({
|
||||
// Group sender checks are explicit and must not inherit DM pairing-store entries.
|
||||
const effectiveGroupAllow = normalizeAllowFrom(groupAllowOverride ?? groupAllowFrom);
|
||||
const hasGroupAllowOverride = typeof groupAllowOverride !== "undefined";
|
||||
const senderId = msg.from?.id ? String(msg.from.id) : "";
|
||||
const senderUsername = msg.from?.username ?? "";
|
||||
const baseAccess = evaluateTelegramGroupBaseAccess({
|
||||
isGroup,
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
describeReplyTarget,
|
||||
expandTextLinks,
|
||||
normalizeForwardedContext,
|
||||
resolveTelegramDirectPeerId,
|
||||
resolveTelegramForumThreadId,
|
||||
} from "./helpers.js";
|
||||
|
||||
@@ -53,6 +54,20 @@ describe("buildTypingThreadParams", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveTelegramDirectPeerId", () => {
|
||||
it("prefers sender id when available", () => {
|
||||
expect(resolveTelegramDirectPeerId({ chatId: 777777777, senderId: 123456789 })).toBe(
|
||||
"123456789",
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back to chat id when sender id is missing", () => {
|
||||
expect(resolveTelegramDirectPeerId({ chatId: 777777777, senderId: undefined })).toBe(
|
||||
"777777777",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("thread id normalization", () => {
|
||||
it.each([
|
||||
{
|
||||
|
||||
@@ -175,6 +175,24 @@ export function buildTelegramGroupPeerId(chatId: number | string, messageThreadI
|
||||
return messageThreadId != null ? `${chatId}:topic:${messageThreadId}` : String(chatId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the direct-message peer identifier for Telegram routing/session keys.
|
||||
*
|
||||
* In some Telegram DM deliveries (for example certain business/chat bridge flows),
|
||||
* `chat.id` can differ from the actual sender user id. Prefer sender id when present
|
||||
* so per-peer DM scopes isolate users correctly.
|
||||
*/
|
||||
export function resolveTelegramDirectPeerId(params: {
|
||||
chatId: number | string;
|
||||
senderId?: number | string | null;
|
||||
}) {
|
||||
const senderId = params.senderId != null ? String(params.senderId).trim() : "";
|
||||
if (senderId) {
|
||||
return senderId;
|
||||
}
|
||||
return String(params.chatId);
|
||||
}
|
||||
|
||||
export function buildTelegramGroupFrom(chatId: number | string, messageThreadId?: number) {
|
||||
return `telegram:group:${buildTelegramGroupPeerId(chatId, messageThreadId)}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user