Node.js
ECMAScript
PokemonGo

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

More than 1 year has passed since last update.

pokemon_go_logo.png


使用技術

Node.js v6.3.1
Node.jsなに?って人はこちらへ
Node.js を5分で大雑把に理解する
ECMAScript


やったこと

nvmでnode.js導入
以下参考
nvmでnode.jsの環境をつくる。

今回は最新版(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実行すると
逃げられます。
なので、アプリと同じ地域でやると損するのでやめておきましょう〜
(そんな非効率なことやる人いないと思うけど)