mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 02:40:20 +00:00
refactor(agents): unify subagent announce delivery pipeline
Co-authored-by: Smith Labs <SmithLabsLLC@users.noreply.github.com> Co-authored-by: Do Cao Hieu <docaohieu2808@users.noreply.github.com>
This commit is contained in:
@@ -196,6 +196,10 @@ describe("sendMessageTelegram", () => {
|
||||
for (const testCase of cases) {
|
||||
botCtorSpy.mockClear();
|
||||
loadConfig.mockReturnValue(testCase.cfg);
|
||||
botApi.sendMessage.mockResolvedValue({
|
||||
message_id: 1,
|
||||
chat: { id: "123" },
|
||||
});
|
||||
await sendMessageTelegram("123", "hi", testCase.opts);
|
||||
expect(botCtorSpy, testCase.name).toHaveBeenCalledWith(
|
||||
"tok",
|
||||
@@ -325,6 +329,40 @@ describe("sendMessageTelegram", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("fails when Telegram text send returns no message_id", async () => {
|
||||
const sendMessage = vi.fn().mockResolvedValue({
|
||||
chat: { id: "123" },
|
||||
});
|
||||
const api = { sendMessage } as unknown as {
|
||||
sendMessage: typeof sendMessage;
|
||||
};
|
||||
|
||||
await expect(
|
||||
sendMessageTelegram("123", "hi", {
|
||||
token: "tok",
|
||||
api,
|
||||
}),
|
||||
).rejects.toThrow(/returned no message_id/i);
|
||||
});
|
||||
|
||||
it("fails when Telegram media send returns no message_id", async () => {
|
||||
mockLoadedMedia({ contentType: "image/png", fileName: "photo.png" });
|
||||
const sendPhoto = vi.fn().mockResolvedValue({
|
||||
chat: { id: "123" },
|
||||
});
|
||||
const api = { sendPhoto } as unknown as {
|
||||
sendPhoto: typeof sendPhoto;
|
||||
};
|
||||
|
||||
await expect(
|
||||
sendMessageTelegram("123", "caption", {
|
||||
token: "tok",
|
||||
api,
|
||||
mediaUrl: "https://example.com/photo.png",
|
||||
}),
|
||||
).rejects.toThrow(/returned no message_id/i);
|
||||
});
|
||||
|
||||
it("uses native fetch for BAN compatibility when api is omitted", async () => {
|
||||
const originalFetch = globalThis.fetch;
|
||||
const originalBun = (globalThis as { Bun?: unknown }).Bun;
|
||||
|
||||
@@ -86,6 +86,16 @@ type TelegramReactionOpts = {
|
||||
retry?: RetryConfig;
|
||||
};
|
||||
|
||||
function resolveTelegramMessageIdOrThrow(
|
||||
result: TelegramMessageLike | null | undefined,
|
||||
context: string,
|
||||
): number {
|
||||
if (typeof result?.message_id === "number" && Number.isFinite(result.message_id)) {
|
||||
return Math.trunc(result.message_id);
|
||||
}
|
||||
throw new Error(`Telegram ${context} returned no message_id`);
|
||||
}
|
||||
|
||||
const PARSE_ERR_RE = /can't parse entities|parse entities|find end of the entity/i;
|
||||
const THREAD_NOT_FOUND_RE = /400:\s*Bad Request:\s*message thread not found/i;
|
||||
const MESSAGE_NOT_MODIFIED_RE =
|
||||
@@ -685,11 +695,9 @@ export async function sendMessageTelegram(
|
||||
})();
|
||||
|
||||
const result = await sendMedia(mediaSender.label, mediaSender.sender);
|
||||
const mediaMessageId = String(result?.message_id ?? "unknown");
|
||||
const mediaMessageId = resolveTelegramMessageIdOrThrow(result, "media send");
|
||||
const resolvedChatId = String(result?.chat?.id ?? chatId);
|
||||
if (result?.message_id) {
|
||||
recordSentMessage(chatId, result.message_id);
|
||||
}
|
||||
recordSentMessage(chatId, mediaMessageId);
|
||||
recordChannelActivity({
|
||||
channel: "telegram",
|
||||
accountId: account.accountId,
|
||||
@@ -708,13 +716,15 @@ export async function sendMessageTelegram(
|
||||
: undefined;
|
||||
const textRes = await sendTelegramText(followUpText, textParams);
|
||||
// Return the text message ID as the "main" message (it's the actual content).
|
||||
const textMessageId = resolveTelegramMessageIdOrThrow(textRes, "text follow-up send");
|
||||
recordSentMessage(chatId, textMessageId);
|
||||
return {
|
||||
messageId: String(textRes?.message_id ?? mediaMessageId),
|
||||
messageId: String(textMessageId),
|
||||
chatId: resolvedChatId,
|
||||
};
|
||||
}
|
||||
|
||||
return { messageId: mediaMessageId, chatId: resolvedChatId };
|
||||
return { messageId: String(mediaMessageId), chatId: resolvedChatId };
|
||||
}
|
||||
|
||||
if (!text || !text.trim()) {
|
||||
@@ -728,16 +738,14 @@ export async function sendMessageTelegram(
|
||||
}
|
||||
: undefined;
|
||||
const res = await sendTelegramText(text, textParams, opts.plainText);
|
||||
const messageId = String(res?.message_id ?? "unknown");
|
||||
if (res?.message_id) {
|
||||
recordSentMessage(chatId, res.message_id);
|
||||
}
|
||||
const messageId = resolveTelegramMessageIdOrThrow(res, "text send");
|
||||
recordSentMessage(chatId, messageId);
|
||||
recordChannelActivity({
|
||||
channel: "telegram",
|
||||
accountId: account.accountId,
|
||||
direction: "outbound",
|
||||
});
|
||||
return { messageId, chatId: String(res?.chat?.id ?? chatId) };
|
||||
return { messageId: String(messageId), chatId: String(res?.chat?.id ?? chatId) };
|
||||
}
|
||||
|
||||
export async function reactMessageTelegram(
|
||||
@@ -1013,18 +1021,16 @@ export async function sendStickerTelegram(
|
||||
requestWithChatNotFound(() => api.sendSticker(chatId, fileId.trim(), effectiveParams), label),
|
||||
);
|
||||
|
||||
const messageId = String(result?.message_id ?? "unknown");
|
||||
const messageId = resolveTelegramMessageIdOrThrow(result, "sticker send");
|
||||
const resolvedChatId = String(result?.chat?.id ?? chatId);
|
||||
if (result?.message_id) {
|
||||
recordSentMessage(chatId, result.message_id);
|
||||
}
|
||||
recordSentMessage(chatId, messageId);
|
||||
recordChannelActivity({
|
||||
channel: "telegram",
|
||||
accountId: account.accountId,
|
||||
direction: "outbound",
|
||||
});
|
||||
|
||||
return { messageId, chatId: resolvedChatId };
|
||||
return { messageId: String(messageId), chatId: resolvedChatId };
|
||||
}
|
||||
|
||||
type TelegramPollOpts = {
|
||||
@@ -1121,12 +1127,10 @@ export async function sendPollTelegram(
|
||||
),
|
||||
);
|
||||
|
||||
const messageId = String(result?.message_id ?? "unknown");
|
||||
const messageId = resolveTelegramMessageIdOrThrow(result, "poll send");
|
||||
const resolvedChatId = String(result?.chat?.id ?? chatId);
|
||||
const pollId = result?.poll?.id;
|
||||
if (result?.message_id) {
|
||||
recordSentMessage(chatId, result.message_id);
|
||||
}
|
||||
recordSentMessage(chatId, messageId);
|
||||
|
||||
recordChannelActivity({
|
||||
channel: "telegram",
|
||||
@@ -1134,7 +1138,7 @@ export async function sendPollTelegram(
|
||||
direction: "outbound",
|
||||
});
|
||||
|
||||
return { messageId, chatId: resolvedChatId, pollId };
|
||||
return { messageId: String(messageId), chatId: resolvedChatId, pollId };
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user