Skip to content

Instantly share code, notes, and snippets.

@flockonus
Last active December 29, 2023 17:20
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flockonus/bea0a748139663b192a8f66e867456c9 to your computer and use it in GitHub Desktop.
Save flockonus/bea0a748139663b192a8f66e867456c9 to your computer and use it in GitHub Desktop.
Count your emojis from Slack usage!
'use strict';
/**
npm i bluebird slack-node
CREATE YOUR TOKEN: https://api.slack.com/docs/oauth-test-tokens?team_id=T024G49EC&action=reissue&sudo=1
npm package: https://www.npmjs.com/package/slack-node
user.list: https://api.slack.com/methods/users.list
reactions.list: https://api.slack.com/methods/reactions.list
**/
var Slack = require('slack-node');
var apiToken = "create one: https://api.slack.com/docs/oauth-test-tokens?team_id=T024G49EC&action=reissue&sudo=1";
var Promise = require('bluebird');
var slack = new Slack(apiToken);
Array.prototype.flatten = function() {
return this.reduce(function(prev, cur) {
var more = [].concat(cur).some(Array.isArray);
return prev.concat(more ? cur.flatten() : cur);
},[]);
}
function listUsers() {
console.log('fetching users...')
return new Promise(function(win,lose){
slack.api("users.list", function(err, response) {
if (err) return lose(err)
// console.log(response);
var people = response.members
var active = people.filter((p) => !p.deleted)
console.log('has:', people.length, 'total,', active.length, 'active')
//
win(active)
//debug: win([active[0],active[1]])
});
})
}
function getEmojis() {
return new Promise(function(resolve, reject) {
slack.api("emoji.list", function(err, response) {
if (err) return lose(err)
// name -> url||alias
var emojis = response.emoji;
var emojisAlias = [];
var emojisUrl = []
var emojisAll = []
for (let key in emojis) {
emojisAll.push(key)
if (emojis[key].includes('alias:')) {
emojisAlias.push(key)
} else {
emojisUrl.push(key)
}
}
console.log('emojis:', emojisAll.length, emojisUrl.length, emojisAlias.length)
resolve({emojisAll, emojisUrl, emojisAlias})
});
});
}
// reactionsFromUser({id:'U025188NM'})
function reactionsFromUser(user) {
var id = user.id
// console.log('fetching reactions from:', id, user.name);
return new Promise(function(resolve, reject) {
slack.api("reactions.list", {user: id, count: 100}, function(err, response) {
if (err) return reject(err)
var totalCount = 0;
// console.log(response)
var items = response.items;
var reactions = items
.filter( m => m.type === 'message')
.map(r => r.message.reactions.map(r=> r.name))
.flatten();
var reactionsCounted = {}
reactions.forEach((r) => {
totalCount += 1
reactionsCounted[r] = reactionsCounted[r] != null ? reactionsCounted[r]+1 : 1;
})
console.log('Reactions', id, user.name, totalCount)
resolve(reactionsCounted)
})
});
}
function run() {
// keep variables along the execution
var ctx = {
allReactions: {}
}
// start the chain
return getEmojis().then((emojis) => {
ctx.ourEmojis = emojis.emojisUrl;
// console.log('ctx.emojis.emojisUrl', ctx.emojis.emojisUrl)
return listUsers();
}).then ((activeUsers) => {
console.log('activeUsers:', activeUsers.length);
ctx.activeUsers = activeUsers;
// name -> count of uses
ctx.emojiCount = {}
return Promise.map(activeUsers, reactionsFromUser, {concurrency: 3})
}).then((reactionsMap) => {
console.log('aggregating data from', reactionsMap.length, 'emoji counts')
reactionsMap.forEach((reactionsCounted)=>{ // each item is like emojiname -> use count
for(let name in reactionsCounted) {
if(ctx.allReactions[name] == undefined) ctx.allReactions[name] = 0;
ctx.allReactions[name] += reactionsCounted[name]
}
})
})
// if any step along the way has failed it will break
.catch((err)=> console.error('!FAIL!', err))
.then(() => {
var ar = ctx.allReactions;
// all of the emojis, default and custom
var emojisSortedByUse = {}
// only our emojis
var ourEmojisUsage = {}
Object.keys(ar).sort(function(a,b) {
return ar[b] - ar[a]
}).forEach(function(name) {
emojisSortedByUse[name] = ar[name]
if (ctx.ourEmojis.includes(name)) ourEmojisUsage[name] = ar[name]
else console.log(name, 'not found in ourEmojisUsage, which means its system default')
})
// fill with 0 emojis that were not used at all
ctx.ourEmojis.forEach((name)=> ourEmojisUsage[name] = ourEmojisUsage[name] || 0)
console.log('Done! Total list of emojis used:')
console.log(emojisSortedByUse);
console.log('now our own custom emojis used:');
console.log(ourEmojisUsage);
})
}
run()
@Illyism
Copy link

Illyism commented Dec 22, 2019

I made a little site that does just this: https://streakcarrot.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment