コメント付きRTが含まれるツイートを展開する

# コメント付きRTとは
2015年4月7日から、 Twitter で「コメント付き RT 」というのが使えると案内がありました。
<blockquote class="twitter-tweet" data-cards="hidden" lang="en"><p>ウェブとiPhoneの公式アプリをご利用の皆さん、他の方のツイートにコメントを付けてツイートできるようにしました。Android版ももうすぐご利用いただけるようになります。&#10;<a href="https://t.co/Xci9BDPFpA">https://t.co/Xci9BDPFpA</a> <a href="http://t.co/TB0Or1Lr9F">pic.twitter.com/TB0Or1Lr9F</a></p>&mdash; TwitterJP (@TwitterJP) <a href="https://twitter.com/TwitterJP/status/585238119210954752">April 7, 2015</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
その正体はといえば、単にツイート URL が含まれているツイートを [Twitter カード](https://dev.twitter.com/ja/cards/overview) に埋め込んでいるだけ ~~です~~ だと思われます。
具体例を Web 画面で見てみましょう。
[![スクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/19597/08eb9b59-a811-8df2-bc09-b353fa9caf7f.png)](https://twitter.com/riocampos/status/585278274814611456)

今までのクライアントで上記のツイートを見ると

> @riocampos: コメント付きRT機能って、単にツイートURLをツイートに埋め込んでるだけじゃないの？『コメントは116文字まで』つまりhttpsなURLの文字数23文字+空白1文字でしょ、きっと。 twitter.com/itm_nlab/statu…

のように見えます。

もちろん、コメント付き RT 対応のクライアントであっても、冒頭部分のみの引用なので、長文ツイートの場合にはやはりそのツイート自体を見にいかねばならないわけです。

# コメント付きRTを展開して一気に読みたい
いままでの非公式RTのように一画面で引用文とコメント文とを読みたい、と思いますよね？（私だけかな？）
それを実現するためのメソッドを書きました。

```rb
def expanded_text(tw, client)
  text = tw.full_text.dup
  url_index_ary = []
  unless tw.urls.empty? # ツイートにリンクが含まれているか
    exist_comment = false
    tw.urls.reverse.each do |t|
      exp_url = t.expanded_url.to_s #
      if exp_url[%r[^https://twitter.com/]] && !exist_comment # コメントRTのURL（一番後ろのツイートURLのみを対象にする）
        comment_account = exp_url[%r[(?<=^https://twitter.com/)[^/]+]]
        comment_id = exp_url[/\d+$/]
        comment_tw = client.status(comment_id) # 注意：上限値180回/15分
        comment_text = "RT @#{comment_account}: #{expanded_text(comment_tw, client)}"
        url_index_ary << [comment_text, t.indices]
        exist_comment = true
      else # 単なるURL
        url_index_ary << [exp_url, t.indices]
      end
    end
  end
  if t = tw.media.first # 写真・動画は現状一つしか埋め込まないので一つを取得
    url_index_ary << [t.display_url, t.indices]
  end
  url_index_ary.sort_by { |_, (from, to)| -from }.each do |txt, (from, to)|
    text[from..(to - 1)] = txt
  end
  text
end
```
# 使い方
まず Twitter API アクセスのためのクライアントインスタンス `client` を作ります。

```rb
client = Twitter::REST::Client.new(
  consumer_key:        'your_consumer_key',
  consumer_secret:     'your_consumer_secret',
  access_token:        'your_access_token',
  access_token_secret: 'your_access_token_secret',
)
```
目的のツイートのインスタンスを取得します。例えば上記のツイートであれば

```rb
tw = client.status(585278274814611456)
```
で得られます。
この二つのインスタンスを使って、展開したテキストを取得します。

```rb
expanded_text(tw, client)
#=> "コメント付きRT機能って、単にツイートURLをツイートに埋め込んでるだけじゃないの？『コメントは116文字まで』つまりhttpsなURLの文字数23文字+空白1文字でしょ、きっと。 RT @itm_nlab: Twitter、コメント付きで他人のツイートをRTできる機能導入 - ねとらぼ http://nlab.itmedia.co.jp/nl/articles/1504/07/news055.html @itm_nlabから pic.twitter.com/6anrksjp0T"
```

# 問題点
コメント付きRTがある毎に `Twitter::REST::Client#status` メソッドで Twitter API へアクセスするので API を消費します（一度アクセスしたツイートはクライアントインスタンスに保持されるので *必ず* ではないのですが）。しかも、コメント付きRTをコメント付きRTすると、二段階になるのでさらに一つ API を消費します。
スクリプト部分にも記載しましたが上限値は180回/15分です。
よって、Timelineや検索結果など `Twitter::Tweet` の配列を対象にする場合には、 API 規制を受ける可能性が高いです。 API 規制を避けるために、例えばコメント付き RT に必要なツイートの id を収集し、それをまとめて `Twitter::REST::Client#statuses` で一気に取得して、それぞれのツイートインスタンスの `expanded_text` を作る、ということを構想しています。