diff --git a/README.md b/README.md index f37fb5d..9c9c9ac 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![shieldsIO](https://img.shields.io/david/UlisesGascon/Nodejs-hangouts-robot.svg) # Nodejs-hangouts-robot -Robot de chat para Google hangouts desarrollado con Node.js. Permite el uso de la Terminal/Consola, entre otras cosas +Robot de chat para Google hangouts desarrollado con Node.js. Permite el uso de la Terminal/Consola, Twitter, Alchemy Api... entre otras cosas... ![foto](img/Robotito_chat.png) @@ -29,7 +29,7 @@ botPassword: "PASS" ``` - Instalamos las dependencias y ejecutamos ``` -npm install && node robot +npm install && node index ``` - Preguntamos al robot *Quien soy?* en el chat y respondera con algo parecido a esto ``` @@ -45,13 +45,32 @@ usuarioAutorizado: "loremloremymaslorem1123@public.talk.google.com", ### Eventos Automáticos -- Las siguientes comunicaciones solo son relevantes a *config.usuarioAutorizado*, que será quien recibirá los mensajes. + +Las siguientes comunicaciones solo son relevantes a *config.usuarioAutorizado*, que será quien recibirá los mensajes. - Al arrancar la aplicación de Node... el robot saluda *Hola de nuevo, Jefe!* - Al cerrar la aplicación vía Ctrl+C... el robot se despide *Me piro! Ya no me quieres como antes...* - Al terminarse de manera natural la ejecucción... el robot se despide *Me piro! Vaciones por fín!* - Al tener un error inesperado y cerrarse... el robot se despide *Me piro! Cierre inesperado...* + +### Capturas + + + +![captura_1](img/captura_1.png) + + + +![captura_2](img/captura_2.png) + + + +### Manejo de servicios externos: + +Twitter y Alchemy pueden ser desactivados/activados desde *config.json* + + ### Preguntas y respuestas posibles: Nota: @@ -61,6 +80,10 @@ Si deseas cambiarlo, solo tienes que reescribir las cadenas de texto en las line **Por defecto...** - Si nuestro mensaje no cumple al menos uno de los siguientes casos, por defecto el robot nos respondera *No te entiendo... Explicate mejor, Humano!* +**Ayuda** +- Responde con un listado de ids (preguntas/respuestas) disponibles. +- Puedes ampliar los detalles (descripción, ejemplo, etc..) de un id en particular enviando `ayuda {id}` + **Hola (Expresión regular)** - Se dispara cuando nuestro mensaje empieza con la palabra Hola/hola. - Responde con *Hola Humano! Qué tal?* @@ -77,9 +100,40 @@ Si deseas cambiarlo, solo tienes que reescribir las cadenas de texto en las line **Quien soy?** - Responde con tu ID en formato *lorelipsum1234lorem12@public.talk.google.com* que es lo necesario para configurar el *usuarioAutorizado* en *config.js* -**Timestamp** +**hora** - Responde con la fecha y la hora en formato *MM/DD/YYYY, HH:MM:SS AM/PM* +**Tweet** +- Envia un tweet directamente. Puedes usar #hashtags y @menciones + +**System info** +- Información del sistema(Kernel, Uptime, etc...) y su uso (Disco duro, memoria, cpu, procesos...) + +**Echo** +- Devuelve el mensaje. + + +**Alchemy (Estatus)** +- Nos permite saber cuantas llamdas nos quedan a la API de Alchemy. + + +**Alchemy (Reconocimiento Facial)** +- Podemos enviar la URL de una foto y Alchemy relaizará un analisis. +- Nos devuelve la información sobre lso personajes famosos que aparecen o datos biometricos relevantes si no. + + +**Alchemy (Idioma)** +- Reconoce el idioma de un texto o url. +- Nos devuelve información relevante sobre el idioma, incluido un enlace a Wikipedia. + + +**Alchemy (sentimiento)** +- Análisis de sentimiento de un texto o url + + +**Alchemy (emociones)** +- Analisis por emociones de un texto o url + **Terminal** - Se dispara cuando nuestro mensaje empieza con la palabra Terminal/terminal. diff --git a/alchemy.js b/alchemy.js new file mode 100644 index 0000000..f51ab41 --- /dev/null +++ b/alchemy.js @@ -0,0 +1,194 @@ +var AlchemyAPI = require('alchemy-api'), + config = require('./config'), + alchemy = new AlchemyAPI(config.alchemyApi.key); + +/** + * Se verifica que el servicio este habilitado en cofig.js + * @param {function} botSend - Función que maneja los envios + * @param {string} from - Representa al usuario que lanzo la petición + */ + +function validarEstado(botSend, from, callback) { + if (config.hangouts.services.alchemy) { + if(callback && typeof callback === "function"){ + callback(); + } else { + console.log("[ERROR][Alchemy] El Callback no esta presente o no es una función."); + } + } else { + botSend(from, "Alchemy Api ha sido desactivada por el jefe"); + } +} + +/** + * Función que envía al solicitante el estado del API (errores, estado real) + * @param {function} botSend - Función que maneja los envios + * @param {string} from - Representa al usuario que lanzo la petición + */ + +exports.estado = function(botSend, from) { + validarEstado(botSend, from, function(){ + alchemy.apiKeyInfo({}, function(err, response) { + if (err) { + botSend(from, "Tenemos un error: \n" + err); + } else { + botSend(from, '- Estado: ' + response.status + '\n- Consumido: ' + response.consumedDailyTransactions + '\n- Limite: ' + response.dailyTransactionLimit); + } + }); + }); +}; + + + +/** + * Función que envía al solicitante el analisis de una fotografía (errores, famosos, datos biométricos) + * Se cubren todos los posibles casos: fotos sin personas, personas famosas, personas no famosas, multiples personas... + * @param {function} botSend - Función que maneja los envios + * @param {string} from - Representa al usuario que lanzo la petición + * @param {string} message - Representa el mensaje enviado por el usuario en la petición + */ + +exports.reconocimientoFacial = function(botSend, from, message) { + validarEstado(botSend, from, function(){ + + alchemy.imageFaces(message, {}, function(err, response) { + if (err) { + console.log(err); + botSend(from, err); + } else { + var imageFaces = response.imageFaces; + + if (response.status === "OK") { + if (imageFaces.length !== 0) { + // Información mínima disponible + var respuesta = ""; + for (var i = 0; i < imageFaces.length; i++) { + + if (imageFaces[i].identity) { + // Es un famoso + respuesta += "- " + imageFaces[i].identity.name + " (" + imageFaces[i].identity.score + "%) " + imageFaces[i].identity.disambiguated.subType[1]; + respuesta += "\n"; + + } else { + // No es un famoso + respuesta += "- Anónimo. Estimo una edad entorno a " + imageFaces[i].age.ageRange + " y es " + (imageFaces[i].gender.gender === 'MALE' ? 'Hombre' : 'Mujer'); + respuesta += "\n"; + } + + } + botSend(from, "Yo veo... \n" + respuesta); + } else { + // Sin información mínima disponible + botSend(from, "¿De qué personas me hablas?"); + } + + } else { + botSend(from, "Mala suerte!\nAlchemy me ha mandado datos incorrectos."); + } + } + }); + + }); +}; + + + + +/** + * Función para detectar el idioma + * @param {function} botSend - Función que maneja los envios + * @param {string} from - Representa al usuario que lanzo la petición + * @param {string} message - Representa el mensaje enviado por el usuario en la petición + */ + +exports.idioma = function(botSend, from, message) { + validarEstado(botSend, from, function(){ + alchemy.language(message, {}, function(err, response) { + if (err) { + // Error de Conexión + console.log(err); + botSend(from, err); + } else { + if (response.language === "unknown") { + botSend(from, "Que idioma es ese?!"); + } else { + botSend(from, "Eso es " + response.language); + if (response["iso-639-2"] && response["native-speakers"]) { + botSend(from, "- ISO 639: " + response["iso-639-2"] + "\n- Hablantes: " + response["native-speakers"]); + } + if (response.wikipedia) { + botSend(from, response.wikipedia); + } + } + } + }); + }); +}; + + + +/** + * Función para detectar el sentimeinto + * @param {function} botSend - Función que maneja los envios + * @param {string} from - Representa al usuario que lanzo la petición + * @param {string} message - Representa el mensaje enviado por el usuario en la petición + */ + +exports.sentimiento = function(botSend, from, message) { + validarEstado(botSend, from, function(){ + alchemy.sentiment(message, {}, function(err, response) { + if (err) { + console.log(err); + botSend(from, err); + } else { + var sentiment = ""; + + if (response.status === "OK") { + sentiment += "- Idioma: " + response.language; + if (response.docSentiment) { + sentiment += "\n- Tipo: " + response.docSentiment.type; + if (response.docSentiment.score) { + sentiment += " (" + response.docSentiment.score + ")"; + } + } + botSend(from, sentiment); + } else { + botSend(from, "Alchemy me ha mandado datos incorrectos.\n"+response.statusInfo); + } + } + }); + }); +}; + + + +/** + * Función para detectar las emociones + * @param {function} botSend - Función que maneja los envios + * @param {string} from - Representa al usuario que lanzo la petición + * @param {string} message - Representa el mensaje enviado por el usuario en la petición + */ + +exports.emociones = function(botSend, from, message) { + validarEstado(botSend, from, function(){ + alchemy.emotions(message, {}, function(err, response) { + if (err) { + console.log(err); + botSend(from, err); + } else { + if (response.status === "OK") { + var emotionsData = "Mi análisis:\n"; + emotionsData += "- Idioma: " + response.language + "\n"; + emotionsData += "- Enfado (" + response.docEmotions.anger + ")\n"; + emotionsData += "- Repugnancia (" + response.docEmotions.disgust + ")\n"; + emotionsData += "- Miedo (" + response.docEmotions.fear + ")\n"; + emotionsData += "- Alegría (" + response.docEmotions.joy + ")\n"; + emotionsData += "- Tristeza (" + response.docEmotions.sadness + ")\n"; + botSend(from, emotionsData); + } else { + botSend(from, "Alchemy me ha mandado datos incorrectos.\n"+response.statusInfo); + } + } + }); + }); +}; diff --git a/config.js b/config.js index 52e97d7..98d5d2a 100644 --- a/config.js +++ b/config.js @@ -3,10 +3,27 @@ var pjson = require('./package.json'); var config = { version: pjson.version, creador: pjson.author, - usuarioId: "", - usuarioAutorizado: "", - botEmail: "", - botPassword: "" + // Habgouts + hangouts: { + usuarioId: "", + usuarioAutorizado: "", + botEmail: "", + botPassword: "", + services: { + twitter: true, + alchemy: true + } + }, + alchemyApi: { + key: "" + }, + //Twitter + twitter : { + consumer_key: "", + consumer_secret: "", + access_token_key: "", + access_token_secret: "" + } }; module.exports = config; \ No newline at end of file diff --git a/img/captura_1.png b/img/captura_1.png new file mode 100644 index 0000000..77f1c41 Binary files /dev/null and b/img/captura_1.png differ diff --git a/img/captura_2.png b/img/captura_2.png new file mode 100644 index 0000000..d47e285 Binary files /dev/null and b/img/captura_2.png differ diff --git a/index.js b/index.js new file mode 100644 index 0000000..a64da2a --- /dev/null +++ b/index.js @@ -0,0 +1,16 @@ +var hangouts = require("./robot"); + +hangouts.response({ + id: "ciao", + condition: function(msg){ + return "ciao" === msg; + }, + action: function(from, msg){ + return "Ciao... amigo!"; + }, + // Opcionales + admin: false, // Requiere ser Admin?. Valor por defecto False. + special: false, // Asíncrono? Valor por defecto False + description: "Nos despedimos...", + sample: "ciao" +}); \ No newline at end of file diff --git a/package.json b/package.json index ac3bb61..716faa1 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,28 @@ { - "name": "Nodejs-hangouts-robot", - "version": "0.0.1", - "description": "Robot de chat para Google Hangouts desarrollado con Node.js. Permite el uso de la Terminal/Consola y más...", - "main": "robot.js", + "name": "simple-hangouts-bot", + "homepage": "https://github.com/UlisesGascon/simple-hangouts-bot", + "version": "1.0.0", + "description": "Robot de chat para Google Hangouts desarrollado con Node.js. Permite el uso de la Terminal/Consola, Tweeter, Alchemy y más...", + "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "Ulises Gascon", + "author": { + "name": "Ulises Gascón", + "url": "https://github.com/UlisesGascon" + }, + "keywords": [ + "chatbot", + "hangouts", + "chat", + "bot", + "alchemy" + ], + "repository": "UlisesGascon/simple-hangouts-bot", "license": "GPL-3.0", "dependencies": { - "hangouts-bot": "^0.2.1" + "hangouts-bot": "^0.2.1", + "alchemy-api": "^1.3.2", + "twitter": "1.3.0" } } diff --git a/robot.js b/robot.js index 5eef6b4..9a60c51 100644 --- a/robot.js +++ b/robot.js @@ -1,78 +1,397 @@ -// -- Dependencias -- var hangoutsBot = require("hangouts-bot"), - exec = require('child_process').exec, - config = require('./config'), - bot = new hangoutsBot(config.botEmail, config.botPassword); - -// -- Variables -- -var masterUserRegex = new RegExp(config.usuarioId), - masterUser = config.usuarioAutorizado, - terminalRegex = /^[Tt]erminal /, - holaRegex = /^[Hh]ola/; - -bot.on('online', function() { - bot.sendMessage(masterUser, "Hola de nuevo, Jefe!"); -}); - -bot.on('message', function(from, message) { - console.log(from + ">> " + message); - if(message === "Quien eres?"){ - bot.sendMessage(from, "Soy un Robot... ayudo a desarrolladores que lo necesitan."); - } else if (message === "Que version eres?"){ - bot.sendMessage(from, "Yo estoy en la version "+config.version); - } else if (message === "Quien es tu creador?"){ - bot.sendMessage(from, "Mi creador es "+config.creador); - } else if (message === "Quien soy?"){ - bot.sendMessage(from, "Yo te conozco como "+from); - } else if (holaRegex.test(message)){ - bot.sendMessage(from, "Hola Humano! Qué tal?"); - } else if (message === "Timestamp"){ - bot.sendMessage(from, hora()); - } else if(terminalRegex.test(message)){ - if (masterUserRegex.test(from)){ - var comando = message.replace(terminalRegex,''); - console.log(comando); - - exec(comando, function (err, stdout, stderr) { - if(!err){ - bot.sendMessage(from, 'Respuesta: \n'+stdout); - } else { - bot.sendMessage(masterUser, 'Error: \n'+err); - } - }); - } else { - bot.sendMessage(from, 'Buen intento.. pero con esas zapatillas no ejecutas comandos!'); - bot.sendMessage(masterUser, 'Intento de ejecutar código por parte de '+from+'\n Ha solicitado '+message); - } - } else { - bot.sendMessage(from, "No te entiendo... Explicate mejor, Humano!"); - } -}); - -// -- Eventos -- + config = require('./config'), + exec = require('child_process').exec, + systemInfo = require('./sysinfo'), + alchemy = require('./alchemy'), + twitter = require('twitter'), + bot = new hangoutsBot(config.hangouts.botEmail, config.hangouts.botPassword); + + +var hangouts = { + container: [], + communicator: bot, + regex: { + terminal: /^[Tt]erminal/, + hola: /^[Hh]ola/, + tweet: /^[Tt]weet/, + ayuda: /^[Aa]yuda/, + echo: /^[Ee]cho/, + foto: /^[Ff]oto/, + idioma: /^[Ii]dioma/, + sentimiento: /^[Ss]entimiento/, + emociones: /^[Ee]mociones/, + estado: /^[Ee]stado/, + url: /^http/, + masterUser: new RegExp(config.hangouts.usuarioId) + }, + response: function (options) { + /* Optional */ + options.admin = options.admin || false; + options.special = options.special || false; + options.description = options.description || false; + options.sample = options.sample || false; + + /* Validación */ + var err = false; + if(typeof options.id !== 'string') err = "id has to be a string!"; + if(typeof options.condition !== 'function') err = "condition has to be a function!"; + if(typeof options.action !== 'function') err = "success has to be a function!"; + if(options.special && typeof options.special !== 'boolean') err = "special has to be a string!"; + if(options.admin && typeof options.admin !== 'boolean') err = "admin has to be a string!"; + if(options.description && typeof options.description !== 'string') err = "description has to be a string!"; + if(options.sample && typeof options.sample !== 'string') err = "sample has to be a string!"; + + if(!err) { + var duplicated = false; + + hangouts.container.forEach(function(item,index){ + if(item.id === options.id){ + duplicated = true; + } + }); + + if(!duplicated){ + hangouts.container.push(options); + } else { + console.log("Error: ID ya está en uso... Respuesta no añadida."); + } + + } else { + console.log("Error: " + err +". Respuesta no añadida."); + } + + } +}; + +/* + ----- EVENTOS ----- +*/ + +// Al conectar! +hangouts.communicator.on('online', function(){ + hangouts.communicator.sendMessage(config.hangouts.usuarioAutorizado, "Hola de nuevo, Humano! Que quieres?"); +}); // CONTROL + C process.on('SIGINT', function() { - bot.sendMessage(masterUser, "Me piro! Ya no me quieres como antes..."); + hangouts.communicator.sendMessage(config.hangouts.usuarioAutorizado, "Me piro! Ya no me quieres como antes..."); process.exit(); }); // Salida Normal process.on('exit', function() { - bot.sendMessage(masterUser, "Me piro! Vaciones por fín!"); + hangouts.communicator.sendMessage(config.hangouts.usuarioAutorizado, "Me piro! Vaciones por fín!"); process.exit(); }); // Salida inesperada process.on('uncaughtException', function() { - bot.sendMessage(masterUser, "Me piro! Cierre inesperado..."); + hangouts.communicator.sendMessage(config.hangouts.usuarioAutorizado, "Me piro! Cierre inesperado..."); process.exit(); }); -// -- Funciones -- -function hora (){ - var date = new Date(); - return (date.toLocaleString('es-ES')); -} +hangouts.communicator.on('message', function(from, message){ + var match = false; + message = message.trim(); + hangouts.container.forEach(function(item,index){ + // Es admin? + var validated = item.admin ? hangouts.regex.masterUser.test(from) : true; + + if(validated){ + if(item.condition(message)){ + if(!item.special){ + hangouts.communicator.sendMessage(from, item.action(from, message) || "Operación realizada con éxito"); + } else { + item.action(from, message); + } + match = true; + } + } else { + hangouts.communicator.sendMessage(from, 'Buen intento.. pero con esas zapatillas no ejecutas comandos!'); + hangouts.communicator.sendMessage(config.hangouts.usuarioAutorizado, 'Intento de ejecutar código por parte de '+from+'\n Ha solicitado '+message); + } + }); + if(!match) { + console.log("[No comprendido]", message); + hangouts.communicator.sendMessage(from, "No te entiendo... Explicate mejor, Humano!"); + } +}); + + + +/* + ----- MENSAJES/RESPUESTAS ----- +*/ + +var sender = hangouts.communicator.sendMessage; + + +hangouts.response({ + id: "alchemy-status", + condition: function(msg){ + return hangouts.regex.estado.test(msg); + }, + action: function(from, msg){ + alchemy.estado(sender, from) + }, + admin: false, + special: true, + description: "Verifica el estado de la API", + sample: "estado" +}); + + + +hangouts.response({ + id: "alchemy-reconocimientoFacial", + condition: function(msg){ + return hangouts.regex.foto.test(msg); + }, + action: function(from, msg){ + msg = msg.replace(hangouts.regex.foto,''); + msg = msg.trim(); + alchemy.reconocimientoFacial(sender, from, msg) + }, + admin: false, + special: true, + description: "Análisis fotográfico. Reconoce famosos y patrones biométricos", + sample: "foto {url}" +}); + + +hangouts.response({ + id: "alchemy-idioma", + condition: function(msg){ + return hangouts.regex.idioma.test(msg); + }, + action: function(from, msg){ + msg = msg.replace(hangouts.regex.idioma,''); + msg = msg.trim(); + alchemy.idioma(sender, from, msg) + }, + admin: false, + special: true, + description: "Detección del idioma", + sample: "Idioma {url|texto|html}" +}); + + +hangouts.response({ + id: "alchemy-sentimiento", + condition: function(msg){ + return hangouts.regex.sentimiento.test(msg); + }, + action: function(from, msg){ + msg = msg.replace(hangouts.regex.sentimiento,''); + msg = msg.trim(); + alchemy.sentimiento(sender, from, msg) + }, + admin: false, + special: true, + description: "Análisis del sentimiento", + sample: "Sentimiento {url|texto|html}" +}); + + +hangouts.response({ + id: "alchemy-emociones", + condition: function(msg){ + return hangouts.regex.emociones.test(msg); + }, + action: function(from, msg){ + msg = msg.replace(hangouts.regex.emociones,''); + msg = msg.trim(); + alchemy.emociones(sender, from, msg) + }, + admin: false, + special: true, + description: "Detecta las emociones", + sample: "emociones {url|texto|html}" +}); + + +hangouts.response({ + id: "ayuda", + condition: function(msg){ + return hangouts.regex.ayuda.test(msg); + }, + action: function(from, msg){ + var id = msg.replace(hangouts.regex.ayuda,''); + id = id.trim(); + var fullAnwser = ""; + if(id === "") { + fullAnwser = "Comandos disponibles: "; + hangouts.container.forEach(function(item,index){ + fullAnwser += item.id+", "; + }); + fullAnwser = fullAnwser.slice(0, -2); + } else { + var encontrado = false; + hangouts.container.forEach(function(item,index){ + if(item.id === id.trim()){ + encontrado = true; + fullAnwser += item.id+"\n"; + fullAnwser += "- Descripción: "+(item.description || "No lo añadiste!")+"\n"; + fullAnwser += "- Ejemplo: "+(item.sample || "Improvisa!")+"\n"; + fullAnwser += "- Solo Admin?: "+item.admin+"\n"; + fullAnwser += "- Manejo especial?: "+item.special; + } + }); + if(!encontrado){ + fullAnwser = "Comando no encontrado."; + } + } + return fullAnwser; + }, + admin: false, + description: "Facilita obtener información sobre los comandos disponibles.\n [Ayuda]: muestra comandos disponibles. \n [Ayuda (ID)]: Muestra la información detallada de un comando.", + sample: "ayuda {id}" +}); + + +hangouts.response({ + id: "terminal", + condition: function(msg){ + return hangouts.regex.terminal.test(msg); + }, + action: function(from, msg){ + var comando = msg.replace(hangouts.regex.terminal,''); + comando = comando.trim(); + + exec(comando, function (err, stdout, stderr) { + if(!err){ + hangouts.communicator.sendMessage(from, 'Respuesta: \n'+stdout); + } else { + hangouts.communicator.sendMessage(from, 'Error: \n'+err); + } + }); + + }, + admin: true, + special: true, + description: "Lanza comandos de terminal y retorna la respuesta de la consola.", + sample: "Terminal git status" +}); + +var curratelo_es = new twitter(config.twitter); + +hangouts.response({ + id: "tweet", + condition: function(msg){ + return hangouts.regex.tweet.test(msg); + }, + action: function(from, msg){ + var tweetContent = msg.replace(hangouts.regex.tweet,''); + tweetContent = tweetContent.trim(); + curratelo_es.post('statuses/update', {status: tweetContent}, function(error, tweet, response){ + if(error){ + hangouts.communicator.sendMessage(from, "[Error] "+error+". Tweet: "+tweet); + } else { + hangouts.communicator.sendMessage(from, "Tweet Enviado con Éxito."); + } + }); + }, + admin: true, + special: true, + description: "Manda un Tweet con la cuenta configurada", + sample: "tweet Nos flipa muchisimo #Nodejs y a ti?" +}); + +hangouts.response({ + id: "SystemInfo", + condition: function(msg){ + return "System info" === msg; + }, + action: function(from, msg){ + var data = "[SERVER][SYSTEM][General] Uptime: "+systemInfo.uptime+" | Kernel: "+systemInfo.kernel+" | Hostname: "+systemInfo.hostname+"\n"; + data += "[SERVER][SYSTEM][CPU & RAM] Total: "+systemInfo.memory.total+" | Libre: "+systemInfo.memory.free+" ("+systemInfo.memory.percent.free+"%) | Usada: "+systemInfo.memory.used+" ("+systemInfo.memory.percent.used+"%)\n"; + data += "[SERVER][SYSTEM][CPU & RAM] CPU: "+systemInfo.cpu+"% | Buffered: "+systemInfo.memory.buffered+" ("+systemInfo.memory.percent.buffered+"%) | Cached: "+systemInfo.memory.cached+" ("+systemInfo.memory.percent.cached+"%)\n"; + data += "[SERVER][SYSTEM][Top List] Top 10:\n"+systemInfo.topListOriginal; + return data; + }, + description: "Informacion del sistema muestra RAM, CPU, etc... en tiempo real.", + sample: "System info" +}); + + +hangouts.response({ + id: "hora", + condition: function(msg){ + return "hora" === msg; + }, + action: function(from, msg){ + var date = new Date(); + return (date.toLocaleString('es-ES')); + } +}); + +hangouts.response({ + id: "hola", + condition: function(msg){ + return hangouts.regex.hola.test(msg); + }, + action: function(from, msg){ + return "Hola Humano! Qué tal?"; + } +}); + +hangouts.response({ + id: "quienSoy", + condition: function(msg){ + return "Quien soy?" === msg; + }, + action: function(from, msg){ + return "Yo te conozco como "+from; + }, + sample: "Quien soy?" +}); + +hangouts.response({ + id: "creador", + condition: function(msg){ + return "Quien es tu creador?" === msg; + }, + action: function(from, msg){ + return "Mi creador es "+config.creador; + }, + sample: "Quien es tu creador?" +}); + +hangouts.response({ + id: "version", + condition: function(msg){ + return "Que version eres?" === msg; + }, + action: function(from, msg){ + return "Yo estoy en la version "+config.version; + }, + sample: "Que version eres?" +}); + + +hangouts.response({ + id: "quienEres", + condition: function(msg){ + return "Quien eres?" === msg; + }, + action: function(from, msg){ + return "Soy un Robot... ayudo a desarrolladores que lo necesitan."; + }, + sample: "Quien eres?" +}); + + +hangouts.response({ + id: "echo", + condition: function(msg){ + return hangouts.regex.echo.test(msg); + }, + action: function(from, msg){ + var echoContent = msg.replace(hangouts.regex.tweet,''); + echoContent = echoContent.trim(); + return from + ">> " + echoContent; + } +}); +module.exports = hangouts; \ No newline at end of file diff --git a/sysinfo.js b/sysinfo.js new file mode 100644 index 0000000..aa014db --- /dev/null +++ b/sysinfo.js @@ -0,0 +1,119 @@ +var exec = require('child_process').exec, child, child1; + +var systemInfo = { + memory: { + percent: {} + } +}; + +setInterval(function(){ + // Function for checking memory + child = exec("egrep --color 'MemTotal' /proc/meminfo | egrep '[0-9.]{4,}' -o", function (error, stdout, stderr) { + if (error !== null) { + console.log('[ERROR][SYSINFO][MEM] Exec error: ' + error); + } else { + var memTotal = stdout.replace("\n",""); + systemInfo.memory.total = parseInt(memTotal); + } + }); + + // Function for checking hostname + child = exec("hostname", function (error, stdout, stderr) { + if (error !== null) { + console.log('[ERROR][SYSINFO][Hostname] Exec error: ' + error); + } else { + var hostname = stdout.replace("\n",""); + systemInfo.hostname = hostname; + } + }); + + // Function for checking uptime + child = exec("uptime | tail -n 1 | awk '{print $1}'", function (error, stdout, stderr) { + if (error !== null) { + console.log('[ERROR][SYSINFO][Uptime] Exec error: ' + error); + } else { + var uptime = stdout.replace("\n",""); + systemInfo.uptime = uptime; + } + }); + + // Function for checking Kernel version + child = exec("uname -r", function (error, stdout, stderr) { + if (error !== null) { + console.log('[ERROR][SYSINFO][Kernel] Exec error: ' + error); + } else { + var kernel = stdout.replace("\n",""); + systemInfo.kernel = kernel; + } + }); + + // Function for checking Top list + child = exec("ps aux --width 30 --sort -rss --no-headers | head | awk '{print $11}'", function (error, stdout, stderr) { + if (error !== null) { + console.log('[ERROR][SYSINFO][Top-list] Exec error: ' + error); + } else { + systemInfo.topListOriginal = stdout; + var topList = stdout.split("\n"); + systemInfo.topList = topList; + } + }); + + // Function for checking CPUUsage + child = exec("top -d 0.5 -b -n2 | grep 'Cpu(s)'|tail -n 1 | awk '{print $2 + $4}'", function (error, stdout, stderr) { + if (error !== null) { + console.log('[ERROR][SYSINFO][CPU] Exec error: ' + error); + } else { + var cpuUsageUpdate = parseFloat(stdout); + systemInfo.cpu = cpuUsageUpdate; + } + }); +}, 2000); + + +// Function for checking memory free and used +setInterval(function(){ + child1 = exec("egrep --color 'MemFree' /proc/meminfo | egrep '[0-9.]{4,}' -o", function (error, stdout, stderr) { + if (error === null) { + var memFree = stdout.replace("\n",""); + var memUsed = parseInt(systemInfo.memory.total)-parseInt(memFree); + var percentUsed = Math.round(parseInt(memUsed)*100/parseInt(systemInfo.memory.total)); + var percentFree = 100 - percentUsed; + systemInfo.memory.free = parseInt(memFree); + systemInfo.memory.percent.free = percentFree; + systemInfo.memory.used = parseInt(memUsed); + systemInfo.memory.percent.used = percentUsed; + } else { + console.log('[ERROR][SYSINFO][MEM-DETAILS] Exec error: ' + error); + } + }); + + + // Function for checking memory buffered + child1 = exec("egrep --color 'Buffers' /proc/meminfo | egrep '[0-9.]{4,}' -o", function (error, stdout, stderr) { + if (error === null) { + var memBuffered = stdout.replace("\n",""); + var percentBuffered = Math.round(parseInt(memBuffered)*100/parseInt(systemInfo.memory.total)); + systemInfo.memory.buffered = parseInt(memBuffered); + systemInfo.memory.percent.buffered = percentBuffered; + } else { + console.log('[ERROR][SYSINFO][MEM-BUFFERED] Exec error: ' + error); + } + }); + + + + // Function for checking memory buffered + child1 = exec("egrep --color 'Cached' /proc/meminfo | egrep '[0-9.]{4,}' -o", function (error, stdout, stderr) { + if (error === null) { + var memCached = stdout.replace("\n",""); + var percentCached = Math.round(parseInt(memCached)*100/parseInt(systemInfo.memory.total)); + systemInfo.memory.cached = parseInt(memCached); + systemInfo.memory.percent.cached = percentCached; + } else { + console.log('[ERROR][SYSINFO][MEM-CACHED] Exec error: ' + error); + } + }); + +}, 4000); + +module.exports = systemInfo; \ No newline at end of file