core-edge / src /lib /telegram.ts
dragxd's picture
Initial commit: VoltEdge project
3353b25
export interface TelegramFileResult {
file_id: string;
file_unique_id: string;
file_path?: string;
file_size?: number;
}
export interface TelegramUpdate {
update_id: number;
message?: {
message_id: number;
from: {
id: number;
first_name: string;
username?: string;
};
chat: {
id: number;
type: string;
};
text?: string;
photo?: Array<{
file_id: string;
file_unique_id: string;
file_size: number;
width: number;
height: number;
}>;
document?: {
file_id: string;
file_unique_id: string;
file_name?: string;
mime_type?: string;
file_size: number;
};
animation?: {
file_id: string;
file_unique_id: string;
file_size: number;
mime_type?: string;
};
reply_to_message?: {
message_id: number;
photo?: Array<{
file_id: string;
file_unique_id: string;
file_size: number;
width: number;
height: number;
}>;
document?: {
file_id: string;
file_unique_id: string;
file_name?: string;
mime_type?: string;
file_size: number;
};
animation?: {
file_id: string;
file_unique_id: string;
file_size: number;
mime_type?: string;
};
};
};
}
export async function uploadToTelegram(file: Blob, fileName: string, caption?: string, mediaType: 'photo' | 'animation' | 'video' = 'photo'): Promise<TelegramFileResult> {
const token = process.env.TELEGRAM_BOT_TOKEN;
const chatId = process.env.TELEGRAM_CHAT_ID;
if (!token || !chatId) {
throw new Error('Telegram credentials not configured');
}
const formData = new FormData();
formData.append('chat_id', chatId);
let method = 'sendPhoto';
let fieldName = 'photo';
if (mediaType === 'animation') {
method = 'sendAnimation';
fieldName = 'animation';
} else if (mediaType === 'video') {
method = 'sendVideo';
fieldName = 'video';
}
formData.append(fieldName, file, fileName);
if (caption) {
formData.append('caption', caption);
formData.append('parse_mode', 'HTML');
}
const response = await fetch(`https://api.telegram.org/bot${token}/${method}`, {
method: 'POST',
body: formData,
});
const data = await response.json();
if (!data.ok) {
throw new Error(`Telegram API error: ${data.description}`);
}
let fileId = '';
let fileUniqueId = '';
if (mediaType === 'animation') {
// For animations, it's a single object in 'animation' or 'document' field
const fileInfo = data.result.animation || data.result.document;
fileId = fileInfo.file_id;
fileUniqueId = fileInfo.file_unique_id;
} else if (mediaType === 'video') {
const fileInfo = data.result.video || data.result.document;
fileId = fileInfo.file_id;
fileUniqueId = fileInfo.file_unique_id;
} else {
// For photos, it's an array of sizes
const photos = data.result.photo;
const largestPhoto = photos[photos.length - 1];
fileId = largestPhoto.file_id;
fileUniqueId = largestPhoto.file_unique_id;
}
return {
file_id: fileId,
file_unique_id: fileUniqueId,
};
}
export async function getTelegramFileUrl(fileId: string): Promise<string> {
const token = process.env.TELEGRAM_BOT_TOKEN;
if (!token) {
throw new Error('Telegram token not configured');
}
const response = await fetch(`https://api.telegram.org/bot${token}/getFile?file_id=${fileId}`);
const data = await response.json();
if (!data.ok) {
throw new Error(`Telegram API error: ${data.description}`);
}
const filePath = data.result.file_path;
return `https://api.telegram.org/file/bot${token}/${filePath}`;
}
/**
* Download file from Telegram by file_id
*/
export async function downloadTelegramFile(fileId: string): Promise<Blob> {
const fileUrl = await getTelegramFileUrl(fileId);
const response = await fetch(fileUrl);
if (!response.ok) {
throw new Error(`Failed to download file from Telegram: ${response.statusText}`);
}
return response.blob();
}
export async function sendMessage(chatId: number | string, text: string, parseMode: 'HTML' | 'Markdown' = 'HTML', replyMarkup?: any): Promise<void> {
const token = process.env.TELEGRAM_BOT_TOKEN;
if (!token) return;
await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: chatId,
text,
parse_mode: parseMode,
disable_web_page_preview: false,
reply_markup: replyMarkup
}),
});
}
export async function sendMediaToChannel(fileId: string, caption: string, mediaType: 'photo' | 'animation' | 'video' = 'photo'): Promise<TelegramFileResult | void> {
const token = process.env.TELEGRAM_BOT_TOKEN;
const chatId = process.env.TELEGRAM_CHAT_ID;
if (!token || !chatId) return;
let method = 'sendPhoto';
if (mediaType === 'animation') method = 'sendAnimation';
if (mediaType === 'video') method = 'sendVideo';
const body: any = {
chat_id: chatId,
caption,
parse_mode: 'HTML'
};
if (mediaType === 'animation') {
body.animation = fileId;
} else if (mediaType === 'video') {
body.video = fileId;
} else {
body.photo = fileId;
}
await fetch(`https://api.telegram.org/bot${token}/${method}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
}
export async function sendLog(text: string): Promise<void> {
const logChannelId = process.env.TELEGRAM_LOG_CHANNEL_ID;
if (!logChannelId) return;
await sendMessage(logChannelId, text, 'HTML');
}