ha's notepad II

メモ書きです。

RubyでTwitterにポスト(未完)

Cygwin上で動作するRubyのスクリプトプログラムの中で、Twitterに動作状況をポストできるbotを作ろうと思って、少し調べてみた。

RubyでどのようにTwitterを使おうか調べた所、とても簡単なライブラリがあることを知った。

Twitter by sferik
こちらがそのライブラリ(Rubyではこういったライブラリをgemというようだ)の作者におる説明。Rubyはほとんど書いたことないが、これを見る限りとても簡単に扱えそうであった。
(gemに関しての説明はhttp://www.ruby-lang.org/ja/libraries/が詳しい)



http://rubyinstaller.org/downloads/

gemのインストールは簡単で、Cygwinのコンソールやコマンドプロンプトから、

$ gem install twitter

と打つだけで、必要なものが一式まとめてインストールできる。

まずOAuthでアプリの認証をする(このへんは別の記事で)。そして、最初に紹介したサイトにあるように、認証キーの設定をしてポストにチャレンジしてみる。
実際につぶやく部分は1行で済んでおり、ごくごく簡単にTwitterを活用できそうだ。

require 'rubygems'
require 'twitter'

Twitter.configure do |config|
  config.consumer_key = YOUR_CONSUMER_KEY
  config.consumer_secret = YOUR_CONSUMER_SECRET
  config.oauth_token = YOUR_OAUTH_TOKEN
  config.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
end

Twitter.update("rubytest")

これを適当なファイル名で保存し、Cygwinから実行してみたが・・・
・・・残念ながら、下のようなエラーが出てきた。

/usr/lib/ruby/1.9.1/net/http.rb:800:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (Twitter::Error::ClientError)
        from /usr/lib/ruby/1.9.1/net/http.rb:800:in `block in connect'
        from /usr/lib/ruby/1.9.1/timeout.rb:69:in `timeout'
        from /usr/lib/ruby/1.9.1/timeout.rb:100:in `timeout'
        from /usr/lib/ruby/1.9.1/net/http.rb:800:in `connect'
        from /usr/lib/ruby/1.9.1/net/http.rb:756:in `do_start'
        from /usr/lib/ruby/1.9.1/net/http.rb:745:in `start'
        from /usr/lib/ruby/1.9.1/net/http.rb:1285:in `request'
        from /usr/lib/ruby/gems/1.9.1/gems/faraday-0.8.7/lib/faraday/adapter/net_http.rb:75:in `perform_request'
(以下略)

Twitterは更新されていなかった。

エラーの文で調べてみると、どうも、SSL通信がうまくいっていないようだ。
SSL通信を行うために必要な証明書関連に問題があるらしい。


SSLの認証を切ったらどうなるか試すため、

require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

という宣言を入れてみたら・・・

/usr/lib/ruby/gems/1.9.1/gems/twitter-4.8.1/lib/twitter/response/raise_error.rb:21:in `on_complete': Could not authenticate you (Twitter::Error::Unauthorized)
        from /usr/lib/ruby/gems/1.9.1/gems/faraday-0.8.7/lib/faraday/response.rb:9:in `block in call'
        from /usr/lib/ruby/gems/1.9.1/gems/faraday-0.8.7/lib/faraday/response.rb:63:in `on_complete'
        from /usr/lib/ruby/gems/1.9.1/gems/faraday-0.8.7/lib/faraday/response.rb:8:in `call'
        from /usr/lib/ruby/gems/1.9.1/gems/faraday-0.8.7/lib/faraday/request/url_encoded.rb:14:in `call'
(以下略)

Could not authenticate you・・・そうですか・・・
これはうまく行かなさそうなので、大人しく証明書を何とかすることに。

まず、証明書がどこにあるのかをirbで調べてみた。

irb(main):001:0> require 'openssl'
=> true
irb(main):002:0> p OpenSSL::X509::DEFAULT_CERT_FILE
"/usr/ssl/cert.pem"
=> "/usr/ssl/cert.pem"

このディレクトリを確認したら、なんと"cert.pem"などというファイルが存在しない!

ここでTwitterSSL通信について、以下のサイトなどを参考にしてみた。
https://dev.twitter.com/docs/security/using-ssl
http://d.hatena.ne.jp/otherworld/20101020/1287551203
http://d.hatena.ne.jp/kesikaran/20100213/1266069166

あまりしっかり理解していないが、"VeriSign Class 3 Extended Validation"なる証明書が必要とされている模様。
そして、この証明書(と他色々な証明書がセットになったファイル)は

http://curl.haxx.se/ca/cacert.pem

からダウンロードできる模様。
ここから証明書を引っ張ってきて、あるべきディレクトリに放り込んだ。そしてbotを実行すると・・・

/usr/lib/ruby/gems/1.9.1/gems/twitter-4.8.1/lib/twitter/response/raise_error.rb:21:in `on_complete': Could not authenticate you (Twitter::Error::Unauthorized)
        from /usr/lib/ruby/gems/1.9.1/gems/faraday-0.8.7/lib/faraday/response.rb:9:in `block in call'

またかよ!ということは、この"Could not authenticate you"というエラーは、証明書関連とは別のところか。
認証がうまくいってないような気がする。

http://stackoverflow.com/questions/15146767/twitter-could-not-authenticate-you-error
http://stackoverflow.com/questions/17060459/how-do-i-retrieve-a-status-from-twitter-with-the-oauth-gem-directly
https://dev.twitter.com/docs/auth/oauth/single-user-with-examples#ruby
http://doruby.kbmj.com/daoka_tips/20100302/ruby_oauth_

ここらへんを見て、頭を抱え中。