GMOあおぞらネット銀行のsunabarAPI実験場を使ってLINEのチャットボットを作ってみた


##作ったもの
GMOあおぞらネット銀行のAPIを利用して、Node.jsで銀行チャットボットを作ってみました。
残高照会、口座履歴紹介、振込依頼ができます。
（リアルデータではないです。GMOあおぞらネット銀行のサンドボックスsunabarAPI実験場での架空のデータです）

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



以前こちらのQiita記事[『三菱UFJ銀行のサンプルAPIを試してみた』](https://qiita.com/tatsuya1970/items/edf45780415169aa145a)で書いた三菱UFJ銀行のサンプルAPIは、固定された数字しか取り出せないですが、GMOあおぞらネット銀行は、sunabarというサンドボックス環境を用意しており、仮想的に入金・振込など試せます。

なお、sunabarを利用するためにはGMOあおぞらネット銀行の口座が必要です。（口座開設は面倒な書類のやりとりは無く、ネットだけで完結します）

##私の環境
macOS Catalina
node.js v14.5.0

##準備

API開発者ポータルでアカウント作成
https://api.gmo-aozora.com/ganb/developer/api-docs/#/STOP0101

GMOあおぞら銀行の口座開設
https://gmo-aozora.com/

銀行口座を作成すると、
サンドボックス環境であるsunabarポータルへのログインが可能になります。

ログインID,パスワードは、リアル口座画面から確認できます。
「お客さま情報（申込・設定）」タブ 　＞ 　「開発者向け」
※パスワードは定期的に変更されています。

##sunabar ポータル

sunabarポータルへのログイン
https://portal.sunabar.gmo-aozora.com/

こんな画面です。
[![Image from Gyazo](https://i.gyazo.com/1b6ca1a4635c9ae7d6f75252c0b3b750.png)](https://gyazo.com/1b6ca1a4635c9ae7d6f75252c0b3b750)

自分のサンドボックス口座は、
左側をクリック

![スクリーンショット 2021-09-08 18.50.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/03d37ce0-83de-f4fb-f76d-ffe2fee4bdf7.png)

すでに個人・法人の２つの口座ができてます。
[![Image from Gyazo](https://i.gyazo.com/18f69f887121f72da488b98e082c4c66.png)](https://gyazo.com/18f69f887121f72da488b98e082c4c66)

ログインすると
本物のGMOあおぞら銀行のインターネットバンキングと同じUIです。
開発中に本物かsunabarか混乱したことあるほど。
なお、この画像では残高1万円ですが、デフォルトでは残高はゼロです。
[![Image from Gyazo](https://i.gyazo.com/14c7425f63eb1852b68c14b87ecdbdbe.png)](https://gyazo.com/14c7425f63eb1852b68c14b87ecdbdbe)

では、どうやって入金するかというと、先ほどの画面の右側から入金できます。
仮想的なセブン銀行のATMという設定です。
[![Image from Gyazo](https://i.gyazo.com/ad2f03be904a69acb9d37c2f2235a8f6.png)](https://gyazo.com/ad2f03be904a69acb9d37c2f2235a8f6)



##開発

###LINE
LINEのチャットボットはこちらのリンク先のとおりにすれば作成できます。
[1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)


###APIトークン
APIのトークンを入手
[![Image from Gyazo](https://i.gyazo.com/43f158feb740f422256604583b987fd4.png)](https://gyazo.com/43f158feb740f422256604583b987fd4)

[API開発ポータル](https://api.gmo-aozora.com/ganb/developer/api-docs/#/STOP0101) にソースコードや仕様書があるので、それを参考に、Node.js　で作成しました。




###コード
同じ処理を何度も記載してるなど、もっともっと綺麗にかけると思いますが、とりあえず動いたのでヨシ！とします。
なお、今回は実用的なチャットボットを作ることが目的ではなく、APIの動作確認なので、コードがごちゃごちゃにならないように振込先・金額は固定にしてます。（手抜きではありません）


```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: 'LINE MessagingAPIのchannelSecret',
    channelAccessToken: 'LINE MessagingAPIのchannelAccessToken'
};

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://api.sunabar.gmo-aozora.com/personal/v1/accounts/balances',
      qs: { accountId: '301010003162' }, //支店番号＋口座種別（普通預金：01、当座預金:02）＋口座番号
      headers: 
       { accept: 'application/json;charset=UTF-8',
         'x-access-token': 'APIトークン' } 
    };
  
    request(options, function (error, response, body) {
      if (error) throw new Error(error);
      const data = JSON.parse(body);
      //console.log(data.balances[0].balance);
      const balance = parseInt(data.balances[0].balance);
      resMessage = balance.toLocaleString() + "円";

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

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

    var options = { method: 'GET',
    url: 'https://api.sunabar.gmo-aozora.com/personal/v1/accounts/transactions',
    qs: { accountId: '301010003162' },
    headers: 
     { accept: 'application/json;charset=UTF-8',
       'x-access-token': 'APIトークン' } 
    };

    request(options, function (error, response, body) {
        if (error) throw new Error(error);
        const data = JSON.parse(body);
        console.log(data);
        const count = data.count;
        if (count == 0){resMessage="本日の取引はありません"}
        else {
          resMessage = "本日の取引履歴";
          for (let i = 0; i < count; i++) {
            const date = data.transactions[i].transactionDate;
            const type = data.transactions[i].transactionType;
            let typeStr ="";
            if (type==1){typeStr="入金";}else if (type ==2){typeStr="出金";}
            const amount = parseInt(data.transactions[i].amount);
            const remarks = data.transactions[i].remarks;
            resMessage = resMessage + "\n" + date+" "+typeStr+" "+amount.toLocaleString()+"円 "+remarks;
          }
        }
        return client.replyMessage(event.replyToken, {
            type: 'text',
            text: resMessage //実際に返信の言葉を入れる箇所
          });
        
    });
      
  }else if(event.message.text == "振込"){
    const date = new Date();
    const currentDate = date.toFormat('YYYY-MM-DD');

    //コードが複雑になるので振込先・金額は固定とした
    var options = { method: 'POST',
        url: 'https://api.sunabar.gmo-aozora.com/personal/v1/transfer/request',
        headers: 
         { 'Content-Type': 'application/json',
           'x-access-token': 'APIトークン',
           Accept: 'application/json;charset=UTF-8' },
        body: 
         { accountId: '301010003162',
           transferDesignatedDate: currentDate ,
           transfers: 
             [{
              transferAmount: '1000',
              beneficiaryBankCode: '0398',
              beneficiaryBranchCode: '111',
              accountTypeCode: '1',
              accountNumber: '1234567',
              beneficiaryName: 'ｶ)ｱｵｿﾞﾗｻﾝｷﾞｮｳ' 
             }]
         },
         json: true 
      };
  
    request(options, function (error, response, body) {
      if (error) throw new Error(error);
      const url = 'https://bank.sunabar.gmo-aozora.com/bank/notices/important';
      resMessage = "振込受付完了ーパスワード入力してください→" + url;

      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}`);

```






##参考サイト
既にほとんど同じことを先人の方がしてました・・・。振込のところを参考にさせてもらいました。ありがとうございました。
[sunabar API実験場（GMOあおぞらネット銀行）で遊んでみました２](https://qiita.com/sirolab/items/1708011dfd2110fb98e9)