「Slackの『絵文字によるリアクション率』を計測したい」というご相談を頂きました
とある顧客の担当者様より「社内で『Slackの投稿に対して、絵文字でどれだけリアクションしているかの率を計測したい』という要望が挙がったが、どうすればよいか?」というお問い合わせを頂いた。
それを私が請け負ったりする、という話には一切なっていないが、検証と好奇心の充足を兼ねてコードを書いてみた。
1時間強掛けて、CSV出力できるところまでは実装できたので、自分のための資産としてここにコードを貼り付けておく。
# 注意事項
尚、今回は要件が一切定まっていない状態で検証を行っているため、「各メッセージに含まれる絵文字数」が取れるところまで確認するのをゴールとしている。
というのも、本当にこれを動かすとしたらちゃんとヒアリングなどをする必要があり、
「リアクション率 = メッセージあたりの平均絵文字数」が欲しい数字?
チャンネルの参加人数による重み付けは必要ではない?
などを検討する必要があるが、とりあえず「各メッセージに含まれる絵文字数」が取れれば後はなんとでもなるため。
# 実際のコード
.envにSLACK_BOT_TOKENを設定した上で、nodeのcliから直接下記を叩いた。
code:javascript
import { WebClient } from "@slack/web-api"
const slack = new WebClient(process.env.SLACK_BOT_TOKEN)
const channels = await slack.conversations.list({
exclude_archived: true,
types: "public_channel",
})
const messages = []
const memberCountStore = {}
for(const channel of channels.channels){
console.log(Channel: ${channel.name} (${channel.id}));
if(channel.is_ext_shared) {
console.log("External shared channel, skipping")
continue;
}
if(!channel.is_member) {
console.log("Not a member, joining")
await slack.conversations.join({
channel: channel.id,
})
}
let cursor = undefined
while (cursor !== null) {
const history = await slack.conversations.history({
channel: channel.id,
limit: 999,
cursor: cursor,
})
messages.push(
...history.messages.map(message => Object.assign(message, {channel}))
)
cursor = history.has_more ? history.response_metadata.next_cursor : null
history.messages0.reactions }
if(!channel.is_member) {
console.log("Not a member, leaving")
await slack.conversations.leave({
channel: channel.id,
})
}
}
const result = new Map()
messages.forEach(message => {
const channel = message.channel
const container = result.has(channel) ? result.get(channel) : []
container.push(
message.reactions?.reduce((acc, reaction) => acc + reaction.count, 0) ?? 0
)
result.set(channel, container)
})
console.log("Channel,Member Count,Total Messages,Total Reactions,Average Reactions")
result.forEach((reactions, channel) => {
const totalMessages = reactions.length
const totalReactions = reactions.reduce((acc, count) => acc + count, 0)
const averageReactions = totalReactions / totalMessages
console.log(
#${channel.name},${memberCount},${totalMessages},${totalReactions},${averageReactions.toFixed(2)}
)
})