Skip to content

Instantly share code, notes, and snippets.

@kuboon
Last active April 8, 2020 01:44
Show Gist options
  • Save kuboon/8c66bf61a170bc49f99e5fe91352bb6f to your computer and use it in GitHub Desktop.
Save kuboon/8c66bf61a170bc49f99e5fe91352bb6f to your computer and use it in GitHub Desktop.
Slack の channel で点呼をとる
// Description:
// Slack の channel で点呼をとる
// https://gist.github.com/kuboon/8c66bf61a170bc49f99e5fe91352bb6f
// Commands:
// hubot 点呼
// Dependencies:
// "aa": "^0.1.40"
// "slack-node": "^0.1.3"
// "hubot-redis-brain"
"use strict"
const aa = require('aa'),
Slack = require('slack-node'),
slack = new Slack(process.env.HUBOT_SLACK_TOKEN),
slack_api = aa.promisify(slack, slack.api)
function sleep(msec) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, msec);
})
}
// "点呼とりまーす" に reaction した全ユーザのリスト
function all_reactioned_users(res){
let users = res.message.reactions.map((a) => a.users)
users = users.reduce((a, b) => a.concat(b)) // users.flatten!
return users.filter((e, p) => users.indexOf(e) == p) // users.uniq!
}
function* tenko(channel, all_users){
const postMessage = (text) => {
return slack_api('chat.postMessage', {
text: text,
channel: channel,
as_user: true,
link_names: 1
})
}
const message_ts = yield postMessage('点呼とりまーす @channel').then((res) => res.message.ts)
slack.api('reactions.add', {
name: 'raising_hand',
channel: channel,
timestamp: message_ts
})
// channel の全メンバ (deleted user も含まれているのであとで除外)
const members = yield slack_api('channels.info', {channel: channel}).then((res) => res.channel.members)
var sec = 0
do {
yield sleep(5 * 1000)
sec += 5
const reacted = yield slack_api('reactions.get', {channel: channel, timestamp: message_ts}).then(all_reactioned_users)
// channel の全メンバから、 reaction したユーザを引き算
const diff = members.filter((e) => reacted.indexOf(e) < 0)
// slack の member id から user object へ変換。ついでに deleted user と bot を除外
const users = diff.map((id) => all_users[id]).filter((u) => !u.slack.deleted && !u.slack.is_bot)
if(users.length == 0){
postMessage('全員集合しました!')
break
}
const names_str = users.map((u) => '@' + u.name).join(', ')
if (sec == 30) {
postMessage('反応ない人: ' + names_str)
} else if (sec >= 60) {
postMessage('反応なかった人: ' + names_str + "\n点呼を終了します。")
break
}
}while(true)
}
module.exports = (robot) => {
robot.respond(/点呼$/i, (res) => {
// hubot-slack@3.4.2 では以下のコードで動いたが、
// >4 では res.message.rawMessage.channel の代わりに res.message.room にする
aa(tenko(res.message.rawMessage.channel, robot.brain.data.users))
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment