diff --git a/README.md b/README.md index 84ef58b..3cb604a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ # Slackalytics -Slackalytics is a textual analysis bot built in Node.js that allows for deeper custome analytics by sending message strings to Google Analysis via Slacks realtime API and Google Analytics Measurement Protocol. - -More Readme info is coming soon - -In the meantime checkout the post for this on my blog: http://nicomiceli.com/slackalytics/ +Slackalytics is a textual analysis bot built in Node.js that allows for deeper customer analytics by sending message strings to analytics solutions via Slacks realtime outbound webhook API and respective analytics solution data collection services. \ No newline at end of file diff --git a/app.js b/app.js index 2fcfbd6..bf781dc 100644 --- a/app.js +++ b/app.js @@ -1,93 +1,271 @@ +//Set up Env Vars +var env_var = { + environment: process.env.NODE_ENV || 'development', // supports: production and development + log_level: process.env.LOGLEVEL, // supports: debug, error, warn, info, off + write_mongo: process.env.MONGO_ENABLED, // true / false + analytics_track: process.env.ANALYTICS_ENABLED, // true / false + mongo_user: process.env.MONGO_USER_PROD, + mongo_password: process.env.MONGO_PASSWORD_PROD, + mongo_server: process.env.MONGO_SERVER_PROD, + mongo_port: process.env.MONGO_PORT_PROD, + mongo_db: process.env.MONGO_DB_PROD, + mongo_cluster_db: process.env.MONGO_CLUSTER_DB, + mongo_shard_1: process.env.MONGO_SHARD_ONE, + mongo_shard_1_port: process.env.MONGO_SHARD_ONE_PORT, + mongo_shard_2: process.env.MONGO_SHARD_TWO, + mongo_shard_2_port: process.env.MONGO_SHARD_TWO_PORT, + mongo_shard_3: process.env.MONGO_SHARD_THREE, + mongo_shard_3_port: process.env.MONGO_SHARD_THREE_PORT, + mongo_shard_query: process.env.MONGO_QUERY, + mongo_cluster_server: process.env.MONGO_CLUSTER_SERVER, + ga_key: process.env.GOOGLE_ANALYTICS_PROD, + mixpanel_key: process.env.MIXPANEL_PROD, + segmentio_key: process.env.SEGMENTIO_PROD +}; + //Set up Reqs var express = require('express'); var bodyParser = require('body-parser'); var request = require('request'); var qs = require('querystring'); - +var math = require('mathjs'); +var moment = require('moment'); +var uuid = require('node-uuid'); +var mongodb = require('mongodb'); +var Analytics = require('analytics-node'); //Server Details var app = express(); var port = process.env.PORT || 3000; +//SegmentIO +var analytics = new Analytics(env_var.segmentio_key); + +//Logger +var logger = exports; +logger.debugLevel = env_var.log_level || 'warn'; +logger.log = function(level, message) { + var levels = ['debug', 'error', 'warn', 'info', 'off']; + if (levels.indexOf(level) >= levels.indexOf(logger.debugLevel) ) { + if (typeof message !== 'string') { + message = JSON.stringify(message); + } + console.log(level+': '+message); + } +}; + //Set Body Parser app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json()); app.use(bodyParser.json({ type: 'application/vnd.api+json' })); +//Simple Base64 handler +var base64 = exports; +base64.encode = function (unencoded) { + return new Buffer.from(unencoded || '').toString('base64'); +}; +base64.decode = function (encoded) { + return new Buffer.from(encoded || '', 'base64').toString('utf8'); +}; //Routes app.get('/', function(req, res){ res.send('here'); }); -app.post('/collect', function(req, res){ +app.get('/ping', function(req, res){ + res.send('I\'m alive!' + " Ping Time: " + new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')); +}); +app.post('/collect', function(req, res){ var channel = { id: req.body.channel_id, name: req.body.channel_name }; + var user = { - id: req.body.user_id + id: req.body.user_id, + name: req.body.user_name }; + + var teamDomain = req.body.team_domain; + + var msgTime = math.round(req.body.timestamp, 0); //in epoch by day + + var msgSeconds = req.body.timestamp.replace(/./g,''); //in epoch by millisecond var msgText = req.body.text; function searchM(regex){ var searchStr = msgText.match(regex); - if(searchStr != null){ + if(searchStr !== null){ return searchStr.length; } return 0; - }; + } function searchS(regex){ var searchStr = msgText.split(regex); - if(searchStr != undefined){ + if(searchStr !== undefined){ return searchStr.length; } return 0; - }; + } var wordCount = searchS(/\s+\b/); - var emojiCount = searchM(/:[a-z_0-9]*:/g); + var emojiCount = searchM(/:[a-z_0-9_-]*:/g); var exclaCount = searchM(/!/g); var questionMark = searchM(/\?/g); - var elipseCount = searchM(/\.\.\./g); - - - //Structure Data - var data = { - v: 1, - tid: "UA-XXXXXXXX-1", - cid: user.id, - ds: "slack", //data source - cs: "slack", // campaign source - cd1: user.id, - cd2: channel.name, - cd3: msgText, - cm1: wordCount, - cm2: emojiCount, - cm3: exclaCount, - // cm4: letterCount, - cm5: elipseCount, - cm6: questionMark, //need to set up in GA - t: "event", - ec: "slack: "+ channel.name + "|" + channel.id, - ea: "post by " + user.id, - el: msgText, - ev: 1 - }; - console.log(JSON.stringify(data)); - console.log(req.body); - //Make Post Request - request.post("https://www.google-analytics.com/collect?" + qs.stringify(data), - function(error, resp, body){ - console.log(error); - }) + var elipsisCount = searchM(/\.\.\./g); + var alertCount = searchM(/7.5.1", + "moment": "^2.4.0", + "mongodb": "^3.6.2", + "node-uuid": "^1.4.0", + "querystring": "^0.2.0", + "request": "^2.54.0" }, "scripts": { "start": "node app.js"