Skip to content

Instantly share code, notes, and snippets.

@alloy-d
Last active November 20, 2019 21:40
Show Gist options
  • Save alloy-d/26311ccb34819644569f1858fdb17424 to your computer and use it in GitHub Desktop.
Save alloy-d/26311ccb34819644569f1858fdb17424 to your computer and use it in GitHub Desktop.
Summarizing a year of emoji reactions in Slack
import itertools
import os
import slack
import sys
import time
from functools import reduce
from datetime import datetime
from pprint import pprint
slack_token = os.environ["SLACK_API_TOKEN"]
client = slack.WebClient(token=slack_token)
interesting_channel_names = [ "murica-horse" ]
all_channels = client.channels_list(exclude_archived=1)
interesting_channels = [channel for channel in all_channels.data['channels'] if channel['name'] in interesting_channel_names]
def message_reactions(message):
if not 'reactions' in message:
return None
reactions = message['reactions']
return reactions
def count_recent_reactions(channel, oldest=datetime(2019,1,1)):
def get_batch(oldest):
return client.channels_history(
channel=channel['id'],
oldest=oldest)
def batches():
next_oldest = str(oldest.timestamp())
while next_oldest:
try:
batch = get_batch(next_oldest)
print(".", file=sys.stderr, end='', flush=True)
except slack.errors.SlackApiError as error:
if error.response['error'] == 'ratelimited':
retry_time = int(error.response.headers['Retry-After'])
print("*", file=sys.stderr, end='', flush=True)
time.sleep(60)
continue
yield batch.data['messages']
if batch.data['has_more']:
next_oldest = batch.data['messages'][0]['ts']
else:
next_oldest = None
reaction_batches = map(lambda batch: filter(None, map(message_reactions, batch)), batches())
reactions = itertools.chain.from_iterable(reaction_batches)
def summarize(totals, reactions):
for reaction in reactions:
emoji = reaction['name']
count = reaction['count']
totals[emoji] = count + totals.get(emoji, 0)
return totals
return reduce(summarize, reactions, {})
def print_summary(summary):
ranked = sorted(summary.items(), key=lambda pair: pair[1], reverse=True)
for (name, count) in ranked:
print(f":{name}:: {count} reactions")
for channel in interesting_channels:
print(f"counting reactions on {channel['name']}.", file=sys.stderr, flush=True)
print_summary(count_recent_reactions(channel))
aiohttp==3.6.2
async-timeout==3.0.1
attrs==19.3.0
chardet==3.0.4
idna==2.8
multidict==4.5.2
slackclient==2.3.1
yarl==1.3.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment