fix(telegram): wire sendPollTelegram into channel action handler (#16977)
The Telegram channel adapter listed no 'poll' action, so agents could not create polls via the unified action interface. The underlying sendPollTelegram function was already implemented but unreachable. Changes: - telegram.ts: add 'poll' to listActions (enabled by default via gate), add handleAction branch that reads pollQuestion/pollOption params and delegates to handleTelegramAction with action 'sendPoll'. - telegram-actions.ts: add 'sendPoll' handler that validates question, options (≥2), and forwards to sendPollTelegram with threading, silent, and anonymous options. - actions.test.ts: add test verifying poll action routes correctly. Fixes #16977
This commit is contained in:
committed by
Peter Steinberger
parent
068b9c9749
commit
7bb9a7dcfc
@@ -402,5 +402,42 @@ export async function handleTelegramAction(
|
||||
return jsonResult({ ok: true, ...stats });
|
||||
}
|
||||
|
||||
if (action === "sendPoll") {
|
||||
const to = readStringParam(params, "to", { required: true });
|
||||
const question = readStringParam(params, "question") ?? readStringParam(params, "pollQuestion");
|
||||
if (!question) {
|
||||
throw new Error("sendPoll requires 'question'");
|
||||
}
|
||||
const options = (params.options ?? params.pollOption) as string[] | undefined;
|
||||
if (!options || options.length < 2) {
|
||||
throw new Error("sendPoll requires at least 2 options");
|
||||
}
|
||||
const maxSelections =
|
||||
typeof params.maxSelections === "number" ? params.maxSelections : undefined;
|
||||
const isAnonymous = typeof params.isAnonymous === "boolean" ? params.isAnonymous : undefined;
|
||||
const silent = typeof params.silent === "boolean" ? params.silent : undefined;
|
||||
const replyToMessageId = readNumberParam(params, "replyTo");
|
||||
const messageThreadId = readNumberParam(params, "threadId");
|
||||
const pollAccountId = readStringParam(params, "accountId");
|
||||
|
||||
const res = await sendPollTelegram(
|
||||
to,
|
||||
{ question, options, maxSelections },
|
||||
{
|
||||
accountId: pollAccountId?.trim() || undefined,
|
||||
replyToMessageId,
|
||||
messageThreadId,
|
||||
isAnonymous,
|
||||
silent,
|
||||
},
|
||||
);
|
||||
return jsonResult({
|
||||
ok: true,
|
||||
messageId: res.messageId,
|
||||
chatId: res.chatId,
|
||||
pollId: res.pollId,
|
||||
});
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported Telegram action: ${action}`);
|
||||
}
|
||||
|
||||
@@ -489,6 +489,31 @@ describe("telegramMessageActions", () => {
|
||||
expect(String(call.messageId)).toBe("456");
|
||||
expect(call.emoji).toBe("ok");
|
||||
});
|
||||
|
||||
it("routes poll action to sendPoll with question and options", async () => {
|
||||
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
|
||||
|
||||
await telegramMessageActions.handleAction({
|
||||
action: "poll",
|
||||
params: {
|
||||
to: "-100123",
|
||||
pollQuestion: "Ready?",
|
||||
pollOption: ["Yes", "No", "Maybe"],
|
||||
},
|
||||
cfg,
|
||||
accountId: undefined,
|
||||
});
|
||||
|
||||
expect(handleTelegramAction).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
action: "sendPoll",
|
||||
to: "-100123",
|
||||
question: "Ready?",
|
||||
options: ["Yes", "No", "Maybe"],
|
||||
}),
|
||||
cfg,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("signalMessageActions", () => {
|
||||
|
||||
@@ -52,6 +52,9 @@ export const telegramMessageActions: ChannelMessageActionAdapter = {
|
||||
const gate = (key: keyof TelegramActionConfig, defaultValue = true) =>
|
||||
gates.some((g) => g(key, defaultValue));
|
||||
const actions = new Set<ChannelMessageActionName>(["send"]);
|
||||
if (gate("poll")) {
|
||||
actions.add("poll");
|
||||
}
|
||||
if (gate("reactions")) {
|
||||
actions.add("react");
|
||||
}
|
||||
@@ -232,6 +235,31 @@ export const telegramMessageActions: ChannelMessageActionAdapter = {
|
||||
);
|
||||
}
|
||||
|
||||
if (action === "poll") {
|
||||
const to = readStringParam(params, "to", { required: true });
|
||||
const question =
|
||||
readStringParam(params, "pollQuestion") ??
|
||||
readStringParam(params, "question", { required: true });
|
||||
const options =
|
||||
readStringArrayParam(params, "pollOption") ?? readStringArrayParam(params, "options");
|
||||
const threadId = readStringParam(params, "threadId");
|
||||
const replyTo = readStringParam(params, "replyTo");
|
||||
const silent = typeof params.silent === "boolean" ? params.silent : undefined;
|
||||
return await handleTelegramAction(
|
||||
{
|
||||
action: "sendPoll",
|
||||
to,
|
||||
question,
|
||||
options,
|
||||
replyTo: replyTo != null ? Number(replyTo) : undefined,
|
||||
threadId: threadId != null ? Number(threadId) : undefined,
|
||||
silent,
|
||||
accountId: accountId ?? undefined,
|
||||
},
|
||||
cfg,
|
||||
);
|
||||
}
|
||||
|
||||
throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -18,6 +18,8 @@ export type TelegramActionConfig = {
|
||||
polls?: boolean;
|
||||
deleteMessage?: boolean;
|
||||
editMessage?: boolean;
|
||||
/** Enable poll actions (sendPoll). */
|
||||
poll?: boolean;
|
||||
/** Enable sticker actions (send and search). */
|
||||
sticker?: boolean;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user