年の瀬ですがみなさんいかがお過ごしでしょうか。
私は冬コミに1日目2日目と参加してきて足と腰と肩がバッキバキになりました。運動不足はダメですね。
この記事をご覧の方で参加されている方はどれくらいいらっしゃるでしょうか。
戦場の有明
コミケに参加する上で気になるのは、やっぱり目的とする品を購入できるか否かですよね。
自分みたいに同人誌を買いに回りに回った後で企業ブースに行ったりしていると、当日分が完売していないだろうかと心配になります。企業でなくとも人気サークルさんのところも怖くなりますね。
販売情報を素早く得たい
というわけで、Twitterのリアルタイム性を利用して、「在庫状況に関係ありそうなツイート」をSlack経由で通知するスクリプトを勉強がてら書きました。
能動的にツイートを見に行かずとも通知が来るので余裕が出るかなーと思います。
これを思った時には既に待機列中だったので、ConnectBotでUbuntu14.04の入った自宅マシンに繋いでいじいじしてました。
メモ書きレベルですが何かの参考になれば幸いです。
実装
SlackにPostする
まずはターゲットとなるチャンネルへのエンドポイントを作ります。
こちらの投稿にしたがって作成し、Webhook URL
をメモしておきます。
さて、このエンドポイントを叩くわけですが、勉強も兼ねて直接コーディングします。
今回はこちらの投稿を参考に書きました。
require 'net/http'
require 'json'
class SlackClient
def initialize(url)
@url = url
end
def post(text)
data = { "text" => text }
request_url = @url
uri = URI.parse(request_url)
Net::HTTP.post_form(uri, { "payload" => data.to_json })
end
end
Twitter APIを叩く
Slackの次はTwitterのAPIにアクセスします。
Slackと異なり、TwitterAPIの利用にはOAuth認証が必要ですので、事前にアプリ作成によってトークンを取得しておきます。
コーディングはGemに頼ってしまいましょう。
$ gem install twitter
require 'twitter'
token = {
consumer_key: 'xxxx',
consumer_secret: 'xxxx',
access_token: 'xxxx',
access_token_secret: 'xxxx'
}
@rest = Twitter::REST::Client.new(token)
@stream = Twitter::Streaming::Client.new(token)
見たとおり、Twitterのアプリ管理から作成したトークンをベタ書きしただけのファイルです。
pryなんかでrequire_relativeしてすぐに叩けるので、APIをいじったり動作確認したいときによく使っています。
メイン部分を書く
とりあえずStreamingAPI使ってこんな感じに。
require_relative 'twutil'
require_relative 'slack_client'
@target_sns = %w(foo bar)
@slack = SlackClient.new("https://hooks.slack.com/services/xxxx/xxxx/xxxx")
begin
puts "Connecting to streaming server..."
@stream.user do |st|
next unless st.kind_of?(Twitter::Tweet)
next if st.retweeted_status?
next unless @target_sns.include?(st.user.screen_name)
@slack.post(st.url.to_s) if st.text =~ /\d限|限数|わずか|[減少]|残り|完売|売り?切れ?/
puts "#{st.text} from @#{st.user.screen_name}"
end
rescue EOFError
puts "Connection lost at #{Time.now}"
retry
end
Slackのインライン展開に任せて、正規表現で関係ありそうなワードとマッチすればそのURLを通知しています。
また、販売状況以外にも、/色紙|ポスター|抽選/
などとすれば、サークルさんの色紙・ポスター抽選の結果も見逃しを防止できるかと思います。
最後はEOFErrorでコネクションが失われることがあるので例外処理を入れています。
使う
コミケ会場の回線は安定しているとは限らないので、コネクション消失時に停止しないようにtmux上で走らせていました。
マナーモードにした携帯を胸ポケットに入れておけばブーブー震えていい感じに。
最後に
3つのファイルを作成しましたが、個人的には~/fragment
配下に置いています。その名の通り、プロジェクトというほどの規模でもないスクリプトを書き捨てたりしていますが、こういうものはみなさんどのようにしているのか気になります。
あとコードとか英語とか雑なので適切な形など教えて頂けると喜びます。