node-red-contrib-chatbot
Version:
REDBot a Chat bot for a full featured chat bot for Telegram, Facebook Messenger and Slack. Almost no coding skills required
1,111 lines (1,028 loc) • 34.8 kB
JavaScript
const _ = require('underscore');
const validators = require('../helpers/validators');
const moment = require('moment');
const { ChatExpress, ChatLog } = require('chat-platform');
const TelegramBot = require('node-telegram-bot-api');
const request = require('request').defaults({ encoding: null });
const utils = require('../../lib/helpers/utils');
const helpers = require('../../lib/helpers/regexps');
const {
getMessageId,
when,
params
} = require('../../lib/helpers/utils');
// set the messageId in a returning payload
const setMessageId = (message, messageId) => ({
...message,
payload: {
...message.payload,
messageId
}
});
const sendAnimation = function(chatId, animation, options = {}, fileOptions = {}) {
const opts = {
qs: options
};
opts.qs.chat_id = chatId;
try {
const sendData = this._formatSendData('animation', animation, fileOptions);
opts.formData = sendData[0];
opts.qs.animation = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
return this._request('sendAnimation', opts);
};
// convert to the weird dialect of Telegram
const convertMarkdown = content => content
.replace(/\*\*(.*?)\*\*/g, '--$1--') // tmp replacement
.replace(/\*(.*?)\*/g, '_$1_')
.replace(/\-\-(.*?)\-\-/g, '*$1*');
const MESSAGE_MAX_SIZE = 4096;
const Telegram = new ChatExpress({
color: '#336699',
inboundMessageEvent: 'message',
transport: 'telegram',
transportDescription: 'Telegram',
relaxChatId: true, // sometimes chatId is not necessary (for example inline_query_id)
chatIdKey: function(payload) {
return payload.chat != null ? payload.chat.id : null;
},
userIdKey: function(payload) {
return payload.from.id;
},
messageIdKey: function(payload) {
return payload.message_id;
},
tsKey: function(payload) {
return moment.unix(payload.date).toISOString();
},
type: function() {
// todo remove this
},
language: function(payload) {
return payload != null && payload.from != null ? payload.from.language_code : null;
},
onStop: function() {
var options = this.getOptions();
return new Promise(function(resolve) {
if (options.connector != null) {
if (options.connectMode === 'webHook') {
// cancel the web hook on stop
options.connector.deleteWebHook()
.then(function() {
options.connector = null;
resolve();
}, function() {
resolve();
});
} else if (options.connectMode === 'polling') {
// stop polling
options.connector.stopPolling()
.then(function() {
options.connector = null;
resolve();
}, function() {
resolve();
});
}
} else {
resolve();
}
});
},
onStart: function() {
var options = this.getOptions();
if (options.connectMode === 'webHook') {
options.connector = new TelegramBot(options.token);
options.connector.sendAnimation = sendAnimation.bind(options.connector);
return options.connector.setWebHook(options.webHook);
} else if (options.connectMode === 'polling') {
options.connector = new TelegramBot(options.token, {
polling: {
params: {
timeout: 10
},
interval: !isNaN(parseInt(options.polling, 10)) ? parseInt(options.polling, 10) : 1000
}
});
options.connector.sendAnimation = sendAnimation.bind(options.connector);
return true;
} else {
throw 'Unkown connection mode';
}
},
routes: {
'/redbot/telegram/test': function(req, res) {
res.send('ok');
},
'/redbot/telegram': function(req, res) {
const chatServer = this;
const json = req.body;
if (json.message != null) {
chatServer.receive(json.message);
} else if (json.edited_message != null) {
chatServer.receive(json.edited_message);
} else if (json.callback_query != null) {
this.callbackQuery(json.callback_query);
}
res.send({ status: 'ok' });
}
},
multiWebHook: true,
webHookScheme: function() {
const { connectMode, webHook } = this.getOptions();
// if polling return the base link, if not extract the subpath after /redbot/telegram/
if (connectMode === 'webHook') {
const match = (webHook || '').match(/\/redbot\/telegram\/(.*)$/);
return match != null ? match[1] : '';
}
return '';
},
events: {
inline_query: function(botMsg) {
botMsg.inlineQueryId = botMsg.id;
delete botMsg.id;
this.receive(botMsg);
},
callback_query: function(botMsg) {
this.callbackQuery(botMsg);
},
pre_checkout_query: function(botMsg) {
var chatServer = this;
var options = this.getOptions();
var connector = options.connector;
// send confirmation
connector.answerPreCheckoutQuery(botMsg.id, true)
.then(
function() {
},
function() {
chatServer.error('Error on .answerPreCheckoutQuery(), checkout: ' + botMsg.id);
});
},
shipping_query: function(botMsg) {
var chatServer = this;
// bounce the message into the flow
chatServer.receive({
from: botMsg.from,
shipping_query_id: botMsg.id,
invoice_payload: botMsg.invoice_payload,
shipping_address: botMsg.shipping_address
});
}
}
});
// detect new user in group
Telegram.in(function(message) {
var botMsg = message.originalMessage;
return new Promise(function(resolve) {
if (_.isArray(botMsg.new_chat_members) && !_.isEmpty(botMsg.new_chat_members)) {
message.payload.newUsers = botMsg.new_chat_members;
message.payload.type = 'event';
message.payload.eventType = 'new-user';
resolve(message);
} else {
resolve(message);
}
});
});
// detect inline query
Telegram.in(function(message) {
return new Promise(function(resolve) {
if (message.originalMessage.query != null) {
message.payload.content = message.originalMessage.query;
message.payload.type = 'inline-query';
resolve(message);
} else {
resolve(message);
}
});
});
Telegram.in(function(message) {
var chatServer = this;
return new Promise(function(resolve, reject) {
var connector = message.client();
if (message.originalMessage.sticker != null) {
connector.getFileLink(message.originalMessage.sticker.file_id)
.then(function(imageUrl) {
return chatServer.request({ url: imageUrl });
})
.then(
function(image) {
message.payload.type = 'photo';
message.payload.content = image;
resolve(message);
},
function(err) {
reject(err);
}
);
} else {
resolve(message);
}
});
});
Telegram.in(function(message) {
return new Promise(function(resolve) {
if (_.isString(message.originalMessage.text) && !_.isEmpty(message.originalMessage.text)) {
message.payload.content = message.originalMessage.text;
message.payload.type = 'message';
if (helpers.isCommand(message.originalMessage.text)) {
message.payload.arguments = message.originalMessage.text.split(' ').slice(1);
}
resolve(message);
} else {
resolve(message);
}
});
});
Telegram.in(function(message) {
var botMsg = message.originalMessage;
return new Promise(function(resolve) {
if (botMsg.location != null) {
message.payload.content = botMsg.location;
message.payload.type = 'location';
resolve(message);
} else {
resolve(message);
}
});
});
Telegram.in(function(message) {
var botMsg = message.originalMessage;
return new Promise(function(resolve) {
if (botMsg.contact != null) {
message.payload.content = botMsg.contact;
message.payload.type = 'contact';
resolve(message);
} else {
resolve(message);
}
});
});
Telegram.in(function(message) {
var botMsg = message.originalMessage;
return new Promise(function(resolve) {
if (botMsg.successful_payment != null) {
message.payload.content = botMsg.successful_payment;
message.payload.type = 'payment';
resolve(message);
} else {
resolve(message);
}
});
});
Telegram.in(function(message) {
var botMsg = message.originalMessage;
return new Promise(function(resolve) {
if (botMsg.shipping_query_id != null) {
message.payload.shippingQueryId = botMsg.shipping_query_id;
message.payload.payload = botMsg.payload;
message.payload.shippingAddress = botMsg.shipping_address;
message.payload.type = 'invoice-shipping';
resolve(message);
} else {
resolve(message);
}
});
});
Telegram.in(async function(message) {
const context = message.chat();
const options = this.getOptions();
const authorizedUsernames = (options.authorizedUsernames || '').split(',');
const userId = String(message.originalMessage.from.id);
const vars = {};
const { firstName, lastName, username } = await when(context.get('firstName', 'lastName', 'username')) || {};
// only change if not defined
if (_.isEmpty(firstName) && !_.isEmpty(message.originalMessage.from.first_name)) {
vars.firstName = message.originalMessage.from.first_name;
}
if (_.isEmpty(lastName) && !_.isEmpty(message.originalMessage.from.last_name)) {
vars.lastName = message.originalMessage.from.last_name;
}
if (_.isEmpty(username) && !_.isEmpty(message.originalMessage.from.username)) {
vars.username = message.originalMessage.from.username;
}
// set auth
vars.authorized = false;
if (_.isArray(authorizedUsernames) && !_.isEmpty(authorizedUsernames)) {
if (authorizedUsernames.includes(String(userId)) || authorizedUsernames.includes(username)) {
vars.authorized = true;
}
}
// store back
if (!_.isEmpty(vars)) {
await when(context.set(vars))
}
return message;
});
Telegram.in(async function(message) {
const options = this.getOptions();
const connector = options.connector;
const skipMediaFiles = options.skipMediaFiles === true;
const botMsg = message.originalMessage;
const chatServer = this;
let type = null;
let fileId = null;
let duration = null;
// download one of these binary types
if (botMsg.photo != null) {
type = 'photo';
fileId = _(botMsg.photo).last().file_id;
} else if (botMsg.video != null) {
type = 'video';
fileId = botMsg.video.file_id;
} else if (botMsg.voice != null) {
type = 'audio';
fileId = botMsg.voice.file_id;
duration = botMsg.voice.duration;
} else if (botMsg.document != null) {
type = 'document';
fileId = botMsg.document.file_id;
} else if (botMsg.video_note != null) {
type = 'video_note';
fileId = botMsg.video_note.file_id;
duration = botMsg.video_note.duration;
}
// if not one of these pass thru
if (type != null) {
// skip media files (for example for performance reason)
if (skipMediaFiles) {
// eslint-disable-next-line no-console
console.log(`Skipped download file id (${fileId})`);
return message;
}
message.payload.type = type;
try {
const path = await connector.getFileLink(fileId);
const buffer = await chatServer.downloadFile(path);
message.payload.content = buffer;
message.payload.caption = botMsg.caption;
message.payload.duration = duration;
return message;
} catch(e) {
throw 'Error downloading photo.' + e;
}
}
return message;
});
Telegram.out('photo', async function(message) {
const connector = this.getOptions().connector;
const param = params(message);
const result = await connector.sendPhoto(message.payload.chatId, message.payload.content, {
caption: message.payload.caption,
disable_notification: param('silent', false),
parse_mode: param('parseMode', null),
has_spoiler: param('hasSpoiler', false),
protect_content: param('protectContent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
});
return setMessageId(message, result.message_id);
});
Telegram.out('video', async function(message) {
const connector = this.getOptions().connector;
const param = params(message);
const result = await connector.sendVideo(
message.payload.chatId,
message.payload.content,
{
caption: message.payload.caption,
disable_notification: param('silent', false),
parse_mode: param('parseMode', null),
has_spoiler: param('hasSpoiler', false),
protect_content: param('protectContent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null,
},
{
contentType: message.payload.mimeType,
filename: message.payload.filename
}
);
return setMessageId(message, result.message_id);
});
Telegram.out('document', async function(message) {
const connector = this.getOptions().connector;
const param = params(message);
const result = await connector.sendDocument(
message.payload.chatId,
message.payload.content,
{
caption: message.payload.caption,
parse_mode: param('parseMode', null),
disable_notification: param('silent', false),
protect_content: param('protectContent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
},
{
// remove extension, telegram will put on the end
filename: !_.isEmpty(message.payload.filename) ? message.payload.filename.replace(/\.[^.]+$/, '') : null
}
);
return setMessageId(message, result.message_id);
});
Telegram.out('audio', async function(message) {
const connector = this.getOptions().connector;
const param = params(message);
const result = await connector.sendVoice(
message.payload.chatId,
message.payload.content,
{
caption: message.payload.caption,
parse_mode: param('parseMode', null),
duration: message.payload.duration,
disable_notification: param('silent', false),
protect_content: param('protectContent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
},
{
filename: message.payload.filename
}
);
return setMessageId(message, result.message_id);
});
Telegram.out('telegram-reset-buttons', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
await connector
.sendMessage(
message.payload.chatId,
message.payload.content,
{
reply_markup: { remove_keyboard: true },
parse_mode: param('parseMode', null),
disable_web_page_preview: param('disableWebPagePreview', false),
disable_notification: param('silent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
}
);
return message;
});
Telegram.out('telegram-buttons', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
const chatServer = this;
if (_.isEmpty(message.payload.content)) {
throw 'Buttons node needs a non-empty message';
}
const keyboard = [[]];
_(message.payload.buttons).each(button => {
let json = null;
switch(button.type) {
case 'keyboardButton':
json = button.label;
break;
case 'newline':
keyboard.push([]);
break;
default:
chatServer.warn('Telegram is not able to handle this button type "' + button.type + '"');
}
if (json != null) {
// add the button to the last row, if any
keyboard[keyboard.length - 1].push(json);
}
});
const buttons = {
reply_markup: JSON.stringify({
keyboard: keyboard,
resize_keyboard: true,
one_time_keyboard: _.isBoolean(message.payload.oneTimeKeyboard) ? message.payload.oneTimeKeyboard : false,
is_persistent: _.isBoolean(message.payload.isPersistent) ? message.payload.isPersistent : false,
input_field_placeholder: !_.isEmpty(message.payload.placeholder) ? message.payload.placeholder : undefined
}),
parse_mode: param('parseMode', null),
disable_web_page_preview: param('disableWebPagePreview', false),
disable_notification: param('silent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
};
// finally send
const result = await connector.sendMessage(
message.payload.chatId,
message.payload.content,
buttons
);
return setMessageId(message, result.message_id);
});
Telegram.out('request', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
let keyboard = null;
if (message.payload.requestType === 'location') {
keyboard = [
[{
text: !_.isEmpty(message.payload.label) ? message.payload.label : 'Send your position',
request_location: true
}]
];
} else if (message.payload.requestType === 'phone-number') {
keyboard = [
[{
text: !_.isEmpty(message.payload.label) ? message.payload.label : 'Send your phone number',
request_contact: true
}]
];
}
if (keyboard != null) {
const result = await connector
.sendMessage(message.payload.chatId, message.payload.content, {
reply_markup: JSON.stringify({
keyboard: keyboard,
'resize_keyboard': true,
'one_time_keyboard': true
}),
parse_mode: param('parseMode', null),
disable_web_page_preview: param('disableWebPagePreview', false),
disable_notification: param('silent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
});
return setMessageId(message, result.message_id);
} else {
throw 'Request type not supported';
}
});
Telegram.out('inline-buttons', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const chatServer = this;
const context = message.chat();
const param = params(message);
const modifyMessageId = param('modifyMessageId') || message.originalMessage.modifyMessageId; // for retro compatibility
// create inline buttons, docs for this is https://core.telegram.org/bots/api#inlinekeyboardmarkup
// create the first array of array
const inlineKeyboard = [[]];
const chatId = message.payload.chatId;
// cycle through buttons, add new line at the end if flag
message.payload.buttons.forEach(button => {
let json = null;
switch(button.type) {
case 'url':
json = {
text: button.label,
url: button.url
};
break;
case 'postback':
json = {
text: button.label,
callback_data: !_.isEmpty(button.value) ? button.value : button.label
};
break;
case 'newline':
inlineKeyboard.push([]);
break;
default:
chatServer.warn('Telegram is not able to handle this button type "' + button.type + '"');
}
if (json != null) {
// add the button to the last row, if any
inlineKeyboard[inlineKeyboard.length - 1].push(json);
}
});
// store the last buttons, this will be handled by the receiver
if (connector.lastInlineButtons == null) {
connector.lastInlineButtons = {};
}
connector.lastInlineButtons[chatId] = message.payload.buttons;
// send buttons or edit
let result;
if (modifyMessageId != null) {
// change content of message
await connector.editMessageText(message.payload.content, {
chat_id: chatId,
message_id: modifyMessageId
});
// change buttons of message
result = await connector.editMessageReplyMarkup(JSON.stringify({
inline_keyboard: inlineKeyboard
}), {
chat_id: chatId,
message_id: modifyMessageId
});
} else {
// finally send
result = await connector.sendMessage(chatId, message.payload.content, {
reply_markup: JSON.stringify({
inline_keyboard: inlineKeyboard
}),
parse_mode: param('parseMode', null),
disable_web_page_preview: param('disableWebPagePreview', false),
disable_notification: param('silent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
});
}
// store message id
await when(context.set({
messageId: result.message_id,
outboundMessageId: result.message_id
}));
return setMessageId(message, result.message_id);
});
Telegram.out(async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
const deleteMessageId = param('deleteMessageId');
if (deleteMessageId) {
connector.deleteMessage(
message.originalMessage.chatId,
deleteMessageId
);
message.payload = {};
}
return message;
});
Telegram.out('message', async function(message) {
const options = this.getOptions();
const connector = options.connector ;
const context = message.chat();
const param = params(message);
const modifyMessageId = param('modifyMessageId') || message.originalMessage.modifyMessageId; // for retro compatibility
let content = message.payload.content;
// convert the different markdown dialect of Telegram
if (param('parseMode', null) === 'Markdown' && !_.isEmpty(content)) {
content = convertMarkdown(content);
}
let result = null;
if (modifyMessageId != null) {
result = await connector.editMessageText(content, {
chat_id: message.payload.chatId,
message_id: modifyMessageId,
disable_notification: param('silent', false)
});
} else {
const chunks = utils.split(content, MESSAGE_MAX_SIZE);
for(let idx = 0; idx < chunks.length; idx++) {
// simulate spoiler with entities
let entities = undefined;
if (param('hasSpoiler', false)) {
entities = JSON.stringify([
{
offset: 0,
length: chunks[idx].length,
type: 'spoiler'
}
]);
}
result = await connector.sendMessage(message.payload.chatId, chunks[idx], {
parse_mode: param('parseMode', null),
disable_web_page_preview: param('disableWebPagePreview', false),
disable_notification: param('silent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null,
protect_content: param('protectContent', false),
entities
});
}
}
// store message id
await when(context.set({
messageId: result.message_id,
outboundMessageId: result.message_id
}));
return setMessageId(message, result.message_id);
});
Telegram.out('action', async function(message) {
const options = this.getOptions();
const connector = options.connector;
await connector.sendChatAction(message.payload.chatId, message.payload.waitingType != null ? message.payload.waitingType : 'typing')
return message;
});
Telegram.out('location', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
const result = await connector.sendLocation(
message.payload.chatId,
message.payload.content.latitude,
message.payload.content.longitude,
{
...message.payload.options,
protect_content: param('protectContent', false),
}
);
return setMessageId(message, result.message_id);
});
Telegram.out('inline-query-answer', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const inlineQueryId = message.originalMessage.inlineQueryId;
// do some checks
if (_.isEmpty(inlineQueryId)) {
throw 'Empty inlineQueryId';
}
if (!_.isArray(message.payload.content)) {
throw 'Invalid inline query answer';
}
const inlineOptions = {};
if (validators.integer(message.payload.caching)) {
inlineOptions.cache_time = message.payload.caching;
}
if (validators.boolean(message.payload.personal)) {
inlineOptions.is_personal = message.payload.personal;
}
await connector.answerInlineQuery(inlineQueryId, message.payload.content, inlineOptions);
return message;
});
Telegram.out('invoice', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
if (_.isEmpty(options.providerToken)) {
throw 'Missing providerToken in Telegram chatbot configuration, needed to send an invoice.';
}
const invoiceOptions = {
need_name: message.payload.needName,
need_phone_number: message.payload.needPhoneNumber,
need_email: message.payload.needEmail,
need_shipping_address: message.payload.needShippingAddress,
is_flexible: message.payload.isFlexible,
protect_content: param('protectContent', false),
};
const prices = _(message.payload.prices).map(price => {
return {
label: price.label,
amount: Math.floor(parseFloat(price.amount) * 100)
}
});
if (!_.isEmpty(message.payload.photoUrl)) {
invoiceOptions.photo_url = message.payload.photoUrl;
invoiceOptions.photo_width = message.payload.photoWidth;
invoiceOptions.photo_height = message.payload.photoHeight;
}
const result = await connector.sendInvoice(
message.payload.chatId,
message.payload.title,
message.payload.description,
message.payload.payload,
options.providerToken,
message.payload.startParameter,
message.payload.currency,
prices,
invoiceOptions
);
return setMessageId(message, result.message_id);
});
Telegram.out('invoice-shipping', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const shippingOptions = _(message.payload.shippingOptions).map(function(shippingOption) {
return {
id: shippingOption.id,
title: shippingOption.label,
prices: [{ label: shippingOption.id, amount: Math.floor(shippingOption.amount * 100) }]
};
});
const canShip = !_.isEmpty(shippingOptions);
await connector.answerShippingQuery(message.payload.shippingQueryId, canShip, { shipping_options: shippingOptions });
return message;
});
Telegram.out('sticker', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
const result = await connector.sendSticker(
message.payload.chatId,
message.payload.content,
{
disable_notification: param('silent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
}
);
return setMessageId(message, result.message_id);
});
Telegram.out('animation', async function(message) {
const options = this.getOptions();
const connector = options.connector;
const param = params(message);
const result = await connector.sendAnimation(
message.payload.chatId,
message.payload.content,
{
disable_notification: param('silent', false),
reply_to_message_id: param('replyToMessage', false) ? getMessageId(message) : null
}
);
return setMessageId(message, result.message_id);
});
// log messages, these should be the last
Telegram.out(function(message) {
var options = this.getOptions();
var logfile = options.logfile;
var chatContext = message.chat();
if (!_.isEmpty(logfile)) {
return when(chatContext.all())
.then(function(variables) {
var chatLog = new ChatLog(variables);
return chatLog.log(message, logfile);
});
}
return message;
});
Telegram.in('*', function(message) {
var options = this.getOptions();
var logfile = options.logfile;
var chatContext = message.chat();
if (!_.isEmpty(logfile)) {
return when(chatContext.all())
.then(function(variables) {
var chatLog = new ChatLog(variables);
return chatLog.log(message, logfile);
});
}
return message;
});
Telegram.mixin({
downloadFile: function (url, token) {
return new Promise(function (resolve, reject) {
var options = {
url: url,
headers: {
'Authorization': 'Bearer ' + token
}
};
request(options, function (error, response, body) {
if (error) {
reject(error);
} else {
resolve(body);
}
});
});
},
callbackQuery: function(botMsg) {
var chatServer = this;
var options = this.getOptions();
var connector = options.connector;
var chatId = botMsg.message.chat.id;
var alert = false;
var answer = null;
if (connector.lastInlineButtons != null && connector.lastInlineButtons[chatId] != null) {
// find the button with the right value, takes the answer and alert if any
var button = _(connector.lastInlineButtons[chatId]).findWhere({value: botMsg.data});
if (button != null) {
answer = button.answer;
alert = button.alert;
}
// do not remove from hash, the user could click again
}
// copy the "from" of the message containing user information, not chatbot detail
botMsg.message.from = botMsg.from;
// send answer back to client
connector.answerCallbackQuery(botMsg.id, { text: answer, show_alert: alert })
.then(function() {
// send through the message as usual
botMsg.message.text = botMsg.data;
chatServer.receive(botMsg.message);
});
}
});
const videoExtensions = ['.mp4', '.gif'];
const audioExtensions = ['.mp3'];
const documentExtensions = ['.pdf', '.gif', '.zip'];
const photoExtensions = ['.jpg', '.jpeg', '.png', '.gif'];
Telegram.registerMessageType('action', 'Action', 'Send an action message (like typing, ...)');
Telegram.registerMessageType('telegram-buttons', 'Buttons', 'Open keyboard buttons in the client');
Telegram.registerMessageType('command', 'Command', 'Detect command-like messages');
Telegram.registerMessageType('contact', 'Contact', 'Send a contact');
Telegram.registerMessageType('inline-buttons', 'Inline buttons', 'Send a message with inline buttons');
Telegram.registerMessageType('inline-query', 'Inline Query', 'Receives inline queries');
Telegram.registerMessageType('invoice', 'Invoice', 'Send a payment invoice');
Telegram.registerMessageType('invoice-shipping', 'Invoice Shipping Query', 'Define an invoice shipping option');
Telegram.registerMessageType('location', 'Location', 'Send a map location message');
Telegram.registerMessageType('message', 'Message', 'Send a plain text message');
Telegram.registerMessageType('payment', 'Payment', 'Payment received message');
Telegram.registerMessageType('request', 'Request', 'Trigger a request of location or contact');
Telegram.registerMessageType('sticker', 'Sticker', 'Send a sticker');
Telegram.registerMessageType(
'animation',
'Animation',
'Send an animation',
file => {
if (!_.isEmpty(file.extension) && !videoExtensions.includes(file.extension.toLowerCase())) {
return `Unsupported file format for video node "${file.filename}", allowed formats: ${videoExtensions.join(', ')}`;
}
if (file.size > (50 * 1024 * 1024)) {
return 'Video is too large, max 50 Mb';
}
return null;
}
);
Telegram.registerMessageType('event', 'Event', 'Event from platform');
Telegram.registerMessageType(
'video',
'Video',
'Send video message',
file => {
if (!_.isEmpty(file.extension) && !videoExtensions.includes(file.extension.toLowerCase())) {
return `Unsupported file format for video node "${file.filename}", allowed formats: ${videoExtensions.join(', ')}`;
}
if (file.size > (50 * 1024 * 1024)) {
return 'Video is too large, max 50 Mb';
}
return null;
}
);
Telegram.registerMessageType('video_note', 'Video Note', 'Video note (short video)');
Telegram.registerMessageType(
'document',
'Document',
'Send a document or generic file',
file => {
if (!_.isEmpty(file.extension) && !documentExtensions.includes(file.extension.toLowerCase())) {
return `Unsupported file format for document node "${file.filename}", allowed formats: ${documentExtensions.join(', ')}`;
}
return null;
}
);
Telegram.registerMessageType(
'audio',
'Audio',
'Send an audio message',
file => {
if (!_.isEmpty(file.extension) && !audioExtensions.includes(file.extension.toLowerCase())) {
return `Unsupported file format for audio node "${file.filename}", allowed formats: ${audioExtensions.join(', ')}`;
}
return null;
}
);
Telegram.registerMessageType(
'photo',
'Photo',
'Send a photo message',
file => {
if (!_.isEmpty(file.extension) && !photoExtensions.includes(file.extension.toLowerCase())) {
return `Unsupported file format for image node "${file.filename}", allowed formats: ${photoExtensions.join(', ')}`;
}
}
);
Telegram.registerParam(
'replyToMessage',
'boolean',
{ label: 'Reply to message', default: false }
);
Telegram.registerParam(
'hasSpoiler',
'boolean',
{ label: 'Cover the text, video or photo with spolier animation', default: false }
);
Telegram.registerParam(
'protectContent',
'boolean',
{ label: 'Protects the contents of the sent message from forwarding and saving', default: false }
);
Telegram.registerParam(
'silent',
'boolean',
{ label: 'Silent', default: false, description: 'Deliver the message silently' }
);
Telegram.registerParam(
'modifyMessageId',
'string',
{
label: 'Modify message',
description: 'The id of the sent message to be modified',
placeholder: 'Message Id',
suggestions: [
'{{outboundMessageId}}',
'{{inboundMessageId}}'
]
}
);
Telegram.registerParam(
'parseMode',
'select',
{
label: 'Parse Mode',
default: 'Markdown',
description: 'Parse message with HTML or Markdown',
placeholder: 'Parse mode',
options: [
{ value: '', label: 'Select parse mode'},
{ value: 'Markdown', label: 'Markdown'},
{ value: 'HTML', label: 'HTML' }
]
}
);
Telegram.registerParam(
'disableWebPagePreview',
'boolean',
{ label: 'Disable web page preview', description: 'Disables link previews for links in this message' }
);
Telegram.registerParam(
'deleteMessageId',
'string',
{
label: 'Delete Message',
description: 'Delete a message given the message id',
placeholder: 'Message Id',
suggestions: [
'{{outboundMessageId}}',
'{{inboundMessageId}}'
]
}
);
Telegram.registerEvent('new-user', 'New user');
module.exports = Telegram;