vvlad1973-telegram-framework
Version:
Current version: *7.9.5*
278 lines (214 loc) • 8.6 kB
JavaScript
;
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);
}