Last active
June 1, 2018 21:25
-
-
Save rxtphan/46959aed829760a327a23c1ca0b19746 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const rp = require('request-promise'); | |
const _ = require('lodash'); | |
let emojisList = {}; | |
let allEmojis = {}; | |
let users = {}; | |
let count = 0; | |
const monthsBack = 4; | |
const token = '<get token @ https://api.slack.com/custom-integrations/legacy-tokens>'; | |
let d = new Date(); | |
d.setMonth(d.getMonth() - monthsBack); | |
const ts = Math.round(d.getTime() / 1000); | |
const ts_with_ms = `${ts}.000001`; | |
// Find channel IDs at https://api.slack.com/methods/channels.list/test | |
const channels = [ | |
{ name: 'NAFTA', id: 'C4F53JUJZ' }, | |
{ name: 'COFFEE', id: 'C0B9MEJEQ' }, | |
{ name: 'CREAM', id: 'C07BLMC7K' }, | |
{ name: 'Lightning', id: 'C5WN1A3NE' }, | |
{ name: 'Pacific', id: 'C8T85QDUZ' }, | |
{ name: 'B/E Platform', id: 'C07BK9649' }, | |
{ name: 'F/E Platform', id: 'C9PEW6M4N' }, | |
{ name: 'Octopus', id: 'C90HA1266' }, | |
{ name: 'DevOps', id: 'C052HV5QP' }, | |
{ name: 'USS', id: 'C07KFNT0T' }, | |
{ name: 'Email Engagement', id: 'C2PJF9E72' }, | |
{ name: 'Data Science', id: 'C07BKFUP8' }, | |
{ name: 'Watercooler', id: 'C02GW2AD0' }, | |
{ name: 'Dank Memes', id: 'C1V13BUAG' }, | |
]; | |
const printTitle = (title) => { | |
console.log('=============================='); | |
console.log(`*${title}*`); | |
console.log('=============================='); | |
}; | |
const getEmojis = () => { | |
const getBaseEmojis = rp({ uri: 'https://raw.githubusercontent.com/iamcal/emoji-data/master/emoji.json' }) | |
.then(result => { | |
return _.mapValues(_.keyBy(JSON.parse(result), 'short_name'), () => true); | |
}); | |
const options = { | |
uri: 'https://slack.com/api/emoji.list', | |
qs: { | |
token: token, | |
pretty: 1 | |
} | |
}; | |
const getCustomEmojis = rp(options).then(result => { | |
return _.mapValues(JSON.parse(result).emoji, () => true); | |
}); | |
return Promise.all([getBaseEmojis, getCustomEmojis]).then(([baseResults, customResults]) => { | |
return _.merge({}, baseResults, customResults); | |
}); | |
}; | |
const fetchUser = id => { | |
const options = { | |
uri: 'https://slack.com/api/users.info', | |
qs: { | |
token: token, | |
user: id, | |
pretty: 1 | |
} | |
}; | |
return rp(_.extend({}, options)).then(result => JSON.parse(result)); | |
}; | |
printTitle('Emoji Counter'); | |
console.log('\n'); | |
getEmojis().then(emojisList => { | |
_.each(channels, channel => { | |
let emojis = {}; | |
const options = { | |
uri: 'https://slack.com/api/conversations.history', | |
qs: { | |
token: token, | |
channel: channel.id, | |
inclusive: true, | |
oldest: ts_with_ms, | |
limit: 1000, | |
pretty: 1 | |
} | |
}; | |
rp(_.extend({}, options, { channel: channel.id })).then((resp) => { | |
const response = JSON.parse(resp); | |
_.each(response.messages, (msg) => { | |
// Parse message text | |
const matches = msg.text.match(/:[^:\s]+:/g); | |
if (matches && matches.length) { | |
_.each(matches, (match) => { | |
const m = match.replace(/:/g, ''); | |
// Ignore matches that aren't in slack emoji universe | |
if (!emojisList[m]) { | |
return; | |
} | |
// Don't count matches of form skin-tone-<number> | |
if (m.match(/skin-tone-/)) { | |
return; | |
} | |
// Ignore mass emoji messages — nice try @mertens. | |
if (_.includes(['pr2', 'w0', 'change', 'pk3', 'bl5'], m)) { | |
return; | |
} | |
emojis[m] = (emojis[m] || 0) + 1; | |
allEmojis[m] = (allEmojis[m] || 0) + 1; | |
users[msg.user] = (users[msg.user] || 0) + 1; | |
}); | |
} | |
// Parse message reactions | |
if (msg.reactions) { | |
_.each(msg.reactions, (reaction) => { | |
const m = reaction.name.replace(/::skin-tone-\d/g, '').replace(/:/g, '').replace(/\'/g, ''); | |
emojis[m] = (emojis[m] || 0) + reaction.count; | |
allEmojis[m] = (allEmojis[m] || 0) + reaction.count; | |
_.each(reaction.users, (user) => { | |
users[user] = (users[user] || 0) + 1; | |
}); | |
}); | |
} | |
}); | |
printTitle(channel.name); | |
// Only report emojis that have been used at least 3 times. | |
emojis = _.pickBy(emojis, (value, key) => { | |
return value > 2; | |
}); | |
emojis = _.sortBy(_.toPairs(emojis), 1).reverse(); | |
_.each(emojis, e => { | |
console.log(`:${e[0]}: (${e[0]}) - ${e[1]}`); | |
}); | |
console.log('\n'); | |
if (++count === channels.length) { | |
printTitle('TOP 20 EMOJIS'); | |
allEmojis = _.take(_.sortBy(_.toPairs(allEmojis), 1).reverse(), 20); | |
_.each(allEmojis, e => { | |
console.log(`:${e[0]}: (${e[0]}) - ${e[1]}`); | |
}); | |
console.log('\n'); | |
printTitle('TOP 10 \'MOJERS'); | |
users = _.sortBy(_.toPairs(users), 1).reverse(); | |
const topUsers = _.take(users, 10); | |
let userFetches = []; | |
_.each(topUsers, u => { | |
userFetches.push(fetchUser(u[0])); | |
}); | |
Promise.all(userFetches).then(result => { | |
_.each(result, (r, i) => { | |
console.log(`${r.user.real_name} - ${topUsers[i][1]}`); | |
}); | |
}); | |
} | |
}) | |
.catch((err) => { | |
throw 'Error fetching channel messages.' | |
}); | |
}); | |
}) | |
.catch((err) => { | |
throw 'Error fetching emoji list.' | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment