PokemonGoのAPIとNode.jsで遊んでみた

![pokemon_go_logo.png](https://qiita-image-store.s3.amazonaws.com/0/137745/5c1c3955-082a-4205-d54a-fd43d9d84ce2.png)
- - -
# 使用技術
**Node.js v6.3.1**
Node.jsなに？って人はこちらへ
[Node.js を5分で大雑把に理解する](http://qiita.com/hshimo/items/1ecb7ed1b567aacbe559)
**ECMAScript**

- - -
# やったこと
**nvmでnode.js導入**
以下参考
[nvmでnode.jsの環境をつくる。](http://qiita.com/544/items/7237a32c68619236f446)

今回は最新版(v6.3.1)を入れました。
ECMAScriptはバージョンが4以上じゃないと使えないみたい。

- - -
**PolemonGoAPI導入**
インストールしてみる。
`npm install pokemon-go-node-api`

PokemonGo登録時のGoogleアカウントを設定する。
- - -
最初は以下のコードで動かしてみました。

```pokemon.js
'use strict';

const PokemonGO = require('pokemon-go-node-api');

// using var so you can login with multiple users
let a = new PokemonGO.Pokeio();

//Set environment variables or replace placeholder text
let location = {
    type: 'name',
    name: 'Tokyo/Minato-ku' //東京都港区
};

let username = 'Googleアカウントのメールアドレス';
let password = 'Googleアカウントのパスワード';
let provider = 'google';

a.init(username, password, location, provider, (err) => {
    if (err) throw err;

    console.log('1[i] Current location: ' + a.playerInfo.locationName);
    console.log('1[i] lat/long/alt: : ' + a.playerInfo.latitude + ' ' + a.playerInfo.longitude + ' ' + a.playerInfo.altitude);

    a.GetProfile((err, profile) => {
        if (err) throw err;

        console.log('1[i] Username: ' + profile.username);
        console.log('1[i] Poke Storage: ' + profile.poke_storage);
        console.log('1[i] Item Storage: ' + profile.item_storage);

        let poke = 0;
        if (profile.currency[0].amount) {
            poke = profile.currency[0].amount;
        }

        console.log('1[i] Pokecoin: ' + poke);
        console.log('1[i] Stardust: ' + profile.currency[1].amount);

        setInterval(() => {
            a.Heartbeat((err,hb)=>{
                if(err) {
                    console.log(err);
                }

                let texts = '';
                for (var i = hb.cells.length - 1; i >= 0; i--) {
                    if(hb.cells[i].NearbyPokemon[0]) {
                        //console.log(a.pokemonlist[0])
                        let pokemon = a.pokemonlist[parseInt(hb.cells[i].NearbyPokemon[0].PokedexNumber)-1];
                        console.log('1[+] There is a ' + pokemon.name + ' near.');
                        
                    }
                }
            });
        }, 5000);

    });
});
```
- - -
##何が出来るの？
上のサンプルコードだと以下が出来ます。
　- 公式PokemonGoにログイン
　- ポケモン所持上限値、アイテム所持上限値の表示
　- 現在のポケコイン数、ほしのすなの数の表示
　- 指定した地域（東京都港区）にポケモンがいたらお知らせ
　
- - -
# ポケモン英語→日本語
ここまでちょっと面白いなと思いつつも、表示されるポケモンの名前が全部英語だから
何か全然わからん。てことで、日本語ないかなと探したらあった。
https://gist.github.com/PonDad/93922f63c3143489e30c3716d3d176d2

あざす。

- - -
# もう少し遊んでみた。
他の地域でもやりたいなぁ〜
ポケモン捕まえられないかなぁ〜
出来たら出てくるポケモンのCP知りたい
とか思ってAPIの中身見てたら`CatchPokemon`てある。
以下を参考に早速ポケモン捕まえてみるコード書いてみた。
https://github.com/Armax/Pokemon-GO-node-api

- - -
```pokemon.js
'use strict';

const PokemonGO = require('pokemon-go-node-api');

// using var so you can login with multiple users
let a = new PokemonGO.Pokeio();

//Set environment variables or replace placeholder text
let location = {
    type: 'name',
    name: '東京都港区'
};

let username = 'myadress';
let password = 'password';
let provider = 'google';
let pokeball = {
    monsterball: 1,
    superball: 2,
    hyperball: 3
}

a.init(username, password, location, provider, (err) => {
    if (err) throw err;

    let fs = require("fs");
    let json = JSON.parse(fs.readFileSync('./pokemon.json', 'utf8'));

    console.log('現在位置：' + a.playerInfo.locationName);

    a.GetProfile((err, profile) => {
        if (err) throw err;

        console.log('ユーザー名：' + profile.username);
        console.log('ポケモン所持上限：' + profile.poke_storage);
        console.log('アイテム所持上限：' + profile.item_storage);

        let poke = 0;
        if (profile.currency[0].amount) {
            poke = profile.currency[0].amount;
        }

        console.log('ポケコイン：' + poke);
        console.log('ほしのすな：' + profile.currency[1].amount);

        setInterval(() => {
            a.Heartbeat((err,hb)=>{
                if(err) {
                    console.log(err);
                }

                let texts = '';
                for (var i = hb.cells.length - 1; i >= 0; i--) {
                    if(hb.cells[i].NearbyPokemon[0]) {
                        let pokemon = a.pokemonlist[parseInt(hb.cells[i].NearbyPokemon[0].PokedexNumber)-1];
                        for(var j = 0 ; j<json.length ; j++ ){
                          if(pokemon.name === json[j].en){
                            console.log("やせいの「" + json[j].ja + "」が近くにいる。");
                          }
                        }

                    }
                }

                for (i = hb.cells.length - 1; i >= 0; i--) {
                    for (var j = hb.cells[i].MapPokemon.length - 1; j >= 0; j--)
                    {
                      // use async lib with each or eachSeries should be better :)
                        let currentPokemon = hb.cells[i].MapPokemon[j];
                        (function(currentPokemon) {
                            let pokedexInfo = a.pokemonlist[parseInt(currentPokemon.PokedexTypeId)-1];
                            for(var k = 0 ; k<json.length ; k++) {
                              if(pokedexInfo.name === json[k].en) {
                                pokedexInfo.name = json[k].ja
                              }
                            }

                            a.EncounterPokemon(currentPokemon, function(suc, dat) {
                              console.log('やせいの「' + pokedexInfo.name + "」が飛び出してきた。");
                              if(dat){
                                console.log(dat.WildPokemon.pokemon);
                                a.CatchPokemon(currentPokemon, 1, 1.950, 1, pokeball.superball, function(xsuc, xdat) {
                                  // if(dat.WildPokemon.pokemon.cp < 100){
                                  //   console.log("cpが100未満のポケモンは無視する。");
                                  //   return
                                  // }
                                  console.log("cp:" + dat.WildPokemon.pokemon.cp + "の" + pokedexInfo.name + "をつかまえよう！");
                                  console.log('xdat：' + xdat);
                                    let status = ['予期しないエラー', 'やった！つかまえた', 'エスケープ', '逃げられた。', '外した'];
                                    if(xdat) {
                                      console.log("ボールを投げた！");
                                      console.log('xdat.Status：' + status[xdat.Status]);
                                      if(xdat.Status == 1) {
                                        console.log(pokedexInfo.name + "をつかまえた！");
                                      }
                                    }
                                });
                              }
                            });
                        })(currentPokemon);

                    }
                }
            });
        }, 5000);

    });
});

```

かなり膨大になったけど、これで出てきた野生のポケモンの情報取れるし、色々やったからここでおしまい。

以下大いに参考した記事
http://qiita.com/n0bisuke/items/31daa590056d3d5d8336

- - -
# 遊んだ後
　5秒ごとにスクリプトが実行されていることを忘れてコード修正とかしてたらモンスターボールがめっちゃなくなってた。。。
　ポケモン捕まえようとしてるから経験値めっちゃたまってた。exp:3000→10000くらい。
　遊びで色んなところで遊んでるとBANされるみたいです。。。

- - -
# 追記
場所は日本語でも大丈夫みたいですね。あと海外でもいけちゃいました。
今日はアメリカ/ニューヨーク、オーストラリア/シドニーに行ってみました！
皆さんも色んな所にポケモンゲットしに行ってみてください。
これはけっこう楽しい！
GoogleMapのAPIも使っているので、緯度と経度も取れます！
以下のコードを追加すると緯度と経度と高度が取れるので、
ご自身で確認してみてください。
```
console.log('lat/long/alt: 緯度: ' + a.playerInfo.latitude + ' 経度：' + a.playerInfo.longitude + ' 高度：' + a.playerInfo.altitude);
```

アプリでポケモン起動したまま、こっちで同じ地域を指定して実行すると、
アプリ側で出ていた「近くにいるポケモン」がいなくなります。
（api側ではちゃんといます。）
アプリ側でポケモン捕まえる画面を表示させて、api実行すると
逃げられます。
なので、アプリと同じ地域でやると損するのでやめておきましょう〜
（そんな非効率なことやる人いないと思うけど）