EventMachineのつかいかたのはずだったけどStreamingするAPIの説明とか簡単なリプライbotの作り方とかになった
ServerSentEventを使って何かやってみたいなと思っていたのですが、結局TwitterのタイムラインをStreaming APIで読み取って、適当にリプライを返すbotになってしまいました。
Steaming APIの仕様
curlで読み取ってみるとこうなります。
curl --get 'https://userstream.twitter.com/1.1/user.json' --header 'Authorization: OAuth oauth_consumer_key="OauthConsumerKey", oauth_nonce="OauthNonce", oauth_signature="OauthSignature", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1388583567", oauth_token="OauthToken", oauth_version="1.0"' --verbose * Adding handle: conn: 0x000000000000 * Adding handle: send: 0 * Adding handle: recv: 0 * Curl_addHandleToPipeline: length: 1 * - Conn 0 (0x000000000000) send_pipe: 1, recv_pipe: 0 * About to connect() to userstream.twitter.com port 443 (#0) * Trying 199.59.148.139... * Connected to userstream.twitter.com (199.59.148.139) port 443 (#0) * TLS 1.2 connection using TLS_RSA_WITH_RC4_128_SHA * Server certificate: userstream.twitter.com * Server certificate: VeriSign Class 3 Secure Server CA - G3 > GET /1.1/user.json HTTP/1.1 > User-Agent: curl/7.30.0 > Host: userstream.twitter.com > Accept: */* > Authorization: OAuth oauth_consumer_key="OauthConsumerKey", oauth_nonce="OauthNonce", oauth_signature="OauthSignature", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1388583567", oauth_token="OauthToken", oauth_version="1.0" > < HTTP/1.1 200 OK < Connection: close < Transfer-Encoding: chunked < Content-Type: application/json < Date: Wed, 01 Jan 2014 13:39:57 GMT < {"friends":[ ... ]} {"created_at":"Wed Jan 01 13:40:01 +0000 2014", ... } {"created_at":"Wed Jan 01 13:40:02 +0000 2014", ... } {"created_at":"Wed Jan 01 13:40:05 +0000 2014", ... } {"created_at":"Wed Jan 01 13:40:08 +0000 2014", ... } ...
改行2つで区切られたものがデータのひとかたまりです。これが一度に投げてこられるわけですね。コネクションを張り続けている間、ずっとこういうデータが流れ続けてきます。これをEventMachineでいい感じにキャッチして、なんかしてみようというつもりだったのですが、よくわからないところではまってしまって無理でした。
結局リプライbotを作ってみた
結局、裏でStreaming APIを捌いているGemを見つけて、それでリプライが来たらなんかtweetするような感じのbotを動かせるようにしてみました。その前に試行錯誤と再三のフルスクラッチがありますが、だいたい30分くらいでできました。細かいところでつまずいて試行錯誤した割にはコードが短いので、Rubyの闇さと先人の偉大さが改めてわかりました。
require 'tweetstream' require 'twitter_oauth' CONSUMER_KEY = 'CONSUMER_KEY' CONSUMER_SECRET = 'CONSUMER_SECRET' OAUTH_TOKEN ||= 'OAUTH_TOKEN' OAUTH_TOKEN_SECRET ||= 'OAUTH_TOKEN_SECRET' def client TwitterOAuth::Client.new( consumer_key: CONSUMER_KEY, consumer_secret: CONSUMER_SECRET, token: OAUTH_TOKEN, secret: OAUTH_TOKEN_SECRET ) end TweetStream.configure do |config| config.consumer_key = CONSUMER_KEY config.consumer_secret = CONSUMER_SECRET config.oauth_token = OAUTH_TOKEN config.oauth_token_secret = OAUTH_TOKEN_SECRET config.auth_method = :oauth end TweetStream::Client.new.userstream do |status| if status.text.to_s[/^@yuu_hara/] begin tweet = "@#{status.user.screen_name} にゃーん" p client.update tweet if client.authorized? rescue Exception => e p e end end end
なんでこう細かいところではまりやすいのか、理由がわからないと今後苦労しそうですね…それはさておき、今年もよろしくお願いします。