放映中のアニメ公式 Twitterアカウントのフォロワー変動履歴情報を提供するRESTful API サーバーを作りました

現在放映されているアニメ作品の公式アカウントのフォロワー数をグラフ化するanime_followerというTwitterボットを作っています。
https://twitter.com/anime_follower


![CTYbAcsUEAA2Q-r.png-large.png](https://qiita-image-store.s3.amazonaws.com/0/36931/a0e14037-8602-12e1-5b2d-35800404ad63.png)


こんなの

また現在のフォロワー数だけでなく、一定期間のフォロワー増加数なんかもとっています。
![CTYUl3kUkAA2BMz.png](https://qiita-image-store.s3.amazonaws.com/0/36931/21c0fd74-e9b0-67b8-dfa4-f68b66078142.png)


Twitter APIではTwitterの現在のフォロワー数しかとれないので、フォロワー履歴をデータベースにためて、REST APIで取得できるAPIサーバーをElixir Phoenix + MySQLで作成しました。


https://github.com/Project-ShangriLa/sana_server_phoenix

今回は、サーバー側の実装でなくAPIの仕様とクライアントからの利用について紹介します。
・・がリアルに一般公開されているElixir Phoenix製のAPIサーバーとしてちょっとはElixirユーザーにも参考になると思います。

なおこの記事は以前のAnime APIの記事の追加APIについての紹介になりますのでこちらも参考にしてください。

[放映中のアニメ作品の情報を提供するAnime RESTful API サーバー作りました](http://qiita.com/AKB428/items/64938febfd4dcf6ea698)

![shangriLa.png](https://qiita-image-store.s3.amazonaws.com/0/36931/d0a79b38-275a-a87b-a44e-8a69c5b0c6ec.png)



## ShangriLa Anime Twitter API 仕様書

### 取り扱うデータ

2014年以降のアニメ作品
(※過去のも追加予定はあり)


### API Server ドメイン

http://api.moemoe.tokyo/

### 認証

V1では認証を行いません。


### レートリミット

なし

### GET /anime/v1/twitter/follower/status

リクエストで指定されたアニメ公式アカウントの最新のフォロワー数を返却します

#### Request Parameter

| Property     | Value               |description|Sample|
| :------------ | :------------------ |:--------|:-------|
| accounts    |String|対象のTwitterアカウントをカンマ区切りにしたもの|usagi_anime,kinmosa_anime|


#### Response Body

| Property     | Value               |description|Sample|
| :------------ | :------------------ |:--------|:-------|
| Request twitter_account 1|follower Object||"usagi_anime": {..}|
| Request twitter_account 2|follower Object||"kinmosa_anime": {..}|
| Request twitter_account X|follower Object||"lovelive_staff": {..}|

##### follower Object

| Property     | Value               |description|Sample|
| :------------ | :------------------ |:--------|:-------|
| follower    |Number|フォロワー数|12500|
| updated_at   |Number|データの更新日時 UNIX TIMESTAMP|1446132941|

#### レスポンス例

```
curl -v http://api.moemoe.tokyo/anime/v1/twitter/follower/status?accounts=usagi_anime,kinmosa_anime,aldnoahzero | jq .
```

```json
{
  "aldnoahzero": {
    "updated_at": 1432364949,
    "follower": 51055
  },
  "usagi_anime": {
    "updated_at": 1411466007,
    "follower": 51345
  },
  "kinmosa_anime": {
    "updated_at": 1432364961,
    "follower": 57350
  }
}
```



### GET /anime/v1/twitter/follower/history

リクエストで指定されたアニメ公式アカウントのフォロワー数の履歴を返却します。（最大100履歴）

#### Request Parameter


| Property     |Value |Required|description|Sample|
| :------------|:-----|:-------|:----------|:-----|
| account    |String|◯|対象のTwitterアカウント|usagi_anime|
| end_date |Number|-|unixtimestampで指定した日時より過去のデータを取得。指定がない場合は現在日時。 where updated_at < end_date |1446132941|


#### Response Body

| Property     | Value               |description|Sample|
| :------------ | :------------------ |:--------|:-------|
| Array Object|history Object Array|取得できない場合は空の配列|[]|


##### history Object

| Property     | Value               |description|Sample|
| :------------ | :------------------ |:--------|:-------|
| follower    |Number|フォロワー数|12500|
| updated_at   |Number|データの更新日時 UNIXTIMESTAMP|1446132941|

データは更新日時の降順でソートされ格納されています。

#### レスポンス例1

```
curl -v http://api.moemoe.tokyo/anime/v1/twitter/follower/history?account=usagi_anime | jq .
```

```json
[
  {
    "updated_at": 1411466007,
    "follower": 51345
  },
  {
    "updated_at": 1410674102,
    "follower": 50606
  },
  {
    "updated_at": 1410673804,
    "follower": 50607
  },
  {
    "updated_at": 1407743045,
    "follower": 46350
  }
]
```


#### レスポンス例2

```
curl "http://api.moemoe.tokyo/anime/v1/twitter/follower/history?account=usagi_anime&end_date=1407562541" | jq .
```

```json
[
  {
    "updated_at": 1407560663,
    "follower": 46165
  },
  {
    "updated_at": 1407558786,
    "follower": 46166
  },
  {
    "updated_at": 1407556908,
    "follower": 46162
  }
]
```

## クライアントからの利用方法 Ruby モジュール実装編

URLを叩くだけですが簡単なrubygemsを実装しrubygems.orgに配置しています

```ruby
require 'net/http'
require 'uri'
require 'json'
require 'httpclient'

module Shangrila

  class Sana
    URL = 'http://api.moemoe.tokyo/anime/v1/twitter'

    def initialize
    end

    # @param [Array] accounts データ取得対象のアニメTwitter公式アカウント
    # @return [Hash] アカウント群をキーとしたハッシュ
    def follower_status(accounts)
      response = HTTPClient.get(sprintf('%s/follower/status?accounts=%s', URL, accounts.join(',')))
      JSON.load(response.body)
    end

    # @param [Array] account データ取得対象のアニメTwitter公式アカウント
    # @param [int] end_date 検索対象の終了日時 where update_at < end_date)
    # @return [Array] フォロワー数と更新日時のハッシュの配列
    def follower_history(account, end_date = nil)
      response = nil
      if end_date.nil?
        response = HTTPClient.get(sprintf('%s/follower/history?account=%s', URL, account))
      else
        response = HTTPClient.get(sprintf('%s/follower/history?account=%s&end_date=%d', URL, account, end_date))
      end

      JSON.load(response.body)
    end

  end

end
```

## クライアントからの利用方法 Ruby モジュール使用編

```ruby:Gemfile
# A sample Gemfile
source "https://rubygems.org"

gem 'shangrila'
```

### follower_status.rb

指定した年&クールのTwitterアカウントのフォロワー数リストを表示

```ruby:follower_status.rb
require 'shangrila'

year = ARGV[0]
cours = ARGV[1]

# 指定した年、クールのアニメ公式Twitterアカウントを取得(Sora[Master] API)
master =  Shangrila::Sora.new().get_flat_data(year, cours, ['twitter_account'])

twitter_account_list = master.flatten

# 指定したTwitterアカウントのフォロワー数を取得(Sana[Twitter] API)
follower_status = Shangrila::Sana.new().follower_status(twitter_account_list)

follower_status.each do |key,val|
  puts sprintf('%20s %d', key, val['follower'])
end

```


実行

```
 bundle exe ruby follower_status.rb 2015 4
```

結果

```
     ketsuekigatakun 5659
         anime_lance 8685
            DwD_info 22470
          g_tekketsu 35960
      DDhokuto_anime 2572
      owarino_seraph 95786
      anime_kagewani 1625
              te_kyu 12599
         rainy_cocoa 4224
        hokuto_15aji 11417
       fafnerproject 29933
     Anime_W_Trigger 41316
          onsenyosei 2685
         usagi_anime 134950
            ho_anime 7633
         f_noitamina 12723
     nisioisin_anime 131155
            hstar_mu 26364
        cometlucifer 8161
     anime_kyojinchu 30973
        SakurakoKujo 10738
     UtawareOfficial 14501
         shinmaimaou 14722
     animehaikyu_com 286058
      anime_yuruyuri 92904
           ittoshura 15200
           anime_k11 92573
           opm_anime 52513
     animekindaichiR 5132
        ariaAA_anime 11440
        asterisk_war 15870
        anime_syomin 11946
      35shoutai_info 7946
        anime_somera 2553
     Hackadoll_anime 7120
        lupinIII_4th 20991
      anime_dialover 68508
         conrevoinfo 8273
           anime_ybj 9113
       valkyriedrive 6383
        komori_anime 2570
         noragami_PR 81402
         osomatsu_PR 129156
```

この情報を元にこういうグラフはすぐ作れるようになります


![CTYavkjUsAA-I3A.png-large.png](https://qiita-image-store.s3.amazonaws.com/0/36931/d23b6d5d-2399-e0c5-5bd6-916de6f16d43.png)



### follower_history.rb

指定したアニメ公式Twitterアカウントのフォロワー履歴を取得


```ruby:follower_history.rb
require 'shangrila'

account = ARGV[0]
end_date_unixtimestamp = ARGV[1]

#指定したアカウントのフォロワー履歴を取得
history_list = Shangrila::Sana.new().follower_history(account, end_date_unixtimestamp)

history_list.each do |history|
 puts sprintf('%d %s %d', history['follower'], Time.at(history['updated_at']).strftime('%Y-%m-%d %H:%M:%S'), history['updated_at'] )
end
```



実行

```
 bundle exe ruby follower_history.rb usagi_anime
```

or 

```
 bundle exe ruby follower_history.rb usagi_anime 1446901208
```

結果

```
134964 2015-11-10 00:30:07 1447083007
134942 2015-11-10 00:00:07 1447081207
134924 2015-11-09 23:30:06 1447079406
134900 2015-11-09 23:00:07 1447077607
134882 2015-11-09 22:30:07 1447075807
134868 2015-11-09 22:00:07 1447074007
134851 2015-11-09 21:30:06 1447072206
134838 2015-11-09 21:00:07 1447070407
134824 2015-11-09 20:30:06 1447068606
134809 2015-11-09 20:00:06 1447066806
134791 2015-11-09 19:30:07 1447065007
134766 2015-11-09 19:00:06 1447063206
134759 2015-11-09 18:30:07 1447061407
134755 2015-11-09 18:00:07 1447059607
134747 2015-11-09 17:30:06 1447057806
134745 2015-11-09 17:00:06 1447056006
134741 2015-11-09 16:30:06 1447054206
134734 2015-11-09 16:00:07 1447052407
134730 2015-11-09 15:30:07 1447050607
134724 2015-11-09 15:00:06 1447048806
134720 2015-11-09 14:30:06 1447047006
134718 2015-11-09 14:00:07 1447045207
134718 2015-11-09 13:30:06 1447043406
134715 2015-11-09 13:00:06 1447041606
134711 2015-11-09 12:30:06 1447039806
134712 2015-11-09 12:00:06 1447038006
```

最大100件、返却します。
それ以上過去の履歴が見たい場合は、配列の最後のUNIX TIMESTAMPを引数に渡します。


## ShangriLa Anime APIの参考情報

こちらを参考にしてください

https://github.com/Project-ShangriLa/shangrila_api_doc