UNPKG

node-red-contrib-telegrambot

Version:
291 lines (253 loc) 13.1 kB
/** * Created by Karl-Heinz Wind **/ module.exports = function(RED) { "use strict"; var telegramBot = require('node-telegram-bot-api'); // -------------------------------------------------------------------------------------------- // The configuration node // holds the token // and establishes the connection to the telegram bot function TelegramBotNode(n) { RED.nodes.createNode(this,n); var self = this; this.botname = n.botname; if (this.credentials) { this.token = this.credentials.token; if (this.token) { this.token = this.token.trim(); if (!this.telegramBot) { this.telegramBot = new telegramBot(this.token, { polling: true }); } } } this.on('close', function (done) { // Workaround: the api does not support stopping the polling timer which is neccessary on redeploy. // see https://github.com/yagop/node-telegram-bot-api/issues/69 //self.telegramBot.stopPolling(); if (self.telegramBot._polling) { self.telegramBot._polling.abort = true; self.telegramBot._polling.lastRequest.cancel('Polling stopped'); } done(); }); } RED.nodes.registerType("telegram bot", TelegramBotNode, { credentials: { token: { type: "text" } } }); // -------------------------------------------------------------------------------------------- // The input node receives messages from the chat. // the message details are stored in the playload // chatId // type // content // depending on type caption and date is part of the output, too. // The original message is stored next to payload. // // message : content string // photo : content file_id of first image in array // audio : content file_id // docuemnt: content file_id of document // sticker : content file_id // video : content file_id // voice : content file_id // location: content is object with latitude and longitude // contact : content is full contact object function TelegramInNode(config) { RED.nodes.createNode(this, config); var node = this; this.bot = config.bot; this.config = RED.nodes.getNode(this.bot); if (this.config) { this.status({ fill: "red", shape: "ring", text: "disconnected" }); node.telegramBot = this.config.telegramBot; if (node.telegramBot) { this.status({ fill: "green", shape: "ring", text: "connected" }); node.telegramBot.on('message', function (botMsg) { var messageDetails; if (botMsg.text) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'message', content: botMsg.text }; } else if (botMsg.photo) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'photo', content: botMsg.photo[0].file_id, caption : botMsg.caption, date : botMsg.date }; } else if (botMsg.audio) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'audio', content: botMsg.audio.file_id, caption : botMsg.caption, date : botMsg.date }; } else if (botMsg.document) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'document', content: botMsg.document.file_id, caption : botMsg.caption, date : botMsg.date }; } else if (botMsg.sticker) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'sticker', content: botMsg.sticker.file_id }; } else if (botMsg.video) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'video', content: botMsg.video.file_id, caption : botMsg.caption, date : botMsg.date }; } else if (botMsg.voice) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'voice', content: botMsg.voice.file_id, caption : botMsg.caption, date : botMsg.date }; } else if (botMsg.location) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'location', content: botMsg.location }; } else if (botMsg.contact) { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'contact', content: botMsg.contact }; } else { // unknown type --> no output } if (messageDetails) { var msg = { payload: messageDetails, originalMessage : botMsg }; node.send(msg); } }); } this.status({ fill: "green", shape: "ring", text: "connected" }); } else { node.warn("TelegramInNode: no config."); } } RED.nodes.registerType("telegram receiver", TelegramInNode); // -------------------------------------------------------------------------------------------- // The input node receives a command from the chat. // The message details are stored in the playload // chatId // type // content // depending on type caption and date is part of the output, too. // The original message is stored next to payload. // // message : content string function TelegramCommandNode(config) { RED.nodes.createNode(this, config); var node = this; var command = config.command; this.bot = config.bot; this.config = RED.nodes.getNode(this.bot); if (this.config) { this.status({ fill: "red", shape: "ring", text: "disconnected" }); node.telegramBot = this.config.telegramBot; if (node.telegramBot) { this.status({ fill: "green", shape: "ring", text: "connected" }); node.telegramBot.on('message', function (botMsg) { var msg; var messageDetails; if (botMsg.text) { var message = botMsg.text; if (message.startsWith(command)) { var remainingText = message.replace(command, ""); messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'message', content: remainingText }; msg = { payload: messageDetails, originalMessage : botMsg }; node.send([msg, null]); } else { messageDetails = { chatId : botMsg.chat.id, messageId : botMsg.message_id, type : 'message', content: botMsg.text }; msg = { payload: messageDetails, originalMessage : botMsg }; node.send([null, msg]); } } else { // unknown type --> no output } }); } this.status({ fill: "green", shape: "ring", text: "connected" }); } else { node.warn("TelegramCommandNode: no config."); } } RED.nodes.registerType("telegram command", TelegramCommandNode); // -------------------------------------------------------------------------------------------- // The output node sends to the chat // The payload needs three fields // chatId : string destination chat // type : string type of message to send // content : message content // The type is a string can be any of the following: // message content is String // photo content is String|stream.Stream|Buffer // audio content is String|stream.Stream|Buffer // document content is String|stream.Stream|Buffer // sticker content is String|stream.Stream|Buffer // video content is String|stream.Stream|Buffer // voice content is String|stream.Stream|Buffer // location content is an object that contains latitude and logitude // contact content is full contact object function TelegramOutNode(config) { RED.nodes.createNode(this, config); var node = this; this.bot = config.bot; this.config = RED.nodes.getNode(this.bot); if (this.config) { this.status({ fill: "red", shape: "ring", text: "disconnected" }); node.telegramBot = this.config.telegramBot; if (node.telegramBot) { this.status({ fill: "green", shape: "ring", text: "connected" }); } } else { node.warn("TelegramInNode: no config."); } this.on('input', function (msg) { if (msg.payload) { if (msg.payload.content) { if (msg.payload.chatId) { if (msg.payload.type) { var chatId = msg.payload.chatId; var type = msg.payload.type; switch (type) { case 'message': var chunkSize = 4000; var message = msg.payload.content; var done = false; do { var messageToSend; if (message.length > chunkSize) { messageToSend = message.substr(0, chunkSize); message = message.substr(chunkSize); } else { messageToSend = message; done = true; } node.telegramBot.sendMessage(chatId, messageToSend, msg.payload.options); } while (!done) break; case 'photo': node.telegramBot.sendPhoto(chatId, msg.payload.content, msg.payload.options); break; case 'audio': node.telegramBot.sendAudio(chatId, msg.payload.content, msg.payload.options); break; case 'document': node.telegramBot.sendDocument(chatId, msg.payload.content, msg.payload.options); break; case 'sticker': node.telegramBot.sendSticker(chatId, msg.payload.content, msg.payload.options); break; case 'video': node.telegramBot.sendVideo(chatId, msg.payload.content, msg.payload.options); break; case 'voice': node.telegramBot.sendVoice(chatId, msg.payload.content, msg.payload.options); break; case 'location': node.telegramBot.sendLocation(chatId, msg.payload.content.latitude, msg.payload.content.longitude, msg.payload.options); break; default: // unknown type nothing to send. } } else { node.warn("msg.payload.type is empty"); } } else { node.warn("msg.payload.chatId is empty"); } } else { node.warn("msg.payload.content is empty"); } } else { node.warn("msg.payload is empty"); } }); } RED.nodes.registerType("telegram sender", TelegramOutNode); }