mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-11 06:33:17 +08:00
feat: support inbound files across all channels
This commit is contained in:
parent
29bcb67a64
commit
0a26d7df92
45 changed files with 2651 additions and 343 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import { fetchFileStream } from '../shared/file-download.mjs';
|
||||
import { fetchImageBuffer } from '../shared/image-prompt.mjs';
|
||||
|
||||
const DEFAULT_BASE_URL = 'https://api.telegram.org/';
|
||||
|
|
@ -131,6 +132,25 @@ export class TelegramApi {
|
|||
}
|
||||
|
||||
async downloadFile({ fileId, signal, maxBytes } = {}) {
|
||||
const url = await this.#downloadUrl(fileId, signal);
|
||||
return fetchImageBuffer(url, {
|
||||
fetchImpl: this.#fetch,
|
||||
signal,
|
||||
maxBytes,
|
||||
allowedHosts: TELEGRAM_FILE_HOSTS,
|
||||
});
|
||||
}
|
||||
|
||||
async downloadFileStream({ fileId, signal } = {}) {
|
||||
const url = await this.#downloadUrl(fileId, signal);
|
||||
return fetchFileStream(url, {
|
||||
fetchImpl: this.#fetch,
|
||||
signal,
|
||||
allowedHosts: TELEGRAM_FILE_HOSTS,
|
||||
});
|
||||
}
|
||||
|
||||
async #downloadUrl(fileId, signal) {
|
||||
const file = await this.getFile({ fileId, signal });
|
||||
const filePath = cleanString(file?.file_path);
|
||||
if (!filePath || filePath.startsWith('/') || filePath.includes('\\')
|
||||
|
|
@ -148,12 +168,7 @@ export class TelegramApi {
|
|||
}
|
||||
const url = new URL(this.#baseUrl);
|
||||
url.pathname = `/file/bot${this.#token}/${filePath}`;
|
||||
return fetchImageBuffer(url, {
|
||||
fetchImpl: this.#fetch,
|
||||
signal,
|
||||
maxBytes,
|
||||
allowedHosts: TELEGRAM_FILE_HOSTS,
|
||||
});
|
||||
return url;
|
||||
}
|
||||
|
||||
async sendMessage({ chatId, text, replyToMessageId, messageThreadId, signal }) {
|
||||
|
|
|
|||
|
|
@ -100,9 +100,27 @@ function telegramImageSource(message, loadFile) {
|
|||
};
|
||||
}
|
||||
|
||||
export function normalizeTelegramUpdate(update, { botId, username, loadFile = async () => {
|
||||
throw new Error('Telegram file downloader is unavailable');
|
||||
} }) {
|
||||
function telegramFileSource(message, loadFile) {
|
||||
const file = message?.document;
|
||||
if (!file || imageTypeForDocument(file)
|
||||
|| typeof file.file_id !== 'string' || !file.file_id) return null;
|
||||
const mediaType = typeof file.mime_type === 'string' && file.mime_type
|
||||
? file.mime_type.toLowerCase() : undefined;
|
||||
return {
|
||||
name: typeof file.file_name === 'string' && file.file_name
|
||||
? file.file_name : String(file.file_unique_id ?? file.file_id),
|
||||
...(mediaType ? { mediaType } : {}),
|
||||
size: fileSize(file.file_size),
|
||||
load: ({ signal } = {}) => loadFile(file.file_id, { signal }),
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeTelegramUpdate(update, {
|
||||
botId,
|
||||
username,
|
||||
loadFile = async () => { throw new Error('Telegram file downloader is unavailable'); },
|
||||
loadFileStream = loadFile,
|
||||
}) {
|
||||
const message = update?.message;
|
||||
const chatId = message?.chat?.id;
|
||||
const senderId = message?.from?.id;
|
||||
|
|
@ -117,6 +135,7 @@ export function normalizeTelegramUpdate(update, { botId, username, loadFile = as
|
|||
const messageThreadId = Number.isSafeInteger(message.message_thread_id)
|
||||
? message.message_thread_id : undefined;
|
||||
const image = telegramImageSource(message, loadFile);
|
||||
const file = telegramFileSource(message, loadFileStream);
|
||||
return {
|
||||
messageId: String(update.update_id),
|
||||
senderId: String(senderId),
|
||||
|
|
@ -126,6 +145,7 @@ export function normalizeTelegramUpdate(update, { botId, username, loadFile = as
|
|||
? String(chatId) : `${chatId}:${messageThreadId}`,
|
||||
content: withoutBotMention(message.text ?? message.caption ?? '', username),
|
||||
images: image ? [image] : [],
|
||||
files: file ? [file] : [],
|
||||
addressed,
|
||||
replyTarget: {
|
||||
chatId,
|
||||
|
|
@ -381,6 +401,7 @@ export class TelegramRuntime {
|
|||
botId: this.#config.platformId,
|
||||
username: this.#config.username,
|
||||
loadFile: (fileId, options) => this.#api.downloadFile({ fileId, ...options }),
|
||||
loadFileStream: (fileId, options) => this.#api.downloadFileStream({ fileId, ...options }),
|
||||
});
|
||||
if (message && telegramInboundAllowed(message, {
|
||||
accessMode: this.#accessMode,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue