feat: unify provider reaction tools
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
export { createTelegramBot, createTelegramWebhookCallback } from "./bot.js";
|
||||
export { monitorTelegramProvider } from "./monitor.js";
|
||||
export { sendMessageTelegram } from "./send.js";
|
||||
export { reactMessageTelegram, sendMessageTelegram } from "./send.js";
|
||||
export { startTelegramWebhook } from "./webhook.js";
|
||||
|
||||
@@ -8,7 +8,7 @@ vi.mock("../web/media.js", () => ({
|
||||
loadWebMedia,
|
||||
}));
|
||||
|
||||
import { sendMessageTelegram } from "./send.js";
|
||||
import { reactMessageTelegram, sendMessageTelegram } from "./send.js";
|
||||
|
||||
describe("sendMessageTelegram", () => {
|
||||
beforeEach(() => {
|
||||
@@ -108,3 +108,50 @@ describe("sendMessageTelegram", () => {
|
||||
expect(res.messageId).toBe("9");
|
||||
});
|
||||
});
|
||||
|
||||
describe("reactMessageTelegram", () => {
|
||||
it("sends emoji reactions", async () => {
|
||||
const setMessageReaction = vi.fn().mockResolvedValue(undefined);
|
||||
const api = { setMessageReaction } as unknown as {
|
||||
setMessageReaction: typeof setMessageReaction;
|
||||
};
|
||||
|
||||
await reactMessageTelegram("telegram:123", "456", "✅", {
|
||||
token: "tok",
|
||||
api,
|
||||
});
|
||||
|
||||
expect(setMessageReaction).toHaveBeenCalledWith("123", 456, [
|
||||
{ type: "emoji", emoji: "✅" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("removes reactions when emoji is empty", async () => {
|
||||
const setMessageReaction = vi.fn().mockResolvedValue(undefined);
|
||||
const api = { setMessageReaction } as unknown as {
|
||||
setMessageReaction: typeof setMessageReaction;
|
||||
};
|
||||
|
||||
await reactMessageTelegram("123", 456, "", {
|
||||
token: "tok",
|
||||
api,
|
||||
});
|
||||
|
||||
expect(setMessageReaction).toHaveBeenCalledWith("123", 456, []);
|
||||
});
|
||||
|
||||
it("removes reactions when remove flag is set", async () => {
|
||||
const setMessageReaction = vi.fn().mockResolvedValue(undefined);
|
||||
const api = { setMessageReaction } as unknown as {
|
||||
setMessageReaction: typeof setMessageReaction;
|
||||
};
|
||||
|
||||
await reactMessageTelegram("123", 456, "✅", {
|
||||
token: "tok",
|
||||
api,
|
||||
remove: true,
|
||||
});
|
||||
|
||||
expect(setMessageReaction).toHaveBeenCalledWith("123", 456, []);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,6 +18,12 @@ type TelegramSendResult = {
|
||||
chatId: string;
|
||||
};
|
||||
|
||||
type TelegramReactionOpts = {
|
||||
token?: string;
|
||||
api?: Bot["api"];
|
||||
remove?: boolean;
|
||||
};
|
||||
|
||||
const PARSE_ERR_RE =
|
||||
/can't parse entities|parse entities|find end of the entity/i;
|
||||
|
||||
@@ -57,6 +63,21 @@ function normalizeChatId(to: string): string {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function normalizeMessageId(raw: string | number): number {
|
||||
if (typeof raw === "number" && Number.isFinite(raw)) {
|
||||
return Math.trunc(raw);
|
||||
}
|
||||
if (typeof raw === "string") {
|
||||
const value = raw.trim();
|
||||
if (!value) {
|
||||
throw new Error("Message id is required for Telegram reactions");
|
||||
}
|
||||
const parsed = Number.parseInt(value, 10);
|
||||
if (Number.isFinite(parsed)) return parsed;
|
||||
}
|
||||
throw new Error("Message id is required for Telegram reactions");
|
||||
}
|
||||
|
||||
export async function sendMessageTelegram(
|
||||
to: string,
|
||||
text: string,
|
||||
@@ -196,6 +217,28 @@ export async function sendMessageTelegram(
|
||||
return { messageId, chatId: String(res?.chat?.id ?? chatId) };
|
||||
}
|
||||
|
||||
export async function reactMessageTelegram(
|
||||
chatIdInput: string | number,
|
||||
messageIdInput: string | number,
|
||||
emoji: string,
|
||||
opts: TelegramReactionOpts = {},
|
||||
): Promise<{ ok: true }> {
|
||||
const token = resolveToken(opts.token);
|
||||
const chatId = normalizeChatId(String(chatIdInput));
|
||||
const messageId = normalizeMessageId(messageIdInput);
|
||||
const bot = opts.api ? null : new Bot(token);
|
||||
const api = opts.api ?? bot?.api;
|
||||
const remove = opts.remove === true;
|
||||
const trimmedEmoji = emoji.trim();
|
||||
const reactions =
|
||||
remove || !trimmedEmoji ? [] : [{ type: "emoji", emoji: trimmedEmoji }];
|
||||
if (typeof api.setMessageReaction !== "function") {
|
||||
throw new Error("Telegram reactions are unavailable in this bot API.");
|
||||
}
|
||||
await api.setMessageReaction(chatId, messageId, reactions);
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
function inferFilename(kind: ReturnType<typeof mediaKindFromMime>) {
|
||||
switch (kind) {
|
||||
case "image":
|
||||
|
||||
Reference in New Issue
Block a user