diff --git a/README.md b/README.md index d46b998..2bec2d1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,33 @@ # Telegram Bot that saves photos -Run: + +## Things you will need to do to run it + + - Get a telegram bot token from the botFather + - Just talk to [BotFather](https://telegram.me/botfather) and follow a few simple steps. Once you've created a bot and received your authorization token, copt and paste it into the config file. (botId) + - Make sure you have NodeJS and npm installed + - Install dependencies. + - ``` $ npm install``` + +All done :) + +## Configuration + +This bot can be configured via the config.js file. +Keep the structure of this file as is, and change the values to your needs. + +## Running the bot + +I would suggest to use [pm2](http://pm2.keymetrics.io) to manage this process. but its your call... + +Production Run: ``` $ node index.js ``` -to debug a single message and exit (For debug): +Debug Run: ``` $ node index.js --printMessage ``` +> This will print out the firs message the bot receives and will exit.
+So you can see user ID and other data attached to the message. diff --git a/botEngine.js b/botEngine.js index d8d3e16..bb431a8 100644 --- a/botEngine.js +++ b/botEngine.js @@ -1,16 +1,57 @@ +// Node imports const fs = require('fs'); const path = require('path'); +// Telegram Module const TelegramBot = require('node-telegram-bot-api'); +// Congifuration const config = require('./config'); -let admin_chatId = null; +let admin_chatId; let authorizedUsers; let telegram; const SLIDESHOW_LOCATION = config.slideShowFolderPath; -// Functions +/** + * Runs the bot. + * @param {Array} args CLI arguments + * @return {void} + */ +let runBot = (args) => { + loadDB(); + telegram = new TelegramBot(config.botId, { + polling: true + }); + telegram.on('message', (msg) => { + const chatId = msg.chat.id; + if (args.indexOf('--printMessage') > 0) { + console.log(JSON.stringify(msg, null, 2)); + process.exit(0); + } + if (userAllowd(msg)) { + handleMessage(msg); + } else { + let message = config.messages.sendieResponse.unauthorizedUser; + message = message.replace('{username}', msg.from.username); + message = message.replace('{messageObj}', JSON.stringify(msg, null, 2)); + telegram.sendMessage(chatId, message); + message = config.messages.adminNotifications.unauthorizedUser; + message = message.replace('{username}', msg.from.username); + message = message.replace('{messageObj}', JSON.stringify(msg, null, 2)); + console.warn(message); + notifyAdmin(message); + } + }); + console.log('Telegram bot is alive and listening!'); +} + +/** + * Save a photo to config.slideShowFolderPath + * @param {string} fileId fileId (received from telegram) + * @param {Function} callback post save function - args: {Error} error, {string} filePath + * @return {void} + */ function storeFile(fileId, callback) { telegram.downloadFile(fileId, SLIDESHOW_LOCATION) .then((filePath) => { @@ -43,6 +84,11 @@ let storeFileCallback = (err, filePath, chatId, photoId) => { } }; +/** + * This function is called on every message from an authorized user. + * @param {JSON} msg telegram message object + * @return {void} + */ let handleMessage = (msg) => { const chatId = msg.chat.id; if (msg.photo || (msg.document && msg.document.mime_type.indexOf('image/') === 0)) { // Handle Images @@ -65,6 +111,11 @@ let handleMessage = (msg) => { } }; +/** + * Check if a user is authorized to interact with this bot + * @param {JSON} msg telegram message object + * @return {boolean} true/false + */ let userAllowd = (msg) => { if (msg.from.id === config.admin.id) { admin_chatId = msg.chat.id; @@ -75,6 +126,12 @@ let userAllowd = (msg) => { return false; }; +/** + * Sends a message to admin. Only if config.admin.notifyActivity is true + * @param {string} msg message to send + * @param {string} photo_id the photo to send to admin incase config.notifyActivity.sendPhoto is true + * @return {void} + */ let notifyAdmin = (msg, photo_id) => { if (admin_chatId != null && config.admin.notifyActivity) { telegram.sendMessage(admin_chatId, msg); @@ -82,6 +139,13 @@ let notifyAdmin = (msg, photo_id) => { } }; +/** + * Will add/remove a user from authorized users list. (Saved in a file) + * If a user is not in the list, it will add him. Else remove him. + * Will notify admin if wanted (config.admin.notifyActivity) and send the initiating user on fail/success + * @param {JSON} contact Telegram contact object. The user to add/remove + * @param {JSON} from Telegram user object. Who wanted to add/remove the contact + */ let addRemoveUser = (contact, from) => { if (!config.permissions.allowAddingUsers) { // Ignore... @@ -125,6 +189,11 @@ let addRemoveUser = (contact, from) => { } } +/** + * Load authorized users list from disk (Reading a JSON file). If not exists (Usually on first run), will create the file. + * Incase the file is not in valid JSON format. will kill process with err code 1. + * @return {void} + */ let loadDB = () => { let dbLocation = config.DBLocation; if (dbLocation[dbLocation.length - 1] != '/') dbLocation += '/users.json'; @@ -149,6 +218,10 @@ let loadDB = () => { } } +/** + * Saves the authorized users list to disk. (config.DBLocation) + * @return {boolean} true=success, false=fail + */ let saveToDB = () => { let dbLocation = config.DBLocation; if (dbLocation[dbLocation.length - 1] != '/') dbLocation += '/users.json'; @@ -162,38 +235,10 @@ let saveToDB = () => { } } -let runBot = (args) => { - /****** Run script ******/ - loadDB(); - - telegram = new TelegramBot(config.botId, { - polling: true - }); - telegram.on('message', (msg) => { - const chatId = msg.chat.id; - if (args.indexOf('--printMessage') > 0) { - console.log(JSON.stringify(msg, null, 2)); - process.exit(0); - } - if (userAllowd(msg)) { - handleMessage(msg); - } else { - let message = config.messages.sendieResponse.unauthorizedUser; - message = message.replace('{username}', msg.from.username); - message = message.replace('{messageObj}', JSON.stringify(msg, null, 2)); - telegram.sendMessage(chatId, message); - message = config.messages.adminNotifications.unauthorizedUser; - message = message.replace('{username}', msg.from.username); - message = message.replace('{messageObj}', JSON.stringify(msg, null, 2)); - console.warn(message); - notifyAdmin(message); - } - - }); -} - - - +/** + * Bot engine exported interface + * @type {Object} + */ module.exports = { runBot: runBot } diff --git a/index.js b/index.js index 120fcc2..22cb264 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,10 @@ -const botEngine = require('./botEngine'); +/** + * A Telegram bot thats saves your photos locally + * + */ +// Import bot engine module +const botEngine = require('./botEngine'); +console.log('Initializing bot...'); +//Run the bot. botEngine.runBot(process.argv);