feat(gateway): handle send_file action in Telegram service

Add sendFileToTelegram method that decodes base64 file data and sends
it via grammy's InputFile API. Handle send_file RoutedMessage action
in the virtual device sendCallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jiayuan Zhang 2026-02-13 01:37:41 +08:00
parent c64616512a
commit f5ac4b85e8

View file

@ -9,7 +9,7 @@
import { Inject, Injectable, Logger } from "@nestjs/common";
import type { OnModuleInit } from "@nestjs/common";
import { Bot, webhookCallback } from "grammy";
import { Bot, InputFile, webhookCallback } from "grammy";
import type { Context } from "grammy";
import { v7 as uuidv7 } from "uuid";
import { parseConnectionCode } from "@multica/store/connection";
@ -121,6 +121,46 @@ export class TelegramService implements OnModuleInit {
}
}
/** Send a file (photo/document/video/audio) to a Telegram user */
private async sendFileToTelegram(
telegramUserId: string,
data: Buffer,
type: string,
caption?: string,
filename?: string,
): Promise<void> {
if (!this.bot) return;
const chatId = Number(telegramUserId);
const inputFile = new InputFile(data, filename);
const extra = caption ? { caption: caption.slice(0, 1024) } : {};
try {
switch (type) {
case "photo":
await this.bot.api.sendPhoto(chatId, inputFile, extra);
break;
case "video":
await this.bot.api.sendVideo(chatId, inputFile, extra);
break;
case "audio":
await this.bot.api.sendAudio(chatId, inputFile, extra);
break;
case "voice":
await this.bot.api.sendVoice(chatId, inputFile, extra);
break;
case "document":
default:
await this.bot.api.sendDocument(chatId, inputFile, extra);
break;
}
this.logger.debug(`Sent ${type} to Telegram: telegramUserId=${telegramUserId}`);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
this.logger.error(`Failed to send ${type} to Telegram: telegramUserId=${telegramUserId}, error=${message}`);
}
}
/** Setup bot message handlers */
private setupHandlers(): void {
if (!this.bot) return;
@ -390,6 +430,26 @@ export class TelegramService implements OnModuleInit {
return;
}
// Send file — Hub agent wants to send a file to the Telegram user
if (msg.action === "send_file") {
const payload = msg.payload as {
data?: string;
type?: string;
caption?: string;
filename?: string;
};
if (payload?.data) {
void this.sendFileToTelegram(
telegramUserId,
Buffer.from(payload.data, "base64"),
payload.type ?? "document",
payload.caption,
payload.filename,
);
}
return;
}
// Regular message (e.g., "message" action from Hub)
if (msg.action === "message") {
const payload = msg.payload as { content?: string; agentId?: string };