Skip to content

Instantly share code, notes, and snippets.

@rxtphan
Last active June 1, 2018 21:25
Show Gist options
  • Save rxtphan/46959aed829760a327a23c1ca0b19746 to your computer and use it in GitHub Desktop.
Save rxtphan/46959aed829760a327a23c1ca0b19746 to your computer and use it in GitHub Desktop.
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