Add accountId and config support to Telegram webhook
The Telegram webhook and monitor now accept and pass through accountId and config parameters, enabling routing and configuration per Telegram account. Tests have been updated to verify correct bot instantiation and DM routing based on accountId bindings.
This commit is contained in:
committed by
Peter Steinberger
parent
ab993904d7
commit
ecb91bbb1a
@@ -887,6 +887,53 @@ describe("createTelegramBot", () => {
|
||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("routes DMs by telegram accountId binding", async () => {
|
||||
onSpy.mockReset();
|
||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<
|
||||
typeof vi.fn
|
||||
>;
|
||||
replySpy.mockReset();
|
||||
|
||||
loadConfig.mockReturnValue({
|
||||
telegram: {
|
||||
accounts: {
|
||||
opie: {
|
||||
botToken: "tok-opie",
|
||||
dmPolicy: "open",
|
||||
},
|
||||
},
|
||||
},
|
||||
bindings: [
|
||||
{
|
||||
agentId: "opie",
|
||||
match: { provider: "telegram", accountId: "opie" },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
createTelegramBot({ token: "tok", accountId: "opie" });
|
||||
const handler = getOnHandler("message") as (
|
||||
ctx: Record<string, unknown>,
|
||||
) => Promise<void>;
|
||||
|
||||
await handler({
|
||||
message: {
|
||||
chat: { id: 123, type: "private" },
|
||||
from: { id: 999, username: "testuser" },
|
||||
text: "hello",
|
||||
date: 1736380800,
|
||||
message_id: 42,
|
||||
},
|
||||
me: { username: "clawdbot_bot" },
|
||||
getFile: async () => ({ download: async () => new Uint8Array() }),
|
||||
});
|
||||
|
||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||
const payload = replySpy.mock.calls[0][0];
|
||||
expect(payload.AccountId).toBe("opie");
|
||||
expect(payload.SessionKey).toBe("agent:opie:main");
|
||||
});
|
||||
|
||||
it("allows per-group requireMention override", async () => {
|
||||
onSpy.mockReset();
|
||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<
|
||||
|
||||
@@ -96,6 +96,8 @@ export async function monitorTelegramProvider(opts: MonitorTelegramOpts = {}) {
|
||||
if (opts.useWebhook) {
|
||||
await startTelegramWebhook({
|
||||
token,
|
||||
accountId: account.accountId,
|
||||
config: cfg,
|
||||
path: opts.webhookPath,
|
||||
port: opts.webhookPort,
|
||||
secret: opts.webhookSecret,
|
||||
|
||||
@@ -14,25 +14,33 @@ const handlerSpy = vi.fn(
|
||||
const setWebhookSpy = vi.fn();
|
||||
const stopSpy = vi.fn();
|
||||
|
||||
const createTelegramBotSpy = vi.fn(() => ({
|
||||
api: { setWebhook: setWebhookSpy },
|
||||
stop: stopSpy,
|
||||
}));
|
||||
|
||||
vi.mock("grammy", () => ({
|
||||
webhookCallback: () => handlerSpy,
|
||||
}));
|
||||
|
||||
vi.mock("./bot.js", () => ({
|
||||
createTelegramBot: () => ({
|
||||
api: { setWebhook: setWebhookSpy },
|
||||
stop: stopSpy,
|
||||
}),
|
||||
createTelegramBot: (...args: unknown[]) => createTelegramBotSpy(...args),
|
||||
}));
|
||||
|
||||
describe("startTelegramWebhook", () => {
|
||||
it("starts server, registers webhook, and serves health", async () => {
|
||||
createTelegramBotSpy.mockClear();
|
||||
const abort = new AbortController();
|
||||
const { server } = await startTelegramWebhook({
|
||||
token: "tok",
|
||||
accountId: "opie",
|
||||
config: { bindings: [] },
|
||||
port: 0, // random free port
|
||||
abortSignal: abort.signal,
|
||||
});
|
||||
expect(createTelegramBotSpy).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ accountId: "opie" }),
|
||||
);
|
||||
const address = server.address();
|
||||
if (!address || typeof address === "string") throw new Error("no address");
|
||||
const url = `http://127.0.0.1:${address.port}`;
|
||||
@@ -46,9 +54,12 @@ describe("startTelegramWebhook", () => {
|
||||
|
||||
it("invokes webhook handler on matching path", async () => {
|
||||
handlerSpy.mockClear();
|
||||
createTelegramBotSpy.mockClear();
|
||||
const abort = new AbortController();
|
||||
const { server } = await startTelegramWebhook({
|
||||
token: "tok",
|
||||
accountId: "opie",
|
||||
config: { bindings: [] },
|
||||
port: 0,
|
||||
abortSignal: abort.signal,
|
||||
path: "/hook",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createServer } from "node:http";
|
||||
|
||||
import { webhookCallback } from "grammy";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
@@ -8,6 +9,8 @@ import { createTelegramBot } from "./bot.js";
|
||||
|
||||
export async function startTelegramWebhook(opts: {
|
||||
token: string;
|
||||
accountId?: string;
|
||||
config?: ClawdbotConfig;
|
||||
path?: string;
|
||||
port?: number;
|
||||
host?: string;
|
||||
@@ -27,6 +30,8 @@ export async function startTelegramWebhook(opts: {
|
||||
token: opts.token,
|
||||
runtime,
|
||||
proxyFetch: opts.fetch,
|
||||
config: opts.config,
|
||||
accountId: opts.accountId,
|
||||
});
|
||||
const handler = webhookCallback(bot, "http", {
|
||||
secretToken: opts.secret,
|
||||
|
||||
Reference in New Issue
Block a user