【GAS】bitbank(ビットバンク)のAPIをGoogle Apps Scriptで利用する ~自分の資産情報を取得してみる~

##前提として
:white_check_mark:  bitbankに登録(口座開設)済である
https://app.bitbank.cc

:white_check_mark:  bitbankのAPIアクセスキーとアクセスシークレットを発行済である
https://support.bitbank.cc/hc/ja/articles/360036234574-API%E3%82%AD%E3%83%BC%E3%81%AE%E7%99%BA%E8%A1%8C%E3%81%A8API%E4%BB%95%E6%A7%98%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95

:white_check_mark:  Googleアカウント取得済である
https://www.google.com/intl/ja/account/about/

:white_check_mark:  Google Apps Scriptを利用したことがある
https://script.google.com/home

:relaxed:  前回の記事は読んだ
[【GAS】bitbank(ビットバンク)のAPIをGoogle Apps Scriptで利用する ~ビットコインの最新取引価格を取得してみる~](https://qiita.com/kaketechjapan/items/d6ae9a0630e949fcc517 "【GAS】bitbank(ビットバンク)のAPIをGoogle Apps Scriptで利用する ~ビットコインの最新取引価格を取得してみる~")

## 自分の資産情報を取得してみる 
プライベートAPIを利用して自分の資産情報を取得してみましょう。

プライベートAPI公式ドキュメント(日本語)
https://github.com/bitbankinc/bitbank-api-docs/blob/master/rest-api_JP.md

このドキュメント中の
**アセット一覧を返す**の項目を利用します。

プライベートな情報を取得する場合、肝になるのが**認証**だと思います。
ここが良く分からずに諦めてしまう方が多いのはないでしょうか。

ドキュメントによると、以下三つが必要とのことです。

* ACCESS-KEY : APIキーページで取得したAPIキー
* ACCESS-NONCE : UNIXタイムスタンプ(整数値) ※リクエスト毎に数を増加
* ACCESS-SIGNATURE : 文字列を```HMAC-SHA256```形式でAPIシークレットキーを使って署名した結果

一つずつ見ていきましょう。

### ACCESS-KEY
APIキーページで取得したAPIキーとのことなので、これはそのままですね。
取得している自分のAPIキーを使用してください。

### ACCESS-NONCE
これは？って思った方もいますかね。
ナンスと読みます。
>ナンス（nonce）とは「number used once」の略で、「一度だけ使われる数」という意味の言葉です。
主に暗号通信などで用いられる値のことを指します。
https://bitcoin.dmm.com/glossary/nonce

なので、今の時間をタイムスタンプという整数に変換して、ナンスとします。

```
const date = new Date();
const nonce = Math.floor( (date.getTime() / 1000) ).toString();
```
今の日時を取得し、そこからUNIXタイムスタンプ(ミリ秒)を生成し、かつ秒単位に変換して小数点以下を切り捨てて出来上がった整数値を文字列に変換しています。
最後はなぜ文字列に？と思われた方もいるでしょう。
後述する著名作成で、連結させるために文字列としておく必要があります。

### ACCESS-SIGNATURE
ここが難関かもしれませんね。
著名の作成です。
つまり、***情報を取得しようとしているのは、私です、本人です***というサインみたいなものです。
そのサインが、簡単で毎回変わらないものだとセキュリティ的にもどうなんだ、というところがありますから
ルールに従って多少複雑にして暗号化したサインを作ってくださいね、ということです。
そのルールが、
>署名作成は、以下の文字列を HMAC-SHA256 形式でAPIシークレットキーを使って署名した結果となります。
GETの場合: 「ACCESS-NONCE、リクエストのパス、クエリパラメータ」を連結させたもの

となっています。

今回、資産情報の取得は```GET```なので、
まず最初に***「ACCESS-NONCE、リクエストのパス、クエリパラメータ」を連結させたもの***を作成します。
```ACCESS-NONCE```は先ほど作成しました、```nonce```に値が入っています。
リクエストのパスは、ドキュメントに記載されている```/v1/user/assets```です。
クエリパラメータは、取得する条件を細かく指定する際に利用するものですが、今回は指定できるパラメータ自体が存在しないので、ナシです。
これらを連結させます。

```
// concatenated_stringは連結文字列みたいな意味です
const concatenated_string = `${nonce}/v1/user/assets`;
```

そしてこれを***HMAC-SHA256形式でAPIシークレットキーを使って署名に変換***します。
へ？って感じですよね、最大の山場です。

```
// 連結文字列をHMAC-SHA256で暗号化
const signature_base = Utilities.computeHmacSha256Signature(concatenated_string, ACCESS_SECRET);

// 暗号を16進数に変換
const signature = signature_base.reduce( function(str, chr) {
  chr = (chr < 0 ? chr + 256 : chr).toString(16);
  return str + (chr.length == 1 ? '0' : '') + chr;
}, '');
```
ここはもう、こういうものだとしてサラッといきましょう。
16進数に変換、のくだりが一手間かかっていますが、
Google Apps ScriptのHMAC-SHA256暗号化に関しては、暗号がバイト配列(データの構造みたいなもの)として返されるために、そのまま著名サインとして使えないので16進数に変換して使えるようにしています。

### いざリクエスト
材料は揃いました。あとはこれらをヘッダー情報に含めて、APIにリクエストを送ります。
完成したプログラムはこちらです。

```getMyAsset.gs
function getMyAsset(){
  // プライベートAPIのURL
  const PRIVATE_URL = "https://api.bitbank.cc/v1";

  // APIアクセスキーとアクセスシークレット
  const ACCESS_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXX", // ご自分のアクセスキーを入れてください
  ACCESS_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // ご自分のアクセスシークレットを入れてください

  // UNIXタイムスタンプからナンスを作成
  const date = new Date();
  const nonce = Math.floor( (date.getTime() / 1000) ).toString();

  // 連結文字列を作成
  const concatenated_string = `${nonce}/v1/user/assets`;

  // 著名を作成
  const signature_base = Utilities.computeHmacSha256Signature(concatenated_string, ACCESS_SECRET);
  const signature = signature_base.reduce( function(str, chr) {
    chr = (chr < 0 ? chr + 256 : chr).toString(16);
    return str + (chr.length == 1 ? '0' : '') + chr;
  }, '');

  // ヘッダー情報を設定
  const headers = {
    "Content-Type": "application/json",
    "ACCESS-KEY": ACCESS_KEY,
    "ACCESS-NONCE": nonce,
    "ACCESS-SIGNATURE": signature　
  };

  // オプションを設定
  const options = {
    "method": "GET",
    "headers": headers,
  };

  // 資産情報取得
  const response = JSON.parse( UrlFetchApp.fetch(PRIVATE_URL + '/user/assets', options) );
  console.log(response.data.assets);
}
```

結果例

```
"assets": [
      {
        "asset": "jpy",
        "free_amount": "string",
        "amount_precision": 0,
        "onhand_amount": "string",
        "locked_amount": "string",
        "withdrawal_fee": {
            "under": "string",
            "over": "string",
            "threshold": "string"
        },
        "stop_deposit": false,
        "stop_withdrawal": false,
    　},
      {
        "asset": "btc",
        "free_amount": "string",
        "amount_precision": 0,
        "onhand_amount": "string",
        "locked_amount": "string",
        "withdrawal_fee": {
            "under": "string",
            "over": "string",
            "threshold": "string"
        },
        "stop_deposit": false,
        "stop_withdrawal": false,
    　},
　　　...
]
```
実際の資産になるので、参考例は公式ドキュメントにあるものをそのまま流用していますが
このようなものが返ってくれば成功です。
取得した情報から、各項目にアクセスして値を取り出してみてください。

## これが基本
認証のくだりが少し難しかったかもしれませんが、
これをクリアすれば後は応用するだけです。

[次回](https://qiita.com/kaketechjapan/items/38ea0eca12642f0e9ad3 "【GAS】bitbank(ビットバンク)のAPIをGoogle Apps Scriptで利用する ~ビットコインを注文(売買)してみる~")は、注文をしてみたいと思います。