拙いコードですがRubyとTwitterでなんかしたいなんて思ってる人の参考になればと思います。
※2015/06/21 説明を部分的に編集しました。(内容は変わっていません)
登録
まずTwitterAPIを使うためにアプリケーションの登録をするのですが、以下のサイトがとてもわかりやすかったです。
Twitter APIの使い方 アプリケーションの登録
こちらでもかいつまんで簡単に説明すると、以下のリンクへ行ってBotにしたいアカウントでログインします。
https://dev.twitter.com/
アプリケーションの名前はクライアント名として表示されるので重要ですが、それ以外(説明やWebsite)は適当でいいと思います。
↓
アプリを作るボタンを押したらいろいろ設定する画面に行くのですが、Permissionsの設定でアクセスレベルを必ず「Read and Write」以上にしてください。設定の変更が反映されるまで数分かかるので更新されるまで待ちます。
↓
更新されたらAPIkeysのタブを選択し、一番下にある[Create my access token]ボタンを押します。(これも押したあと更新まで数分待ちます。)
その後ページに表示された
・API key
・API secret
・Access token
・Access token secret
をどこかにメモって大切に管理してください。
これで登録の手順は終了です。
Ruby Gem
今回使用するGemは以下のふたつです。
github twitter
github tweetstream
$ gem install twitter $ gem install tweetstreamで導入可能ですが、特にTwitterのGemの方がバージョンアップでキーを設定する部分がコロコロ変更されるので、ちょくちょくソースのページを確認しにいったりバージョンを意識して使うとよいかと思います。(Gemfileでバージョンを指定しておくとか)
ちなみに今使っているのは
twitter(5.11.0)
tweetstream(2.6.1)
で、以下もそのバージョンを使った紹介になります。
RubyでBotを書く
これから
- config.yml
- bot.rb
- reply.rb
config.yml
これは先ほど取得したキーを書いておくファイルです。ファイルを分けておくとコードを公開するときこれだけ除外すればよいし、今後何かと便利です。
api_key: xxxxxxxx api_secret: xxxxxxxx access_token: xxxxxxxx access_token_secret: xxxxxxxxxxxxxxxxには自分のものを書いてください。
bot.rb
このファイルには、Botクラスを書いておきます。ふたつのgemを簡単に扱えるようにしたものですが、クラスのまとめ方は人それぞれだと思うので参考までに。
# coding:utf-8 require 'yaml' require 'twitter' require 'tweetstream' class Bot attr_accessor :client, :timeline def initialize keys = YAML.load_file('./config.yml') @client = Twitter::REST::Client.new do |config| config.consumer_key = keys["api_key"] config.consumer_secret = keys["api_secret"] config.access_token = keys["access_token"] config.access_token_secret = keys["access_token_secret"] end TweetStream.configure do |config| config.consumer_key = keys["api_key"] config.consumer_secret = keys["api_secret"] config.oauth_token = keys["access_token"] config.oauth_token_secret = keys["access_token_secret"] config.auth_method = :oauth end @timeline = TweetStream::Client.new end def post(text = "", twitter_id:nil, status_id:nil) if status_id rep_text = "@#{twitter_id} #{text}" @client.update(rep_text, {:in_reply_to_status_id => status_id}) puts "#{rep_text}" else @client.update(text) puts "#{text}" end end def fav(status_id:nil) if status_id @client.favorite(status_id) end end def retweet(status_id:nil) if status_id @client.retweet(status_id) end end end
reply.rb
Botクラスを使用する実行ファイルです。
以下のコード例では
- 「おーい」とつぶやくと、Botがそのつぶやきをリツイートしリプライをする
- 「ほげ」とリプライを送ると、Botがそのつぶやきをお気に入り登録しリプライをする
#!/usr/bin/env ruby # coding:utf-8 require './bot.rb' bot = Bot.new begin bot.timeline.userstream do |status| twitter_id = status.user.screen_name name = status.user.name contents = status.text status_id = status.id # リツイート以外を取得 if !contents.index("RT") str_time = Time.now.strftime("[%Y-%m-%d %H:%M]") # botを呼び出す(他人へのリプを無視) if !(/^@\w*/.match(contents)) if contents =~ /おーい/ text = "はい\n#{str_time}" bot.retweet(status_id:status_id) bot.post(text, twitter_id:twitter_id, status_id:status_id) end end # 自分へのリプであれば if contents =~ /^@hoge\s*/ if contents =~ /ほげ/ text = "ほげほげ\n#{str_time}" bot.fav(status_id:status_id) bot.post(text, twitter_id:twitter_id, status_id:status_id) end end end sleep 2 end rescue => em puts Time.now p em sleep 2 retry rescue Interrupt exit 1 end
reply.rbについて
実行ファイルで何をやっているかを簡単に書きます。何気に行番号が対応してたりします。
タイムラインの取得
botというインスタンスを生成したら、下記のブロックがタイムラインが流れる度に処理されます。
bot.timeline.userstream do |status| # タイムラインが流れる度に処理される end
ブロック変数
次に、statusと名前をつけたブロック変数ですが、下記のような情報を得ることができます。ツイート自体のIDというのはつぶやきごとに与えられたIDで、これを使ってリプライやふぁぼ、リツイートを行います。
(この他の情報も得ることができますが、とりあえずはこれくらいで大丈夫だと思います)
twitter_id = status.user.screen_name #アカウントのID name = status.user.name # アカウントの名前 contents = status.text # つぶやき内容 status_id = status.id # ツイート自体のID
リツイートに反応しないようにする
これは好みの問題ですが、リツイートしたものの中に反応ワードが入っているとBotが反応してしまうので、除外します。
公式リツイートを取得した場合、contentsは 「RT @リツイートされたカウントのID: 内容」 という文字列になるため、contents.index("RT") は普通のツイートである場合 nil を、リツイートである場合 0 を返すことになります。よって、nil は false、0 は trueであるため !contents.index("RT") はリツイート以外のときtrueとなり、それ以降の処理をします。ちょっとややこしいですね。
(実は status.retweeted_status とかでも判断できたりする)
# リツイート以外を取得 if !contents.index("RT")
自分以外へのリプライを除外
自分以外のアカウントへのリプライに呼び出しワードが含まれていた場合、それに反応するのを防ぎます。先頭に@があって以降[a-zA-Z0-9_]が続いているものを除外しています。
このif文中でさらにもうひとつの条件、「おーい」という文字にマッチすればそのツイートはBotによってリツイートされ、「はい\n#{str_time}」というリプライが返ってくるという処理がされます。
# botを呼び出す(他人へのリプを無視) if !(/^@\w*/.match(contents))
自分へのリプライには反応する
一方、自分へのリプには反応したいので、別のif文を用意します。(@hogeにはBotのIDを入れてください。)
このif文中でさらにもうひとつの条件、「ほげ」という文字にマッチすればそのツイートはBotによってふぁぼられ、「ほげほげ\n#{str_time}」というリプライが返ってくるという処理がされます。
# 自分へのリプであれば if contents =~ /^@hoge\s*/
各メソッドについて
bot.rbでつくった各メッソドについて、postメソッドを例にとって説明します。
postメソッドにはつぶやく内容と、相手のアカウントIDとそのつぶやき自体のIDを渡しています。リプライでなければ status_id は不要ですが、このIDを与えることにより、お馴染み「会話を表示」などでリプライが繋がります。
fav、retweetメッソドでも同様にこのつぶやきのIDを与えることでふぁぼやリツイートを行います。
bot.post(text, twitter_id:twitter_id, status_id:status_id)
最後に
拙いコードで、わかりづらい部分もあったかと思いますが最後まで読んでいただきありがとうございました。
もし説明が間違ってる箇所等ありましたらご指摘ください。
また自分はRubyでBotを作成するにあたって
大五郎(U^ω^)BOTを参考にさせていただきました。
この場を借りてお礼申し上げます。ありがとうございました。
ついでに私が書いたBotも紹介だけしておきます。
→OE_bot
機能としてはある部屋の入退室管理なので、完全に身内ものになっていて関係者以外がフォヨーしても意味がありませんが、もしよければコードだけでも見てみて、これまたご指摘等お待ちしております。
0 件のコメント:
コメントを投稿