Skip to content

Instantly share code, notes, and snippets.

@monkbroc
Last active July 10, 2017 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monkbroc/e91169dbe3d845e40244d0ef0ed08c35 to your computer and use it in GitHub Desktop.
Save monkbroc/e91169dbe3d845e40244d0ef0ed08c35 to your computer and use it in GitHub Desktop.
Extract the Slack message history per channel for a time period
// Extract the Slack message history per channel for a time period
// Gives an idea which Slack channels are most used
// Usage:
// Save SLACK_TOKEN in .env file
// npm install
// npm start | tee slack_channels.csv
const WebClient = require('@slack/client').WebClient;
const Promise = require('bluebird');
const moment = require('moment');
const token = process.env.SLACK_TOKEN;
if (!token) {
console.error('Run with environment variable SLACK_TOKEN set to a token from https://api.slack.com/docs/oauth-test-tokens');
process.exit(1);
}
const web = new WebClient(token);
// How many channels and users to fetch from Slack at a time
const channelsConcurrency = 4;
const userConcurrency = 4;
// How long ago to look back at messages
const messagesSince = moment().subtract(60, 'days').format('YYYY-MM-DD');
// Show or hide debug messages
const debug = false;
console.debug = debug ? console.log : () => {};
const channels = {};
const users = {};
const channelMembers = new Set();
// Fetch channels
console.debug('fetching channels');
web.channels.list({ exclude_archived: true }).then(info => {
return Promise.map(info.channels, (channel) => {
const id = channel.id;
// Filter non-public channels
if (id[0] !== 'C') {
return;
}
// Save channel
channels[channel.name] = {
membersCount: channel.members.length,
messageCount: {},
};
// Fetch user info for channel members
console.debug(`fetching users for ${channel.name}`);
return Promise.map(channel.members, (member) => {
if (!users[member]) {
users[member] = web.users.info(member).then(info => info.user);
}
return users[member];
}, { concurrency: userConcurrency }).then((members) => {
// Get message count by each user
return Promise.map(members, (member) => {
// Only count core members
if (member.is_bot || member.is_restricted || member.deleted) {
return;
}
const query = `in:${channel.name} after:${messagesSince} from:${member.name}`;
console.debug(`getting message count ${query}`);
return web.search.messages(query, { count: 0 }).then(info => {
// Save message count and member info
channelMembers.add(member.name);
channels[channel.name].messageCount[member.name] = info.messages.total;
});
}, { concurrency: userConcurrency });
});
}, { concurrency: channelsConcurrency });
}).then(() => {
// Display in CSV format
const sortedMembers = [...channelMembers].sort();
const sortedMembersList = sortedMembers.join(",");
console.log(`channel,members,messages,${sortedMembersList}`);
Object.keys(channels).forEach((channelName) => {
const channel = channels[channelName];
const membersCount = channel.membersCount;
const totalMessageCount = Object.values(channel.messageCount).reduce((a, b) => (a || 0) + (b || 0), 0);
const memberMessageCountList = sortedMembers.map((memberName) => channel.messageCount[memberName]).join(",");
console.log(`${channelName},${membersCount},${totalMessageCount},${memberMessageCountList}`);
});
});
{
"name": "slack-channels",
"version": "1.0.0",
"description": "Extract the Slack message history per channel for a time period",
"main": "index.js",
"scripts": {
"start": "env $(cat .env | xargs) node index.js"
},
"author": "Julien Vanier <jvanier@gmail.com>",
"license": "MIT",
"dependencies": {
"@slack/client": "^3.10.0",
"bluebird": "^3.5.0",
"moment": "^2.18.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment