Ruby を用いて userstream に対応した Twitter bot を作る

  • 26
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

動作環境

  • OS: FreeBSD 10.0-RELEASE-p7 GENERIC (uname -sri)
  • ruby: 2.1.2 (rbenv install 2.1.2)
  • rbenv: 0.4.0-98-g13a474c (rbenv --version)
  • ruby-build: 20140702 (rbenv install --version)
  • 使う gem: sferik/twitter - Github (5.11.0)

前提

sstephenson/rbenv, sstephenson/ruby-build
を用いて Ruby を入れていますが、システムの Ruby を用いて gem を入れる方法でも適用できると思います。

FreeBSD で動作の確認を行っていますが、その他の OS でもこの方法は適用できると思います。
FreeBSD でやる場合は devel/git, devel/gmake が必要なので、入れておいてください。

rbenv, ruby-build, ruby, gem のインストール

公式のドキュメント (rbenv, ruby-build) 通りに従ってインストールを行います。

% git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
% git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
% echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc #=> 使用している shell によって変えてください
% echo 'eval "$(rbenv init -)"' >> ~/.zshrc
% source ~/.zshrc
% rbenv install 2.1.2 #=> FreeBSD の場合は gmake がないとここでコケる
% rbenv global 2.1.2
% gem install twitter

ルート証明書のインストール

SSL 証明書をインストールして Ruby が分かるようにしてあげないと例外を吐いて死ぬので、
http://curl.haxx.se/docs/caextract.html のリンクにある、証明書を設置し、
そのファイルへのパスを環境変数の SSL_CERT_FILE に設定します。
(もしくは Ruby プログラム内で ENV["SSL_CERT_FILE"] = "/path/to/ssl" と書く。)
# そもそも何でこのようなエラーが出るのか、探してもあまり無いようなので、教えていただきたいです。

% wget http://curl.haxx.se/ca/cacert.pem -O /path/to/ssl
#=> or https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt
% echo 'export SSL_CERT_FILE="/path/to/ssl"' >> ~/.zshrc

実際に使ってみる

基本的に README とか rdoc とか読めば API の扱い方が分かると思います。
どんな API があるかは Twitter Developers の API 系のドキュメントを読めば分かると思います。

require "twitter"
ENV["SSL_CERT_FILE"] = "/path/to/ssl"

CONSUMER_KEY       = '<Your Consumer Key>'
CONSUMER_SECRET    = '<Your Consumer Secret>'
OAUTH_TOKEN        = '<Your OAuth Token>'
OAUTH_TOKEN_SECRET = '<Your OAuth Token Secret>'

client_rest = Twitter::REST::Client.new do |config|
  config.consumer_key        = CONSUMER_KEY
  config.consumer_secret     = CONSUMER_SECRET
  config.access_token        = OAUTH_TOKEN
  config.access_token_secret = OAUTH_TOKEN_SECRET
end

client_stream = Twitter::Streaming::Client.new do |config|
  config.consumer_key        = CONSUMER_KEY
  config.consumer_secret     = CONSUMER_SECRET
  config.access_token        = OAUTH_TOKEN
  config.access_token_secret = OAUTH_TOKEN_SECRET
end

client_stream.user do |object|
  # ここに userstream が流れてくる
end

サンプルコード

userstream で流れてくるツイートを取得してその情報を表示する

client_stream.user do |object|
  if object.is_a?(Twitter::Tweet)
    puts object.user.screen_name
      #=> ツイートしたユーザの screen name (e.g.: owatan_)
    puts object.text
      #=> ツイート本文 (e.g.: うさちゃん、うさちゃん、ぴょんぴょんぴょーん♪)
    puts object.id
      #=> ツイートの ID (e.g.: 497366451490021376)
    puts object.user.name
      #=> ツイートしたユーザの名前 (e.g.: おわたん)
    puts object.source
      #=> ツイートしたクライアント
      #=> e.g.: <a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>
      #=> a 要素が入っているので、クライアント名だけを抽出したい時は以下のように #gsub を使うと良い
    puts object.source.gsub(/(<a href=".*" rel=".*">)(.*)(<\/a>)/, '\2')
      #=> ツイートしたクライアント名(e.g.: YoruFukurou)
  end
end

正規表現にマッチしたツイートに対して reply, favorite, retweet をする

client_stream.user do |object|
  if object.is_a?(Twitter::Tweet)
    if object.text =~ /おはよう/
      client_rest.update("@#{object.user.screen_name} おはようございます", options = {in_reply_to_status_id: object.id})
        #=> "おはよう" という文字列が含まれているツイートに対して "おはようございます" と reply をする
    end

    if object.text =~ /ふぁぼ/
      client_rest.favorite(object.id)
        #=> "ふぁぼ" という文字列が含まれているツイートをお気に入りに追加する
    end

    if object.text =~ /りついーと/
      client_rest.retweet(object.id)
      #=> "りついーと" という文字列が含まれているツイートをリツイートする
    end
  end
end

サンプルコードは随時追加していきます ... 。