LoginSignup
0
0

Minecraft The HIVE PlayHIVE API を GASで呼び出す

Last updated at Posted at 2024-01-04

やってみたこと

マイクラのHIVEっていうゲーム(サーバ)がありますが、各種情報がとれるようにAPIが公開されています。
APIを叩くとJSONで返ってくるので、WEBで表示するプログラムをGASで作ってみました。

Swagger

下記にAPIが公開されています。
ゲーム名やゲーマータグを入れればJSONが見えるので、わざわざ作る必要もないっちゃないのですが、GASをたまに作らないと忘れちゃうので作ってみました。

設計

GASでWEB画面を2つ作ることにしました。

  • API呼び出し&結果表示画面
  • 入力画面

API呼び出し&結果表示用 Google Spread Sheet

まず、入力画面用のGASを書くために、スプレッドシートを作りました。
さらにいうと、今回はレベル計算をしたかったのでデータベース代わりにしています。

下記に自分のXPからレベルを出す表があるので、この表をスプレッドシートにコピペして、ウニョウニョ編集して、テーブル化しました。

スクリーンショット 2024-01-04 19.19.51.png

↓↓↓↓↓ こんな感じで・・

スクリーンショット 2024-01-04 19.22.05.png

取得できるJSONの確認

前記のSwaggerで全部のデータのJSONを取得してみて、このスプレッドシートにコピペして、内容を調べました。

コード.gs

doGetでHTMLServiceを使います。
上記で調べた内容も反映します。このときも、スプレッドシートで関数を使って、GASのコードを生成しちゃえば、エディタでコピペするより簡単ですね。

例えば、
html.activated = jsonData['activated'];
だったら、A列に内容を並べておいて、
="html."&A1&" = jsonData['"&A1&"'];"
ってやれば、コードがスプレッドシート上で一発で完成!
なにげに、スプレッドシート+GASの組み合わせって便利ですね。

API仕様

doGet(e) の e にパラメータで入れられますので、今回は下記な感じになります。

  var gamename = encodeURI(e.parameter.gamename);
  var gamertag = encodeURI(e.parameter.gamertag);
  var targetperiod = encodeURI(e.parameter.targetperiod);

PlayHIVE APIのURLを下記のように生成します。

全期間の場合:
https://api.playhive.com/v0/game/all/[gamename]/[gamertag]

月間の場合;
https://api.playhive.com/v0/game/monthly/player/[gamename]/[gamertag]

APIはfetchで呼ぶ

  response = UrlFetchApp.fetch(url);
  responseCode = response.getResponseCode()

response にAPIの呼び出し結果が帰ってきます。

JSON を Parse

jsonData = JSON.parse(response);
xp = jsonData['xp'];

これで、response内のJSONをperseしてくれて、値がとれるんです。
なんて便利なの!! GAS!

HTMLService

html = HtmlService.createTemplateFromFile("index");

これで、 index.htmlと doGetを紐づけます。

htmlオブジェクトにとりあえず、全部の値をいれちゃいましょー。

例)
 html.xp = jsonData['xp'];

最後に下記でHTML化します。
ところで、Metaタグは、最初index.htmlに書いたんですが、反映されず、ググったところ、ここに書かないといけないという先人からの情報があり、ここに入れています。

  const htmlOutput = html.evaluate();
  htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1');
  return htmlOutput;

レベルの計算

スプレッドシートの内容を、一旦data配列に読み込んじゃいます、

const sheet = SpreadsheetApp.getActive().getSheetByName('level');
const lastRow = sheet.getLastRow();
const lastColumn = sheet.getLastColumn();

data = sheet.getDataRange().getValues();

で、面倒なんで、なめちゃいました。

  lv=0;
  for(i=0;i<lastRow;i++) {
    if (data[i][0]==gamename) if (xp > data[i][1]) lv = data[i][2];
  }
  return lv;

でも、ほんとに、GAS便利だなぁ・・

というわけで、「コード.gs」の完成です。

function doGet(e) {
  var gamename = encodeURI(e.parameter.gamename);
  var gamertag = encodeURI(e.parameter.gamertag);
  var targetperiod = encodeURI(e.parameter.targetperiod);

  url = "https://api.playhive.com/v0/game/all/"+gamename+"/"+gamertag; // デフォルトは「All(全期間)」
  if (targetperiod=="monthly")  url = "https://api.playhive.com/v0/game/monthly/player/"+gamename+"/"+gamertag; // 「monthly(月間)」

  response = UrlFetchApp.fetch(url);
  responseCode = response.getResponseCode()

  if (responseCode != 200) {
    return -1;
  }

  jsonData = JSON.parse(response);

  html = HtmlService.createTemplateFromFile("index");

  html.gamename = gamename;
  html.targetperiod = targetperiod;

  html.activated = jsonData['activated'];
  html.assists = jsonData['assists'];
  html.blocks_destroyed = jsonData['blocks_destroyed'];
  html.blocks_placed = jsonData['blocks_placed'];
  html.checkpoints = jsonData['checkpoints'];
  html.coins = jsonData['coins'];
  html.cows = jsonData['cows'];
  html.crates = jsonData['crates'];
  html.deathmatches = jsonData['deathmatches'];
  html.deaths = jsonData['deaths'];
  html.final_kills = jsonData['final_kills'];
  html.flags_captured = jsonData['flags_captured'];
  html.flags_returned = jsonData['flags_returned'];
  html.human_index = jsonData['human_index'];
  html.index = jsonData['index'];
  html.kills = jsonData['kills'];
  html.m_solo_deaths = jsonData['m_solo_deaths'];
  html.m_solo_goals = jsonData['m_solo_goals'];
  html.m_solo_kills = jsonData['m_solo_kills'];
  html.m_solo_played = jsonData['m_solo_played'];
  html.m_solo_victories = jsonData['m_solo_victories'];
  html.maps_completed = jsonData['maps_completed'];
  html.maps_completed_without_dying = jsonData['maps_completed_without_dying'];
  html.murderer_eliminations = jsonData['murderer_eliminations'];
  html.murders = jsonData['murders'];
  html.mystery_chests_destroyed = jsonData['mystery_chests_destroyed'];
  html.ores_mined = jsonData['ores_mined'];
  html.played = jsonData['played'];
  html.powerups_collected = jsonData['powerups_collected'];
  html.prestige = jsonData['prestige'];
  html.projectiles_fired = jsonData['projectiles_fired'];
  html.rating_good_received = jsonData['rating_good_received'];
  html.rounds_survived = jsonData['rounds_survived'];
  html.spells_used = jsonData['spells_used'];
  html.treasure_destroyed = jsonData['treasure_destroyed'];
  html.uncapped_xp = jsonData['uncapped_xp'];
  html.victories = jsonData['victories'];
  html.username = jsonData['username'];
  html.xp = jsonData['xp'];
  html.lv =getLevel(gamename,jsonData['xp']);

  const htmlOutput = html.evaluate();
  htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1');
  htmlOutput.setTitle("The HIVE Ranking");
  htmlOutput.setFaviconUrl("https://support.playhive.com/content/images/size/w256h256/2021/11/favicontest.png");
  return htmlOutput;
}

function getLevel(gamename,xp) {
  const sheet = SpreadsheetApp.getActive().getSheetByName('level');
  const lastRow = sheet.getLastRow();
  const lastColumn = sheet.getLastColumn();

  data = sheet.getDataRange().getValues();
  lv=0;
  for(i=0;i<lastRow;i++) {
    if (data[i][0]==gamename) if (xp > data[i][1]) lv = data[i][2];
  }
  return lv;
}

index.html の作成

App Script の画面のファイルのところの「+」を押すと、「HTML」があるので、選びます。「index」と入れて、「index.html」を書きます。
内容的には、PlayHIVEのAPIで取得した内容を表で表示しているだけです。
ちなみに、
<?=gamename ?> みたいに書くと、「コード.gs」で、htmlオブジェクトに埋め込んだ内容が取り出せます。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= HtmlService.createHtmlOutputFromFile("css").getContent(); ?>
  </head>
  <body>
    <div>
      <img src="https://support.playhive.com/content/images/2021/11/Hive---Yellow---Small.png" style="display: block; margin: auto;" />
    </div>
    <br>
    <div>
    <table>
      <tbody>
      <tr><td> GameName </td><td> <?=gamename ?> </td></tr>
      <tr><td> UserName</td><td> <?=username ?> </td></tr>
      <tr></tr>
      <tr><td> Prestige </td><td> <?=prestige ?> </td></tr>
      <tr><td> Level </td><td> <?=lv ?> </td></tr>
      <tr><td> Ranking </td><td> <?=human_index ?> </td></tr>
      </tbody>
    </table>
    <br><br>
    </div>
  </body>
</html>

css.html の作成

せっかくなので、cssも作ります。
App Script の画面のファイルのところの「+」を押すと、「HTML」があるので、選びます。「css」と入れて、「css.html」を書きます。

「index.html」に、

<?!= HtmlService.createHtmlOutputFromFile("css").getContent(); ?>

を書くことで、cssのファイルも読み込みます。
cssの詳細は省略します。

<style>
  body {
     background-image: url(https://いい感じの背景画像ーほげほげ.jpg);
     background-size: cover;
     color: white;
     font-size: x-large;
     font-family: "Arial Black","ヒラギノ角ゴ ProN W3", HiraKakuProN-W3, 游ゴシック, "Yu Gothic", メイリオ, Meiryo, Verdana, Helvetica, Arial, sans-serif;
  }
  table {
    margin: auto;
    border-collapse: collapse;
  }
  th, td {
    border: solid 2px white;
  }
</style>

デプロイ

画面右上のほうの「デプロイ」→「新規デプロイ」でデプロイします。
一応、これでAPI部分は完成。

補足

GASの画面構成が変わってわかってなかったのですが、下記画像のように「デプロイの管理」からデプロイすれば、URLを固定できるようです。めでたしめでたし。
スクリーンショット 2024-01-05 11.36.38.png

入力画面用 Google Spread Sheet

入力画面もGASで作っちゃいましょう。
WEBサーバを準備しないでよいので、便利です、URLは長いですが・・

コード.js

HTML化するだけなので、簡単です。

function doGet(e) {
  html = HtmlService.createTemplateFromFile("index");
  const htmlOutput = html.evaluate();
  htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1');
  htmlOutput.setTitle("The HIVE Player Profile");
  htmlOutput.setFaviconUrl("https://support.playhive.com/content/images/size/w256h256/2021/11/favicontest.png");
  return htmlOutput;
}

index.html

入力画面を作ります。ありがちなコードを書いて、GETで、API部分のデプロイ後のURLを書けばOK

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= HtmlService.createHtmlOutputFromFile("css").getContent(); ?>
  </head>
  <body>
    <div>
      <img src="https://support.playhive.com/content/images/2021/11/Hive---Yellow---Small.png" style="display: block; margin: auto;" />
    </div>
    <br>
    <div>
    <table>
      <tbody>
      <tr><td> Please input your info </td></tr>
      </tbody>
    </table>
    </div>
    <div>
    <form action="さっきデプロイしたGASのURL" method="get">
    <table>
      <tbody>
      <tr><td>
        <p>Game Name :
          <select name=gamename>
            <option value=sky>SKY</option>
            <option value=wars>Wars</option>
            <option value=murder>Murder</option>
            <option value=grav>Grav</option>
            <option value=party>Party</option>
            <option value=drop>Drop</option>
            <option value=dr>DR</option>
            <option value=hide>Hide</option>
            <option value=sg>SG</option>
            <option value=ctf>CTF</option>
            <option value=ground>Ground</option>
            <option value=bridge>Bridge</option>
            <option value=build>Build</option>
          </select>
        </p>
        <p>Gamer Tag :
          <input type="text" name=gamertag>
        </p>
        <p> Target Period:
          <select name=targetperiod>
            <option value=all>ALL</option>
            <option value=monthly>Monthly</option>
        </p>
      </td></tr>
      <tr><td>
        <input type="submit" value="Submit">
      </td></tr>
      </tbody>
    </table>
    </div>
    </form>    
  </body>
</html>

「css.html」は、API部分と同じです。

デプロイ

画面右上のほうの「デプロイ」→「新規デプロイ」でデプロイします。2回目からは「デプロイの管理」で。
一応、これで入力画面部分も完成。

完成スクショ

下記な感じです。
(ゲーマータグはリーダーボードの乗っている方のゲーマータグをお借りしました。)
ちなみに、GASでHTML化すると、こんなメッセージがヘッダーにでます。

スクリーンショット 2024-01-04 20.46.35.png

スクリーンショット 2024-01-04 20.46.58.png

なんか、バグってるかも・・
まぁ。いいか・・

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0