slackbotでRails製websocketサービスを叩いて非同期描画してみる
背景
春になり、新入生が自分の大学にも入ってきました。
今年度から自分が運営している団体も本格的に人を集めようと思い、気づいた時には40人ものニューフェイスが参加表明をしてくれました。
今日は、その人たちの為に作ったwebsocketサービスとslack botの連携について少しまとめられたらなと思います。
作ったもの
僕たちの団体に所属する人には、タイポでのバグ等最低限のミスをなくすために、「寿司打」というタイピングゲームの高級コースで一万点以上のスコアを取ることを課しています。
はじめは壁に書いていたのですが、人数が増えてきておさまらなくなってきたので、じゃあWebに置き換えるついでに表題という感じです。
はじめは上のように更新したらマーカーで書き換えてましたが、
いまは上記のようにWeb上で管理できています。
slack上で、当団体の電脳ペットである「taro」に申告することで、自動で順位を計算し描画しなおしてくれます。
websocketを使っているので、更新ボタンを押さなくても、自動的に画面が切り替わってくれるのが嬉しいところです。
実装方法
オーバースペックかもしれませんが、websocket-rails
を使いました。
websocket-rails
の使い方については他に譲るとして、実際にどのように通信したのかを説明します。実装方法としては、/websocket
にリクエストが走ると、client_connected
というイベントが呼ばれるので、curl
でそのURLを叩き処理を差し込んであげました。具体的には下記です。
class WebsocketSushidaController < WebsocketRails::BaseController
def initialize_session
puts "Session Initialized\n"
end
def client_connected #アクセスされると呼ばれる
puts "connected"
if params[:name]
if @user = User.find_or_create_by(name: params[:name])
if params[:screen_name]
@user.update(screen_name: params[:screen_name])
else
@score = Score.create(value: params[:score].to_i)
@score.user = @user
@score.save()
end
end
end
@users = User.all.map do |user|
@data = user.attributes
if @score = user.scores.last
@data[:score] = @score.value
else
@data[:score] = 0
end
@data
end
@users = @users.sort_by{|user| user[:score]}.reverse
broadcast_message :new_message, @users
end
end
huebotの方は以下の通りです
module.exports = (robot) ->
execSync = require('child_process').execSync
loadsh = require('lodash');
robot.respond /sushida score (\S+)$/, (msg) ->
if msg.match[1].match(/[0-9]+/)
score = msg.match[1]
update_score msg, msg.envelope.user.name, score
else
msg.send "変な値入れないでよ"
robot.respond /sushida name (\S+)$/, (msg) ->
if msg.match[1]
screen_name = msg.match[1]
update_name msg, msg.envelope.user.name, screen_name
else
msg.send "変な値入れないでよ"
update_score = (msg, name, score) ->
execSync 'timeout -sKILL 1 curl -X GET "http://example.com/websocket?' +"name=#{name}&score=#{score}\""
msg.send "#{name}さんの寿司打のスコアを更新したよ。#{score}円分も食べたんだね!すごい!!"
update_name = (msg, name, screen_name) ->
execSync 'timeout -sKILL 1 curl -X GET "http://example.com/websocket?' +"name=#{name}&screen_name=#{screen_name}\""
msg.send "#{name}さんの表示名を#{screen_name}に変えたよ"
taroには、クエリパラメータ付きのGETリクエストでアクセスしてもらっています。
/websocket?query=value
とすれば、controllerの方でparams[:query]
のデータを取り扱うことができます。
破壊的で、実際にサービスとして運用するのは難しいと思いますが、内部向けのトイサービスなのでこれで良しとしました。
一つ注意する点は、一度/websocket
にアクセスすると、コネクションを貼ってしまって、そのままhuebotが固まってしまいます。なので、timeout
を使い一秒で処理を強制終了させています。
暴力的ですが、簡単に実装ができるためお勧めです。
誰かの参考になればと思います。
Author And Source
この問題について(slackbotでRails製websocketサービスを叩いて非同期描画してみる), 我々は、より多くの情報をここで見つけました https://qiita.com/gamerinshaft/items/7ff2847cefd3ddfdce1c著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .