Last active
November 20, 2019 21:40
-
-
Save alloy-d/26311ccb34819644569f1858fdb17424 to your computer and use it in GitHub Desktop.
Summarizing a year of emoji reactions in Slack
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
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)) |
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
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