# Description: | |
# シャッフルランチの管理をします | |
# | |
# Dependencies: | |
# None | |
# | |
# Configuration: | |
# None | |
# | |
# Commands: | |
# hubot シャッフルランチ - 募集開始 | |
# hubot シャッフルランチキャンセル - 募集の取り消し | |
# hubot シャッフルランチ参加 - 参加 | |
# hubot シャッフルランチ不参加 - 参加の取り消し | |
class MemberCollector | |
constructor: -> | |
@_timer = null | |
@_members = new Set() | |
@_completion = null | |
wait: (duration, completion) -> | |
if @waiting() | |
return | |
@_members = new Set() | |
@_completion = completion | |
@_timer = setTimeout(=> | |
@_onComplete() | |
, duration) | |
stopWaiting: -> | |
if !@waiting() | |
return | |
clearTimeout(@_timer) | |
waiting: -> | |
return @_timer isnt null | |
addMember: (member) -> | |
if !@waiting() | |
return false | |
tmp = @_members.size | |
@_members.add(member) | |
return tmp < @_members.size | |
deleteMember: (member) -> | |
if !@waiting() | |
return false | |
tmp = @_members.size | |
@_members.delete(member) | |
return @_members.size < tmp | |
currentMembers: -> | |
return @_members | |
_onComplete: -> | |
@_timer = null | |
if !@_completion | |
return | |
@_completion(@) | |
class ShuffleLunchAdmin | |
constructor: -> | |
@_collector = new MemberCollector() | |
@_observing = false | |
startObserving: (robot) -> | |
if @_observing | |
return | |
@_observing = true | |
robot.respond /シャッフルランチ(?:\s?スタート)?$/, (res) => | |
if @_collector.waiting() | |
res.send("すでに参加者を募っています。\nキャンセルしたい場合は、\nシャッフルランチ キャンセル\nと送ってください。") | |
return | |
waitMinutes = 5 | |
res.send("シャッフルランチのメンバーを募集します。\n参加される方は#{waitMinutes}分以内に、\nシャッフルランチ参加\nと送ってください。") | |
@_collector.wait(1000 * 60 * waitMinutes, (collector) => | |
members = Array.from(collector.currentMembers()) | |
group = @_groupMembers(members).map((value, index) => | |
return "グループ#{index}: #{value.join(", ")}" | |
).join("\n") | |
res.send("シャッフルランチの募集を終了します。\nグループ分けは次の通りです。\n#{group}") | |
) | |
@_collector.addMember(res.message.user.name) | |
robot.respond /シャッフルランチ\s?参加/, (res) => | |
if !@_collector.waiting() | |
return | |
msg = if @_collector.addMember(res.message.user.name) then '分かりました🌟' else '知ってます🤘' | |
res.send(msg) | |
robot.respond /シャッフルランチ\s?不参加/, (res) => | |
if !@_collector.waiting() | |
return | |
msg = if @_collector.deleteMember(res.message.user.name) then '分かりました😢' else '知ってます😤' | |
res.send(msg) | |
robot.respond /シャッフルランチ\s?キャンセル/, (res) => | |
if !@_collector.waiting() | |
return | |
@_collector.stopWaiting() | |
res.send('シャッフルランチをキャンセルしました') | |
_groupMembers: (members) -> | |
maxNumberOfMembersInGroup = 5 | |
if members.length <= maxNumberOfMembersInGroup | |
return [ | |
members | |
] | |
random = members.map(Math.random) | |
members.sort((a, b) => | |
return random[a] - random[b] | |
) | |
numberOfGroups = Math.ceil(members.length / maxNumberOfMembersInGroup) | |
step = members.length / numberOfGroups | |
return [0...numberOfGroups].map((index) => | |
start = Math.floor(step * index) | |
end = Math.floor(step * (index + 1)) | |
return members.slice(start, end) | |
) | |
module.exports = (robot) -> | |
(new ShuffleLunchAdmin()).startObserving(robot) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
res.message.user.name
がユニークかどうかは要調査