diff --git a/.gitignore b/.gitignore index e2b5f34..aecc63d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - +users.json # Created by https://www.gitignore.io/api/node,linux ### Linux ### diff --git a/README.md b/README.md index b57f69a..d46b998 100644 --- a/README.md +++ b/README.md @@ -1 +1,11 @@ -# Slide Show Telegram Bot Ya'll +# Telegram Bot that saves photos + +Run: +``` +$ node index.js +``` + +to debug a single message and exit (For debug): +``` +$ node index.js --printMessage +``` diff --git a/config.js b/config.js index b3a8514..567d3f4 100644 --- a/config.js +++ b/config.js @@ -2,17 +2,41 @@ * Configuration */ module.exports = { - botId: "443965284:AAEKdvDxwxwbn4eOYJ6wt6lgR2J-hDAwSeA", - slideShowFolderPath: '/media/64C6A9C4724C63E5/slideshow/', //Ends with '/' + botId: '443965284:AAEKdvDxwxwbn4eOYJ6wt6lgR2J-hDAwSeA', // Bot token/Id - Get if from botFather + slideShowFolderPath: '/media/64C6A9C4724C63E5/slideshow', // Where to save files + DBLocation: '.', // Location of DB file. You need to have permissions to read/write in that location permissions: { allowAll: false, // allow any telegram user to add photos - usernames: [], // strings - userIds: [247153816], //numbers + allowAddingUsers: true, // accept contacts as authorized users? + allowNonAdminToAddUsers: false // allow non admin users to add contacts to authorized users }, admin: { - username: 'SagiDayan', notifyActivity: true, + sendPhotoOnSave: true, // send admin the photo that somone else have saved id: 73947511 + }, + messages: { + adminNotifications:{ + unauthorizedUser: 'Unauthorized user: {username}\nMessage:\n{messageObj}', // Plaseholers: {username}, {messageObj} + fileSuccessfullySaved: 'A photo was added.\n', // Plaseholers: {fileLocation} + failedToSaveFile: 'Psst...\nYou might want to know, that i have failed you. a fail was not saved.\nError:\n{error}', // Placeholders: {error} + userAdded: 'The user {username} added {username_add_rem} to the system', // Plaseholers: {username}, {username_add_rem} + userRemoved: 'The user {username} removed {username_add_rem} from the system' // Plaseholers: {username}, {username_add_rem} + }, + sendieResponse: { + unauthorizedUser: 'Hi {username}, \n Who the fuck are you?!\n I have notified my creator and he will hunt you down. I would suggest that you disconnect from the Internet', // Plaseholers: {username}, {messageObj} + fileSuccessfullySaved: 'Added to your slideshow. Saved at: {fileLocation}', // Plaseholers: {fileLocation} + failedToSaveFile: 'Woops,\nsome thing happend... Can\'t save your photo.\nTry Again later', // Placeholders: {error} + unableToDoThat: 'Hi {username},\nIm unable to understand you. I\'m able only to accept photos and contacts', // Placeholders: {username} + noPermissions: 'You have no permissions to do that...', + userAdded: 'Okay, {username} was added as a trusted user.', // Placeholders: {username} + userRemoved: 'Sure, I\'ll stop supporting {username}.' // Plaseholers: {username} + }, + userAdded: { + added: 'Hi {username_add_rem},\n{username} added you as a trusted user. this means that you can send me photos to add to the slide show! Try it now' // Plaseholers: {username}, {username_add_rem} + }, + userRemoved:{ + removed: 'Hi {username_add_rem},\n{username} removed you from my system... It\'s not you, it\'s me :(' // Plaseholers: {username}, {username_add_rem} + } } } - diff --git a/index.js b/index.js index 71a8c2a..3c8b52c 100644 --- a/index.js +++ b/index.js @@ -1,83 +1,188 @@ +const fs = require('fs'); +const path = require('path'); + const TelegramBot = require('node-telegram-bot-api'); const config = require('./config'); -// Be sure to replace YOUR_BOT_TOKEN with your actual bot token on this line. -let telegram = new TelegramBot(config.botId, { - polling: true -}); -let admin_chatId = config.admin.id; -const SLIDESHOW_LOCATION = config.slideShowFolderPath; // Ends with '/' -telegram.on('message', (msg) => { - const chatId = msg.chat.id; - if (userAllowd(msg)) { - handleMessage(msg); - } else { - telegram.sendMessage(chatId, 'Sorry ' + msg.from.username + ' My master says I can\'t talk to strangers...'); - console.log('Unauthorized user: ', msg.from.username, 'Message:'); - console.log(JSON.stringify(msg, null, 2)); - notifyAdmin('Unauthorized user: ' + msg.from.username + ' Message:\n' + JSON.stringify(msg, null, 2)); - } +let admin_chatId = null; +let authorizedUsers; -}); +const SLIDESHOW_LOCATION = config.slideShowFolderPath; -// Location Of HardDrive - /media/64C6A9C4724C63E5/slideshow +// Functions function storeFile(fileId, callback) { telegram.downloadFile(fileId, SLIDESHOW_LOCATION) .then((filePath) => { - callback(null, "YAYYY!!! file saved at: " + filePath); + let message = config.messages.sendieResponse.fileSuccessfullySaved; + message = message.replace('{fileLocation}', filePath); + callback(null, filePath); }) .catch((err) => { callback(err); }); } -let storeFileCallback = (err, message, chatId, photo_id) => { +let storeFileCallback = (err, filePath, chatId, photoId) => { + let response; if (err) { - telegram.sendMessage(chatId, 'Failed to store your photo! - ' + err); - if (admin_chatId !== chatId) notifyAdmin('Hi Master!!,\nA Failed attemt to save a file to slideshow', photo_id); + response = config.messages.sendieResponse.failedToSaveFile; + response = response.replace('{error}', err); + telegram.sendMessage(chatId, response); + response = config.messages.sendieResponse.failedToSaveFile; + response = response.replace('{error}', err); + if (admin_chatId !== chatId) notifyAdmin(response, photoId); } else { - telegram.sendMessage(chatId, message); - if (admin_chatId !== chatId) notifyAdmin('Hi Master!!,\nA photo was saved to your slideshow', photo_id); + response = config.messages.sendieResponse.fileSuccessfullySaved; + response = message.replace('{fileLocation}', filePath); + telegram.sendMessage(chatId, response); + response = config.messages.adminNotifications.fileSuccessfullySaved; + response = message.replace('{fileLocation}', filePath); + if (admin_chatId !== chatId) notifyAdmin(response, photoId); } }; let handleMessage = (msg) => { const chatId = msg.chat.id; - if (msg.photo || (msg.document && msg.document.mime_type.indexOf('image/') === 0)) { + if (msg.photo || (msg.document && msg.document.mime_type.indexOf('image/') === 0)) { // Handle Images if (msg.photo) { - storeFile(msg.photo[msg.photo.length - 1].file_id, (err, message) => { - storeFileCallback(err, message, chatId, msg.photo[msg.photo.length - 1].file_id); + storeFile(msg.photo[msg.photo.length - 1].file_id, (err, filePath) => { + storeFileCallback(err, filePath, chatId, msg.photo[msg.photo.length - 1].file_id); }); } else { // document - uncompressed photo - storeFile(msg.document.file_id, (err, message) => { - storeFileCallback(err, message, chatId, msg.document.file_id); + storeFile(msg.document.file_id, (err, filePath) => { + storeFileCallback(err, filePath, chatId, msg.document.file_id); }); } - } else if(msg.contact) { - notifyAdmin('User with ID of: ' + msg.contact.user_id + ' Should be added/removed!'); - } - else { + } else if (msg.contact) { // Handle Contact + addRemoveUser(msg.contact, msg.from); + } else { // send a message to the chat acknowledging receipt of their message - telegram.sendMessage(chatId, 'Hey dude... I can only help you save photos to your home slideshow.... other functions later :)'); + let message = config.messages.sendieResponse.unableToDoThat; + message = message.replace('{username}', msg.from.username); + telegram.sendMessage(chatId, message); } }; -let userAllowd = (msg)=>{ - if(msg.from.username === config.admin.username) { +let userAllowd = (msg) => { + if (msg.from.id === config.admin.id) { admin_chatId = msg.chat.id; return true; } - if(config.permissions.allowAll) return true; - if(config.permissions.usernames.indexOf(msg.from.username) >= 0) return true; - if(config.permissions.userIds.indexOf(msg.from.id) >= 0) return true; + if (config.permissions.allowAll) return true; + if (authorizedUsers.indexOf(msg.from.id) >= 0) return true; return false; }; let notifyAdmin = (msg, photo_id) => { - console.log(admin_chatId); - if (admin_chatId != null && config.admin.notifyActivity){ + if (admin_chatId != null && config.admin.notifyActivity) { telegram.sendMessage(admin_chatId, msg); - if(photo_id) telegram.sendPhoto(admin_chatId, photo_id); + if (photo_id && config.admin.sendPhotoOnSave) telegram.sendPhoto(admin_chatId, photo_id); } -}; \ No newline at end of file +}; + +let addRemoveUser = (contact, from) => { + if(!config.permissions.allowAddingUsers){ + // Ignore... + console.warn('Attempt to add/remove a user. this functionality is disabled.'); + return; + }else{ + if(from.id != config.admin.id && !config.permissions.allowNonAdminToAddUsers){ + telegram.sendMessage(from.id, config.messages.sendieResponse.noPermissions); + console.warn('Attempt to add/remove a user from an unpermited user. id: ',from.id); + return; + } + } + let toAdd = true; + if(authorizedUsers.indexOf(contact.user_id) < 0){ + // Add user + authorizedUsers.push(contact.user_id); + }else{ + // remove user + toAdd = false; + authorizedUsers.splice(authorizedUsers.indexOf(contact.user_id), 1); + } + if(saveToDB()){ + let message; + if(toAdd) message = config.messages.sendieResponse.userAdded; + else message = config.messages.sendieResponse.userRemoved; + message = message.replace('{username}', contact.first_name); + telegram.sendMessage(from.id, message); // response to the user that added the new one + if(toAdd) message = config.messages.userAdded.added; + else message = config.messages.userRemoved.removed; + message = message.replace('{username_add_rem}', contact.first_name); + message = message.replace('{username}', from.first_name); + telegram.sendMessage(contact.user_id, message); // Notify the new/old user + if(toAdd) message = config.messages.adminNotifications.userAdded; + else message = config.messages.adminNotifications.userRemoved; + message = message.replace('{username_add_rem}', contact.first_name); + message = message.replace('{username}', from.first_name); + if(from.id != config.admin.id) notifyAdmin(message); // notifyAdmin + }else{ + console.log('Failed to save DB!!!'); + } +} + +let loadDB = () => { + let dbLocation = config.DBLocation; + if (dbLocation[dbLocation.length - 1] != '/') dbLocation += '/users.json'; + else dbLocation += 'users.json'; + try{ + data = fs.readFileSync(path.resolve(dbLocation)); + try{ + authorizedUsers = JSON.parse(data.toString()); + console.log('DB loaded. AuthorizedUsers: ', authorizedUsers); + }catch(err){ + console.error('DB file is corrupted. Please delete the file', dbLocation, 'And rerun this service'); + process.exit(1); + } + }catch(err){ + authorizedUsers = []; + if(saveToDB()){ + console.log('DB was created. Everything is Okay.'); + }else{ + console.error('Unable to read from DB. Error:\n', err); + process.exit(1); + } + } +} + +let saveToDB = () => { + let dbLocation = config.DBLocation; + if (dbLocation[dbLocation.length - 1] != '/') dbLocation += '/users.json'; + else dbLocation += 'users.json'; + try{ + fs.writeFileSync(dbLocation, JSON.stringify(authorizedUsers)); + return true; + }catch(err){ + console.error('Failed to save to DB... ERROR:\n', err); + return false; + } +} +/****** Run script ******/ +loadDB(); + +let telegram = new TelegramBot(config.botId, { + polling: true +}); +telegram.on('message', (msg) => { + const chatId = msg.chat.id; + if(process.argv.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); + } + +});