mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 11:55:47 -06:00
fix(telegram): send attachment paths as media
This commit is contained in:
committed by
Peter Steinberger
parent
c897384ae9
commit
fdf01db62b
@@ -561,6 +561,60 @@ describe("handleTelegramAction", () => {
|
||||
expect(options.mediaUrl).toBe("https://example.com/image.jpg");
|
||||
});
|
||||
|
||||
it.each(["path", "filePath"] as const)("uses top-level %s as sendMessage media", async (key) => {
|
||||
const mediaPath = `/tmp/customer_support_${key}.png`;
|
||||
await handleTelegramAction(
|
||||
{
|
||||
action: "sendMessage",
|
||||
to: "telegram:-100123:topic:879",
|
||||
message: "Productivity",
|
||||
[key]: mediaPath,
|
||||
},
|
||||
telegramConfig(),
|
||||
);
|
||||
const call = mockCall(sendMessageTelegram, 0, `${key} media`);
|
||||
expect(call[0]).toBe("telegram:-100123:topic:879");
|
||||
expect(call[1]).toBe("Productivity");
|
||||
const options = requireRecord(call[2], `${key} media options`);
|
||||
expect(options.token).toBe("tok");
|
||||
expect(options.mediaUrl).toBe(mediaPath);
|
||||
});
|
||||
|
||||
it("sends all attachment paths as sendMessage media", async () => {
|
||||
await handleTelegramAction(
|
||||
{
|
||||
action: "sendMessage",
|
||||
to: "telegram:-100123:topic:879",
|
||||
message: "1/2 Productivity",
|
||||
attachments: [
|
||||
{
|
||||
type: "image",
|
||||
path: "/tmp/customer_support_productivity.png",
|
||||
name: "customer_support_productivity.png",
|
||||
},
|
||||
{
|
||||
type: "image",
|
||||
filePath: "/tmp/customer_support_resolution.png",
|
||||
name: "customer_support_resolution.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
telegramConfig(),
|
||||
);
|
||||
const call = mockCall(sendMessageTelegram, 0, "attachment media");
|
||||
expect(call[0]).toBe("telegram:-100123:topic:879");
|
||||
expect(call[1]).toBe("1/2 Productivity");
|
||||
const options = requireRecord(call[2], "attachment media options");
|
||||
expect(options.token).toBe("tok");
|
||||
expect(options.mediaUrl).toBe("/tmp/customer_support_productivity.png");
|
||||
const followUpCall = mockCall(sendMessageTelegram, 1, "second attachment media");
|
||||
expect(followUpCall[0]).toBe("telegram:-100123:topic:879");
|
||||
expect(followUpCall[1]).toBe("");
|
||||
const followUpOptions = requireRecord(followUpCall[2], "second attachment media options");
|
||||
expect(followUpOptions.token).toBe("tok");
|
||||
expect(followUpOptions.mediaUrl).toBe("/tmp/customer_support_resolution.png");
|
||||
});
|
||||
|
||||
it("sends a poll", async () => {
|
||||
const result = await handleTelegramAction(
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
renderMessagePresentationFallbackText,
|
||||
} from "openclaw/plugin-sdk/interactive-runtime";
|
||||
import type { MessagePresentation } from "openclaw/plugin-sdk/interactive-runtime";
|
||||
import { sendPayloadMediaSequenceOrFallback } from "openclaw/plugin-sdk/reply-payload";
|
||||
import { createTelegramActionGate, resolveTelegramPollActionGateState } from "./accounts.js";
|
||||
import { resolveTelegramInlineButtons } from "./button-types.js";
|
||||
import { notifyTelegramInboundEventOutboundSuccess } from "./inbound-event-delivery.js";
|
||||
@@ -132,6 +133,48 @@ function readTelegramReplyToMessageId(params: Record<string, unknown>) {
|
||||
);
|
||||
}
|
||||
|
||||
function pushTelegramMediaUrl(mediaUrls: string[], seen: Set<string>, value: unknown): void {
|
||||
if (typeof value !== "string") {
|
||||
return;
|
||||
}
|
||||
const normalized = value.trim();
|
||||
if (!normalized || seen.has(normalized)) {
|
||||
return;
|
||||
}
|
||||
seen.add(normalized);
|
||||
mediaUrls.push(normalized);
|
||||
}
|
||||
|
||||
function readTelegramSendMediaUrls(params: Record<string, unknown>) {
|
||||
const mediaUrls: string[] = [];
|
||||
const seen = new Set<string>();
|
||||
pushTelegramMediaUrl(mediaUrls, seen, params.mediaUrl);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, params.media);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, params.path);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, params.filePath);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, params.fileUrl);
|
||||
if (Array.isArray(params.mediaUrls)) {
|
||||
for (const mediaUrl of params.mediaUrls) {
|
||||
pushTelegramMediaUrl(mediaUrls, seen, mediaUrl);
|
||||
}
|
||||
}
|
||||
if (Array.isArray(params.attachments)) {
|
||||
for (const attachment of params.attachments) {
|
||||
if (!attachment || typeof attachment !== "object" || Array.isArray(attachment)) {
|
||||
continue;
|
||||
}
|
||||
const record = attachment as Record<string, unknown>;
|
||||
pushTelegramMediaUrl(mediaUrls, seen, record.media);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, record.mediaUrl);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, record.path);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, record.filePath);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, record.fileUrl);
|
||||
pushTelegramMediaUrl(mediaUrls, seen, record.url);
|
||||
}
|
||||
}
|
||||
return mediaUrls;
|
||||
}
|
||||
|
||||
function resolveTelegramButtonsFromParams(
|
||||
params: Record<string, unknown>,
|
||||
presentation = normalizeMessagePresentation(params.presentation),
|
||||
@@ -350,16 +393,13 @@ export async function handleTelegramAction(
|
||||
throw new Error("Telegram sendMessage is disabled.");
|
||||
}
|
||||
const to = readStringParam(params, "to", { required: true });
|
||||
const mediaUrl =
|
||||
readStringParam(params, "mediaUrl") ??
|
||||
readStringParam(params, "media", {
|
||||
trim: false,
|
||||
});
|
||||
const mediaUrls = readTelegramSendMediaUrls(params);
|
||||
const firstMediaUrl = mediaUrls[0];
|
||||
const presentation = normalizeMessagePresentation(params.presentation);
|
||||
const buttons = resolveTelegramButtonsFromParams(params, presentation);
|
||||
const content = readTelegramSendContent({
|
||||
args: params,
|
||||
mediaUrl: mediaUrl ?? undefined,
|
||||
mediaUrl: firstMediaUrl,
|
||||
hasButtons: Array.isArray(buttons) && buttons.length > 0,
|
||||
interactive: params.interactive,
|
||||
presentation,
|
||||
@@ -401,15 +441,13 @@ export async function handleTelegramAction(
|
||||
"Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.",
|
||||
);
|
||||
}
|
||||
const result = await telegramActionRuntime.sendMessageTelegram(to, content, {
|
||||
const sendOptions = {
|
||||
cfg,
|
||||
token,
|
||||
accountId: accountId ?? undefined,
|
||||
mediaUrl: mediaUrl || undefined,
|
||||
mediaLocalRoots: options?.mediaLocalRoots,
|
||||
mediaReadFile: options?.mediaReadFile,
|
||||
gatewayClientScopes: options?.gatewayClientScopes,
|
||||
buttons,
|
||||
replyToMessageId: replyToMessageId ?? undefined,
|
||||
messageThreadId: messageThreadId ?? undefined,
|
||||
quoteText: quoteText ?? undefined,
|
||||
@@ -419,6 +457,22 @@ export async function handleTelegramAction(
|
||||
readBooleanParam(params, "forceDocument") ??
|
||||
readBooleanParam(params, "asDocument") ??
|
||||
false,
|
||||
};
|
||||
const result = await sendPayloadMediaSequenceOrFallback({
|
||||
text: content,
|
||||
mediaUrls,
|
||||
fallbackResult: { messageId: "unknown", chatId: to },
|
||||
sendNoMedia: async () =>
|
||||
await telegramActionRuntime.sendMessageTelegram(to, content, {
|
||||
...sendOptions,
|
||||
buttons,
|
||||
}),
|
||||
send: async ({ text, mediaUrl, isFirst }) =>
|
||||
await telegramActionRuntime.sendMessageTelegram(to, text, {
|
||||
...sendOptions,
|
||||
mediaUrl,
|
||||
...(isFirst ? { buttons } : {}),
|
||||
}),
|
||||
});
|
||||
notifyVisibleOutboundSuccess(to, messageThreadId);
|
||||
await maybePinTelegramActionSend({
|
||||
|
||||
Reference in New Issue
Block a user