Python
Twitter
PokemonGo

#PokemonGO で捕まえたポケモンを呟く Twitter bot を作ってみた

More than 1 year has passed since last update.

序文

Pokemon GO,ようやく日本でもローンチされましたね :tada:

海外勢は
リバースエンジニアリングしたり
内部APIをこねくり回したり
遊んでいるようです

その甲斐あってか,GitHub にはごまんと Pokemon GO 関連のレポジトリがあります

...これは自分もいじくり回して遊ぶしかないな!

よし
Pokemon GO で捕まえたポケモンを呟く Twitter bot を作ろう:exclamation::exclamation:

と,思い立って作りました

試すときには自己責任でお願いします

3846masa/Tweet-PokemonGO-Journal

書いたコードを GitHub に載せておきます

https://github.com/3846masa/Tweet-PokemonGO-Journal

動かすとこんな感じ

https://twitter.com/EBAGmasa_pokego

tejado/pgoapi

API を叩けるライブラリっぽいものはいろいろありましたが,
なんとなく tejado/pgoapi を選んでみました

Dockerfile まで用意されているので,手軽に遊べます

方針

ポケモンを捕まえると,ぼうけんノート(英語名:Journal)に記録が残ります
つまり, ぼうけんノートのデータさえ取れればよさそうです

ぼうけんノート

tejado/pgoapi には,あいにく Journal の Example はありませんでした

関数とかを探してみると, pgoapi.py#L107-L127

def __getattr__(self, func):
    def function(**kwargs):

        if not self._req_method_list:
            self.log.info('Create new request...')

        name = func.upper()
        if kwargs:
            self._req_method_list.append( { RequestType.Value(name): kwargs } )
            self.log.info("Adding '%s' to RPC request including arguments", name)
            self.log.debug("Arguments of '%s': \n\r%s", name, kwargs)
        else:
            self._req_method_list.append( RequestType.Value(name) )
            self.log.info("Adding '%s' to RPC request", name)

        return self

    if func.upper() in RequestType.keys():
        return function
    else:
        raise AttributeError

RequestType.Value を追っていくと,
AeonLucid/POGOProtos - RequestType.proto にたどり着きます

Pokemon GO の通信は,Protocol Buffers を使っているようです

実際にどういったデータが流れているのか,パケットキャプチャしましょう

パケットキャプチャ

Android のパケットキャプチャは,こちらを参考にしました

キャプチャするとこんな感じになっていました

なんとなく見ていくと,801という数字が気になりますね

AeonLucid/POGOProtos - RequestType.protoで探すと,
SFIDA_ACTION_LOG らしいです

tejado/pgoapi のコードと照らし合わせれば,
api.sfida_action_log()で何かが得られそうです

(ちなみに,現時点の tejado/pgoapi にある POGOProtos は古いので置き換えましょう)

api.sfida_action_log()

実行結果はこんな感じ

{
  'api_url': ...,
  'auth_ticket': { ... },
  'request_id': ...,
  'responses': {
    'SFIDA_ACTION_LOG': {
      'log_entries': [{
        'catch_pokemon': {
          'combat_points': 156,
          'pokemon_id': 114,
          'result': 1
        },
        'timestamp_ms': 1469169999498
      }, {
        'fort_search': {
          'items': [{
            'count': 3,
            'item_id': 1
          }],
          'result': 1
        },
        'timestamp_ms': 1469233607913
      }],
      'result': 1
    }
  },
  'status_code': 2
}

おそらく fort_search が,ポケストップ情報で,
catch_pokemon が,捕獲したポケモン情報でしょう

あとはザックリと,Twitter bot を作るだけですね :muscle:

おわりに

こういった非公開APIは,ゲームの改ざんのような悪い印象が強いですが,
ログを取るという方面では面白いことができそうな気がしてきます

もちろん, サーバに負荷をかけるようなことはダメ :no_entry_sign: ですけど
ちょっと遊んでみるぐらいはよいのではないでしょうか