広島銀行のサンプルAPIに挑戦

最近、銀行APIマニアと化してる tatsuya1970　です。

ここ１ヶ月で[三菱UFJ銀行](https://qiita.com/tatsuya1970/items/edf45780415169aa145a)、[GMOあおぞらネット銀行](https://qiita.com/tatsuya1970/items/5cbb0eea5b1e31b85530)のサンプルAPIを試してみました。


##OpenCanvas
さて、お次は、私の地元の広島銀行はどうなのか、調べてみました。
広島銀行は、NTTデータの [OpenCanvas](https://portal.opencanvas.ne.jp/) という仕組み上でAPIが動きます。もちろんサンプルAPIを試すことができます。


では、進んでみましょう。
[![Image from Gyazo](https://i.gyazo.com/1a394bf7ea73c8e5d74926f2e1dd2e49.png)](https://gyazo.com/1a394bf7ea73c8e5d74926f2e1dd2e49)

どんどん進みます。
[![Image from Gyazo](https://i.gyazo.com/3b2821b20ead69f50738d03f699de345.png)](https://gyazo.com/3b2821b20ead69f50738d03f699de345)

広島銀行以外に、福岡銀行、熊本銀行、十八親和銀行、と合計４行のAPIが提供されています。
福岡銀行、熊本銀行、十八親和銀行は、ふくおかフィナンシャルグループで、福岡銀行と広島銀行は共同システムですので、実質１行のようなものです。




「広島銀行」を選びます。
[![Image from Gyazo](https://i.gyazo.com/3f8467510bf487fdbff7a2f780aeb9f6.png)](https://gyazo.com/3f8467510bf487fdbff7a2f780aeb9f6)

###広島銀行のAPI
「広島銀行」のAPIページにたどり着きました。
右上の「API利用情報」をクリック
[![Image from Gyazo](https://i.gyazo.com/108a1fcba3ffd0557b65fd9a7ed3ca3c.png)](https://gyazo.com/108a1fcba3ffd0557b65fd9a7ed3ca3c)

ダウンロードをクリック
[![Image from Gyazo](https://i.gyazo.com/7afc258f544dfa3c0a60579f5257ed56.png)](https://gyazo.com/7afc258f544dfa3c0a60579f5257ed56)


『【広島銀行-APIｖ1.0】シミュレータ環境用データパターン一覧.xlsx』というファイルがダウンロードされます。

開いてみます。


「はじめに（利用方法・制約事項）」を読みます。

なるほど、分からんww

[![Image from Gyazo](https://i.gyazo.com/35b7c34090aad6d9bfa1c2939e96dc27.png)](https://gyazo.com/35b7c34090aad6d9bfa1c2939e96dc27)

次に、口座一覧紹介・口座情報紹介のシートを見ます。
とれるデータは分かりましたが、これらをどうプログラムコードに入れるのか見当もつきません。

[![Image from Gyazo](https://i.gyazo.com/fe22d850580e266a7851497aad31c0a4.png)](https://gyazo.com/fe22d850580e266a7851497aad31c0a4)



さっきのところに戻って、
とりあえず、APIで口座の残高を呼び出す方法を調べます。

下にスクロールすると、それらしきところに到着しました。

[![Image from Gyazo](https://i.gyazo.com/e9abd35399f8ffcd32535156a4b3c701.png)](https://gyazo.com/e9abd35399f8ffcd32535156a4b3c701)

ん？

サンプルコードがない。

普通のエンジニアの方々は、これを見ただけでAPIを使えるのでしょうが、なにぶんド素人の私には、これを見ただけではサッパリ分かりません。

<br>
実は、私は１年前にここで諦めました。


<br><br>
が、
今回は諦めずにがんばってやってみました。

三菱UFJ銀行やGMOあおぞらネット銀行のサンプルコードを参考に、パラメータやヘッダーの記述方法をいろいろなパターンで試してみました。

何度も何度も以下のようなエラーが返ってきます。

```
{"type":"about:blank","title":"invalid_request","detail":null,"inquiry_code":null}
```

invalid_requestだけじゃエラーの原因が分からない。


数時間後・・・

このcurl文で疎通できました！

```
curl --request GET \--url https://sample.apigw.opencanvas.ne.jp/hiroshimabank_retail/v1/accounts/00100010100001000000000000000000\ --header 'Authorization: Bearer ca5723130d3042eea0a6e6b7a97d0001' \ --header 'accept: application/json' | jq .

```

```
curl --request GET \
  --url https://sample.apigw.opencanvas.ne.jp/hiroshimabank_retail/v1/accounts/00100010100001000000000000000000\
  --header 'Authorization: Bearer ca5723130d3042eea0a6e6b7a97d0001' \
  --header 'accept: application/json' | jq .

```

ちなみに末尾の
| jq .
で、JSONを整列します。


で、こんなデータがとれました。

```
{
  "count": 1,
  "accounts": [
    {
      "account_id": "00100010100001000000000000000000",
      "account_name": "本店営業部　総合普通",
      "branch_code": "001",
      "branch_name": "本店営業部",
      "account_type_code": "0001",
      "account_type": "総合普通",
      "account_number": "0100001",
      "account_branch_number": null,
      "account_specificity_division": null,
      "withholding_tax_division": null,
      "currency_code": "JPY",
      "ttb": null,
      "rate_base_date": null,
      "current_balance": 10000,
      "current_balance_yen_equivalent": null,
      "withdrawable_balance": 55000,
      "previous_day_balance": 20000,
      "previous_month_balance": -100000,
      "current_balance_with_special_agreement": null,
      "current_balance_with_special_agreement_yen_equivalent": null,
      "stage_name": "第３ステージ",
      "point": 50,
      "interest_rate": null,
      "base_date": "2018-01-01",
      "base_time": "12:30:00+09:00",
      "_links": {
        "self": {
          "href": "https://sample.apigw.opencanvas.ne.jp/hiroshimabank_retail/v1/accounts/00100010100001000000000000000000"
        },
        "transactions": {
          "href": "https://sample.apigw.opencanvas.ne.jp/hiroshimabank_retail/v1/accounts/00100010100001000000000000000000/transactions"
        }
      },
      "error": null,
      "error_description": null,
      "inquiry_code": null
    }
  ]
}

```

やったぜ！


これさえできれば、あとは何だってできます。


例えば、Node.js 

```sample.js
var request = require("request");

var options = { method: 'GET',
      url: 'https://sample.apigw.opencanvas.ne.jp/hiroshimabank_retail/v1/accounts/00100010100001000000000000000000',
      headers: 
      {   'Authorization' :'Bearer ca5723130d3042eea0a6e6b7a97d0001'}
    };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
```

<br><br>
せっかくなので、この勢いで、Node.jsで　LINEのチャットボットを作ってみました。

[![Image from Gyazo](https://i.gyazo.com/7a583f0187c570ec23b51876a4cdb5c6.gif)](https://gyazo.com/7a583f0187c570ec23b51876a4cdb5c6)


銀行APIのチャットボットの作成方法はこちらを参考にしてください。
[GMOあおぞらネット銀行のsunabarAPI実験場を使ってLINEのチャットボットを作ってみた](https://qiita.com/tatsuya1970/items/5cbb0eea5b1e31b85530)


###LINEのチャットボットのコード

```server.js
'use strict';
require('date-utils');
const request = require("request");
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: 'YOUR CHANNEL SECRET',
    channelAccessToken: 'YOUR CHANNEL ACCESS TOKEN'
};

const app = express();
app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }
  
  let resMessage="";
  if (event.message.text == "残高"){
    var options = { method: 'GET',
      url: 'https://sample.apigw.opencanvas.ne.jp/hiroshimabank_retail/v1/accounts/00100010100001000000000000000000',
      headers: 
      {   'Authorization' :'Bearer ca5723130d3042eea0a6e6b7a97d0001'}
    };
  
    request(options, function (error, response, body) {
      if (error) throw new Error(error);

      const data = JSON.parse(body);
      console.log(data.accounts[0]);
    
      const current_balance = parseInt(data.accounts[0].current_balance);
      resMessage = current_balance.toLocaleString() + "円";

      return client.replyMessage(event.replyToken, {
        type: 'text',
        text: resMessage //実際に返信の言葉を入れる箇所
      });
    

    });
  }else if(event.message.text == "履歴"){

    var options = { method: 'GET',
    url: 'https://sample.apigw.opencanvas.ne.jp/hiroshimabank_retail/v1/accounts/00100010100001000000000000000000/transactions',
    qs: { accountId: '301010003162' },
    headers: 
      {   'Authorization' :'Bearer ca5723130d3042eea0a6e6b7a97d0001'}
    };

    request(options, function (error, response, body) {
        if (error) throw new Error(error);
        const data = JSON.parse(body);
        console.log(data);
        //resMessage="履歴";
        const count = data.count;
        if (count == 0){resMessage="本日の取引はありません"}
           else {
             resMessage = "本日の取引履歴";
             for (let i = 0; i < count; i++) {
               const date = data.transactions[i].transaction_date;
               const detail = data.transactions[i].transaction_detail;
               const amount = parseInt(data.transactions[i].amount);
               const abstract = data.transactions[i].abstract;
            resMessage = resMessage + "\n" + date+" "+detail+" "+amount.toLocaleString()+"円 "+abstract;
          }
        }
        return client.replyMessage(event.replyToken, {
            type: 'text',
            text: resMessage //実際に返信の言葉を入れる箇所
          });
        
    });
  }
  else {
      resMessage="もう1度お願いします";
      return client.replyMessage(event.replyToken, {
        type: 'text',
        text: resMessage //実際に返信の言葉を入れる箇所
      });
  }
}
  
app.listen(PORT);
console.log(`Server running at ${PORT}`);

```

##これから
「これからは組み込み型金融だぜ！　ウェーイ！」　って叫ばれています。
銀行のAPIはこれから一気に普及することは間違いないと思います。
API提供側は、最低限ソースコードを載せるなど利用者フレンドリーなウェブサイトにしないと、フィンテック企業や、組み込したい企業からそっぽを向かれると思います。

<br>
と思ってましたが、
最近、API提供企業のデータ仕様がバラバラで不便というペインを解決するために、フィンテック企業とAPI提供企業の間をつなぐ業者も現れていますので、そういう人たちの仕事領域になるのかもしれませんね。

<br>