前澤さんの総額1億円キャンペーン参加者500万人を取得してみた

<img width="1559" alt="スクリーンショット 2019-01-09 1.13.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/33011/d5638972-ca44-ad21-0ccf-47fcd90263c2.png">

[総額1億円のお年玉キャンペーン](https://twitter.com/yousuck2020/status/1081544630754103296)の参加者が540万人を突破し、リツイート数の世界記録を塗り替えたそうです。（現時点で5,471,482人）

抽選方法は公開されていませんが、社内の担当者はどうやって当選者を選ぶのでしょうか。そもそも、500万人以上のプロフィールをマーケ担当者（それとも本人？）はどうやって取得するのでしょうか。

たまに大規模なユーザー調査等を見かけますが、大半はサンプリング調査しかやっておらず、500万人分のデータを取得（と分析）するとなれば、これだけでも世界初（？）になるかもしれません。

このように興味の種は尽きないため、自分で参加者のデータを500万人分取得してみました。本記事ではその方法を解説します。

**結果だけを見たい方へ**

書いたコードはこれだけです。後は[twitter_friendly gem](https://github.com/ts-3156/twitter_friendly)がうまいことやってくれます。

```ruby
#!/usr/bin/env ruby

require 'twitter_friendly'

client =
    TwitterFriendly::Client.new(
        consumer_key: 'CONSUMER_KEY',
        consumer_secret: 'CONSUMER_SECRET',
        access_token: 'ACCESS_TOKEN',
        access_token_secret: 'ACCESS_TOKEN_SECRET',
        expires_in: 86400 # 1day
    )

ids = []

begin
  ids = client.follower_ids('yousuck2020')
rescue Twitter::Error::TooManyRequests => e
  sleep client.rate_limit.follower_ids[:reset_in]
  retry
end

puts "ids #{ids.size}"
File.write('ids.txt', ids.join("\n"))
```

実行結果は[参加者一覧のダウンロード](https://github.com/ts-3156/yousuck_followers)から見ることができます。

**参考：リツイート数の世界記録**
これまでの記録は355万人、今回の前澤さんの記録は540万人以上。ついでに、これまでの日本記録は50万件ほどらしい。

## 500万人のデータを取得する（失敗例）

500万人分のデータを取得するとなると、普通の方法ではなかなかうまくいきません。思いつく方法と、それが駄目な理由を順に説明します。

### ツイッター検索API

誰でも思いつく方法ですが、実はまったくうまくいきません。[公式ドキュメント](https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets.html)に記載されている通り、そもそも全ツイートを取得することはできず、遡れる時間は7日間までと限定されているためです。（この時間的制約がけっこうきつい）
さらに、一度の検索で取得できるツイートは最大100件なので、500万以上のツイートを検索するには膨大な数のAPIアクセスが必要になり、まったく現実的ではありません。

### あるツイートのリツイートを取得するAPI

2014年頃のAPI仕様変更により、先頭の100人までしか取得できなくなっています。そのため、今回の用途に使うことはできません。
ちなみに、数年前にリツイート数を集計するアプリが大量に消えたのは、この仕様変更の影響です。

### 有料のAPI（旧Firehose）

まず、約1億500万円/年ほどと言われる利用料を払わないと使うことができません。そのため、で今回は試してみるこことができませんでした。

### 統計学的な知識の利用

ツイッターの日本での月間アクティブユーザーは約4500万人、今回の応募者は約500万人、つまり日本全体のおよそ10%が参加しているので、任意のユーザーを選べば、今回の応募者である確率はそれなりにありますし、数学的に定式化することも可能です。
ただし、それでは全参加者の取得とは趣旨が異なります。さらに、「数学とかどうでもいいから！ 吟味して選びたいから全員リストアップしといて！」みたいな話は現実的によくあるので、今回はなしとします。

## 500万人分のデータを取得する（成功例）

これまでに挙げた方法はすべて、ツイートの取得に焦点を当てており、これが原因でうまくいきません。おそらく、次に挙げる方法が唯一の解決策です。

### フォロー・フォロワーのID一覧を取得するAPIを利用する

「リツイートしたデータを集める」という目的に対して遠回りのように見えますが、実はこれが唯一うまくいく方法です。その理由は、[フォロー・フォロワーのID一覧を取得するAPI](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids.html)は1回で5000人分のデータを取得することができるためです。

今回のキャンペーンの参加者はリツイートと同時に前澤さんのアカウントをフォローしているはずなので、「フォロワーの一覧をまず取得し、次にリツイートの有無をチェックする」という方針を取ることができます。

今回の用途に限らず、ツイッターから何かデータを取得しようと思った場合、まずはフォロー・フォロワーの取得から始めてみることをおすすめします。
ユーザーのID一覧さえ取得できてしまえば後はゆっくり各プロフィール情報を取得するなりフォロー構造を分析するなりすることができます。

長々と書きましたが、今回使ったコードはこれだけです。後は[twitter_friendly gem](https://github.com/ts-3156/twitter_friendly)がうまいことやってくれます。

```ruby
#!/usr/bin/env ruby

require 'twitter_friendly'

client =
    TwitterFriendly::Client.new(
        consumer_key: 'CONSUMER_KEY',
        consumer_secret: 'CONSUMER_SECRET',
        access_token: 'ACCESS_TOKEN',
        access_token_secret: 'ACCESS_TOKEN_SECRET',
        expires_in: 86400 # 1day
    )

ids = []

begin
  ids = client.follower_ids('yousuck2020')
rescue Twitter::Error::TooManyRequests => e
  sleep client.rate_limit.follower_ids[:reset_in]
  retry
end

puts "ids #{ids.size}"
File.write('ids.txt', ids.join("\n"))
```

## あとがき

今回の当選者には、アカウントが実名、アイコンが本人の実写、当選金の利用目的が明確という特徴が多く見られたそうです。[参考記事](https://jisin.jp/entertainment/entertainment-news/1700212/)

やっぱり現実的には、直近の何人か気になる人を見て100人選んだ（つまり、前半の数百万人は完全に選考外）という感じなんでしょうか。もし[第二弾が実施](https://twitter.com/yousuck2020/status/1082532240947478528)される際は選考をお手伝いしますので、スタートトゥデイのマーケ担当の方はお気軽にご連絡ください。( ^^) _U~~

また、「ツイッターからこんなデータを取得してほしいんだけど」みたいな要望がある方がいましたら、こちらもお気軽にご連絡ください。