UNPKG

vvlad1973-telegram-framework

Version:
278 lines (214 loc) 8.6 kB
'use strict'; import FormData from 'form-data'; import fs from 'fs'; import { format as f } from 'util'; import got from 'got'; import { TelegramBotApiMethodsWithMedia, MediaProperties, StatusCodes, UserLinks, UpdateTypes, MessageTypes, } from '../classes/enums.js'; const COMMAND_PATTERN = /^[\\/]([^@\s]+)(@([\S]+))?( (.*))?$/; const COMMAND_PART_INDEX = 1; const PARAMS_PART_INDEX = 5; const BOT_NAME_PART_INDEX = 3; export function parseCommand(string) { let result; if (typeof string === 'string') { let parts = string.match(COMMAND_PATTERN); if ( Array.isArray(parts) && parts.length > Math.max( COMMAND_PART_INDEX, PARAMS_PART_INDEX, BOT_NAME_PART_INDEX ) ) { result = { command: parts[COMMAND_PART_INDEX], params: parts[PARAMS_PART_INDEX] ? parts[PARAMS_PART_INDEX] : '', botName: parts[BOT_NAME_PART_INDEX] ? parts[BOT_NAME_PART_INDEX] : '', } } } return result; } export function getMessageType(message) { let result; if (typeof message === 'object') { result = UpdateTypes.MESSAGE; if (message.text) result = MessageTypes.TEXT else if (message.photo) result = MessageTypes.PHOTO else if (message.video) result = MessageTypes.VIDEO else if (message.audio) result = MessageTypes.AUDIO else if (message.document) result = MessageTypes.DOCUMENT else if (message.animation) result = MessageTypes.ANIMATION else if (message.voice) result = MessageTypes.VOICE else if (message.video_note) result = MessageTypes.VIDEO_NOTE; else if (message.sticker) result = MessageTypes.STICKER; else if (message.location) result = MessageTypes.LOCATION; else if (message.poll) result = MessageTypes.POLL; else if (message.contact) result = MessageTypes.CONTACT; else if (message.dice) result = MessageTypes.DICE; else if (message.game) result = MessageTypes.GAME; else if (message.venue) result = MessageTypes.VENUE; else if (message.new_chat_members) result = MessageTypes.NEW_CHAT_MEMBER; else if (message.left_chat_members) result = MessageTypes.LEFT_CHAT_MEMBER; else if (message.invoice) result = MessageTypes.INVOICE; else if (message.pinned_message) result = MessageTypes.PINNED_MESSAGE; else if (message.successful_payment) result = MessageTypes.SUCCESSFUL_PAYMENT; else if (message.web_app_data) result = MessageTypes.WEB_APP_DATA; else if (message.migrate_chat) result = MessageTypes.MIGRATE_CHAT; else if (message.passport_data) result = MessageTypes.PASSPORT_DATA; } return result; } export function getFileId(object = {}) { let result; if (object.video) result = object.video.file_id; else if (object.video_note) result = object.video_note.file_id; else if (object.audio) result = object.audio.file_id; else if (object.document) result = object.document.file_id; else if (object.photo) result = object.photo[object.photo.length - 1].file_id; else if (object.voice) result = object.voice.file_id; else if (object.animation) result = object.animation.file_id; else if (object.sticker) result = object.sticker.file_id; return result; } export function createFormData(data) { let form = new FormData(); if (Object.values(TelegramBotApiMethodsWithMedia).includes(data.method)) { for (let item of Object.values(MediaProperties)) { if (item === MediaProperties.MEDIA && data[item]) for (let mediaItem of data[item]) { if (mediaItem.media?.file) { let fileName = mediaItem.media.file; mediaItem.media.blob = fs.readFileSync(fileName); } if (mediaItem.thumbnail?.file) { let fileName = mediaItem.thumbnail.file; mediaItem.thumbnail.blob = fs.readFileSync(fileName); } } else if (Object.keys(data).includes(item) && data[item].file) { let fileName = data[item].file; data[item].blob = fs.readFileSync(fileName); } } } for (let key of Object.keys(data)) { if (key === MediaProperties.MEDIA) { for (let [index, mediaItem] of data[key].entries()) { if (typeof mediaItem.media === 'object') { let mediaId = `media.${mediaItem.type}.${index}`; form.append(mediaId, mediaItem.media.blob, mediaItem.media.file); mediaItem.media = `attach://${mediaId}`; } if (typeof mediaItem.thumbnail === 'object') { let thumbnailId = `media.${mediaItem.type}.thumb.${index}`; form.append(thumbnailId, mediaItem.thumbnail.blob, mediaItem.thumbnail.file); mediaItem.thumbnail = `attach://${thumbnailId}`; } } form.append(key, JSON.stringify(data[key])); } else if (typeof data[key]?.file === 'string') { form.append(key, data[key].blob, data[key].file); } else if (data[key]) { if (typeof data[key] === 'object') { form.append(key, JSON.stringify(data[key])); } else { form.append(key, String(data[key])); } } } return form; } export function formatUserUrl(userId, username, templates = UserLinks) { let result; if (username) result = f(UserLinks.USERNAME, username); else if (userId) result = f(UserLinks.USER_ID, userId); return result; } export function getGotInstance() { const instance = got.extend({ handlers: [ (options, next) => { Error.captureStackTrace(options.context); return next(options); }, ], hooks: { beforeError: [ (error) => { error.source = error.options.context.stack.split('\n'); return error; }, ], }, }); return instance; } export function sendPostRequest(url, data, instance) { return new Promise(async (resolve, reject) => { let response; let result; try { response = await instance.post(url, data) if (data?.payload?.audio?.blob) data.payload.audio.blob = '<blob>'; if (data?.payload?.video?.blob) data.payload.video.blob = '<blob>'; if (data?.payload?.voice?.blob) data.payload.audio.voice = '<blob>'; if (data?.payload?.video_note?.blob) data.payload.video_note.blob = '<blob>'; if (data?.payload?.photo?.blob) data.payload.photo.blob = '<blob>'; if (data?.payload?.document?.blob) data.payload.document.blob = '<blob>'; if (data?.payload?.animation?.blob) data.payload.animation.blob = '<blob>'; if (data?.payload?.thumbnail?.blob) data.payload.thumbnail.blob = '<blob>'; result = { result: { ok: true, code: StatusCodes.OK, }, response: response.body, request: data, }; return resolve(result); } catch (error) { result = { message: error.response?.body?.description, result: { ok: false, code: error.response?.body?.error_code, description: error.response?.body?.description, }, response: error.response?.body, request: data, error: error, }; return reject(result); }; }); } /** * Replaces placeholders in the template string with corresponding values from strings or data * @param {string} template - The template string containing placeholders like {{KEY}} * @param {Object} strings - An object containing predefined string resources * @param {Object} data - An object containing variable values, including nested properties (async supported) * @returns {Promise<string>} - A promise resolving to the formatted string with replaced values */ export async function replaceTemplate(template, strings, data) { const matches = [...template.matchAll(/\{\{([\w.]+)\}\}/g)]; const replacements = await Promise.all(matches.map(async ([placeholder, path]) => { if (typeof strings[path] === 'string') { return { placeholder, value: strings[path] }; } const value = await path.split('.').reduce(async (obj, key) => { const resolvedObj = await obj; return resolvedObj && resolvedObj[key] !== undefined ? resolvedObj[key] : `{{${path}}}`; }, data); return { placeholder, value }; })); return replacements.reduce((str, { placeholder, value }) => str.replace(placeholder, value), template); }