読者です 読者をやめる 読者になる 読者になる

みんなのちからになりたい

コピペでブログラムつくっていきたい

rubyでEmbedded Tweetsをいろいろやる

ruby

twitterの規約変わってtweetを表示するときはこうしろとかめんどくさくなったんだけど、その他を押すとembed用のコードが出てきてそれを貼るだけでかっこいい表示になる。

これをコピって
f:id:ginzanomama:20130404170331p:plain

htmlに貼るとこうなる。
f:id:ginzanomama:20130404170340p:plain

これを動的にやりたいときってまさかあのテンプレをreplaceしてやるのかなあと思って探したら、oEmbedってフォーマットでやり取りできるっぽい。

Embedded Tweets | Twitter Developers
oEmbed

ちなみにさっきのやつはこれを投げればJSONで返ってくる。

https://api.twitter.com/1/statuses/oembed.json?id=319648428621692928&lang=ja

{"type":"rich","height":null,"author_name":"\u30ac\u30c1\u30e3\u30d4\u30f3\u3010Gachapin\u3011","author_url":"https:\/\/twitter.com\/GachapinBlog","url":"https:\/\/twitter.com\/GachapinBlog\/status\/319648428621692928","html":"\u003Cblockquote class=\"twitter-tweet\" lang=\"ja\"\u003E\u003Cp\u003E\u3042\u30fc\uff01 \u30e0\u30c3\u30af\u304c\u307c\u304f\u306e\u304a\u306b\u304e\u308a\u98df\u3079\u305f\uff01 \u6fc0\u304a\u3053\u3077\u3093\u3077\u3093\u4e38 (\u2267\u30d8\u2266)\uff89\u003C\/p\u003E— \u30ac\u30c1\u30e3\u30d4\u30f3\u3010Gachapin\u3011\u3055\u3093 (@GachapinBlog) \u003Ca href=\"https:\/\/twitter.com\/GachapinBlog\/status\/319648428621692928\"\u003E2013\u5e744\u67084\u65e5\u003C\/a\u003E\u003C\/blockquote\u003E\n\u003Cscript async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"\u003E\u003C\/script\u003E","cache_age":"31536000000","version":"1.0","width":550,"provider_name":"Twitter","provider_url":"http:\/\/twitter.com"}

ということで、apiにtweetのid投げてそれを取ってくるやつを作ってみようと思う。

rubyでhttpのやり取りをするほうほうをぐぐると標準で用意されてた。

library net/http

これでもいいんだけどなんか他にないかなあと思ってぐぐったらいいのがみつかった。

Ruby の HTTP クライアントライブラリ Faraday が便利そう

Faradayっていうのが便利らしい。

というわけでやってみる。

require "bundler/setup"

require "faraday"
require "faraday_middleware"

id = 319648428621692928
url = "https://api.twitter.com/1/statuses/oembed.json?id=#{id}&lang=ja"
conn = Faraday.new(url: url) do |builder|
  builder.request  :url_encoded
  builder.response :logger
  builder.response :json, :content_type => /\bjson$/
  builder.adapter Faraday.default_adapter
end

p response: conn.get.body


$ruby embedded.rb
I, [2013-04-04T16:04:24.078125 #5912]  INFO -- : get https://api.twitter.com/1/statuses/oembed.json?id=319648428621692928&lang=ja
D, [2013-04-04T16:04:24.078125 #5912] DEBUG -- request: User-Agent: "Faraday v0.8.7"
C:/Ruby193/lib/ruby/1.9.1/net/http.rb:799:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (Faraday::Error::ConnectionFailed)
        from C:/Ruby193/lib/ruby/1.9.1/net/http.rb:799:in `block in connect'
        from C:/Ruby193/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
        from C:/Ruby193/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
        from C:/Ruby193/lib/ruby/1.9.1/net/http.rb:799:in `connect'
        from C:/Ruby193/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
        from C:/Ruby193/lib/ruby/1.9.1/net/http.rb:744:in `start'
        from C:/Ruby193/lib/ruby/1.9.1/net/http.rb:1284:in `request'
        from C:/Ruby193/lib/ruby/1.9.1/net/http.rb:1026:in `get'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.7/lib/faraday/adapter/net_http.rb:73:in `perform_request'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.7/lib/faraday/adapter/net_http.rb:38:in `call'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:30:in `call'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.7/lib/faraday/response.rb:8:in `call'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.7/lib/faraday/response/logger.rb:20:in `call'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.7/lib/faraday/request/url_encoded.rb:14:in `call'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.7/lib/faraday/connection.rb:247:in `run_request'
        from C:/workspace/embeddedtweets/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.7/lib/faraday/connection.rb:100:in `get'
        from embedded.rb:15:in `<main>'

盛大に怒られた。

SSLがどうのこうのと言われてるのでぐぐると、証明書がないからっぽい。

証明書の入れ方

OpenSSL Errors and Rails – Certificate Verify Failed – Gem::RemoteFetcher::FetchError · RailsApps

会社ではwindows使ってるのでこっちの方法でやってみた。

Download a cacert.pem for RailsInstaller

Rails Installer入れるのだるいんでマニュアルでやった。

  • http://curl.haxx.se/ca/cacert.pem をダウンロードして C:\RailsInstaller に入れる
  • DOS窓で set SSL_CERT_FILE=C:\RailsInstaller\cacert.pem をぶっ叩く
  • 恒久的にセットしたいときは詳細設定の環境設定で設定する

再チャレンジ。

$ruby embedded.rb
I, [2013-04-04T16:13:00.203125 #4256]  INFO -- : get https://api.twitter.com/1/statuses/oembed.json?id=319648428621692928&lang=ja
D, [2013-04-04T16:13:00.218750 #4256] DEBUG -- request: User-Agent: "Faraday v0.8.7"
I, [2013-04-04T16:13:02.046875 #4256]  INFO -- Status: 200
D, [2013-04-04T16:13:02.046875 #4256] DEBUG -- response: cache-control: "no-cache, no-store, must-revalidate, pre-check=0, post-check=0"

~

status: "200 OK"
strict-transport-security: "max-age=631138519"
vary: "Accept-Encoding"
x-frame-options: "SAMEORIGIN"
x-mid: "df1633d9433080370d4084e36c896c26139fbd80"
x-ratelimit-class: "api"
x-ratelimit-limit: "150"
x-ratelimit-remaining: "141"
x-ratelimit-reset: "1365062198"
x-runtime: "0.01902"
x-transaction: "e18c942d381bd67c"
x-transaction-mask: "a6183ffa5f8ca943ff1b53b5644ef114c83181ff"
connection: "close"
{:response=>{"html"=>"<blockquote class=\"twitter-tweet\" lang=\"ja\"><p>\u3042\u30FC\uFF01 \u30E0\u30C3\u30AF\u304C\u307C\u304F\u306E\u304A\u306B\u304E\u308A\u98DF\u3079\u305F\uFF01 \u6FC0\u304A\u3053\u3077\u3093\u3077\u3093\u4E38 (\u2267\u30D8\u2266)\uFF89</p>&mdash; \u30AC\u30C1\u30E3\u30D4\u30F3\u3010Gachapin\u3011\u3055\u3093 (@GachapinBlog) <a href=\"https://twitter.com/GachapinBlog/status/319648428621692928\">2013\u5E744\u67084\u65E5</a></blockquote>\n<script async src=\"//platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>", "type"=>"rich", "cache_age"=>"31536000000", "author_url"=>"https://twitter.com/GachapinBlog", "provider_name"=>"Twitter", "version"=>"1.0", "provider_url"=>"http://twitter.com", "width"=>550, "author_name"=>"\u30AC\u30C1\u30E3\u30D4\u30F3\u3010Gachapin\u3011", "height"=>nil, "url"=>"https://twitter.com/GachapinBlog/status/319648428621692928"}}

できた、すばらしい。

これをerbのテンプレートに読ませて表示してみる。
テンプレはこんなの。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="keywords" content="">
  <meta name="description" content="">
</head>

<body>

  <%= @tweets %>

</body>

</html>

動かす。

require "bundler/setup"

require "faraday"
require "faraday_middleware"
require "erb"

id = 319648428621692928
url = "https://api.twitter.com/1/statuses/oembed.json?id=#{id}&lang=ja"
conn = Faraday.new(url: url) do |builder|
  builder.request  :url_encoded
  builder.response :logger
  builder.response :json, :content_type => /\bjson$/
  builder.adapter Faraday.default_adapter
end

@tweets = conn.get.body["html"]

template = File.open("tweets.html.erb", 'r').read
erb = ERB.new(template)
File.open("tweets.html", 'w+') { |file| file.write(erb.result(binding)) }
puts "output done."

ちゃんと同じく表示された。
f:id:ginzanomama:20130404170340p:plain

勉強になる。