LoginSignup
12
12

More than 5 years have passed since last update.

RubyとSlackでライフハックならぬコミケハック

Last updated at Posted at 2015-12-30

年の瀬ですがみなさんいかがお過ごしでしょうか。

私は冬コミに1日目2日目と参加してきて足と腰と肩がバッキバキになりました。運動不足はダメですね。
この記事をご覧の方で参加されている方はどれくらいいらっしゃるでしょうか。

戦場の有明

コミケに参加する上で気になるのは、やっぱり目的とする品を購入できるか否かですよね。
自分みたいに同人誌を買いに回りに回った後で企業ブースに行ったりしていると、当日分が完売していないだろうかと心配になります。企業でなくとも人気サークルさんのところも怖くなりますね。

販売情報を素早く得たい

というわけで、Twitterのリアルタイム性を利用して、「在庫状況に関係ありそうなツイート」をSlack経由で通知するスクリプトを勉強がてら書きました。
能動的にツイートを見に行かずとも通知が来るので余裕が出るかなーと思います。

これを思った時には既に待機列中だったので、ConnectBotでUbuntu14.04の入った自宅マシンに繋いでいじいじしてました。
メモ書きレベルですが何かの参考になれば幸いです。

実装

SlackにPostする

まずはターゲットとなるチャンネルへのエンドポイントを作ります。
こちらの投稿にしたがって作成し、Webhook URLをメモしておきます。

さて、このエンドポイントを叩くわけですが、勉強も兼ねて直接コーディングします。

今回はこちらの投稿を参考に書きました。

slack_client.rb
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
twutil.rb
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上で走らせていました。
マナーモードにした携帯を胸ポケットに入れておけばブーブー震えていい感じに。

image

最後に

3つのファイルを作成しましたが、個人的には~/fragment配下に置いています。その名の通り、プロジェクトというほどの規模でもないスクリプトを書き捨てたりしていますが、こういうものはみなさんどのようにしているのか気になります。
あとコードとか英語とか雑なので適切な形など教えて頂けると喜びます。

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12