sunabar API実験場（GMOあおぞらネット銀行）で遊んでみました２

#概要
前回は、GMOあおぞらネット銀行さんのsunabar API実験場で遊んでみるということで、LINENotifyを利用して通知できる仕組みを作ってみましたが、今度はLINEを利用して対話型のアプリケーションに挑戦してみたいと思います。

#目次
- 作りたいイメージ
- 準備
- 実現方法の調査と準備
- コーディングと実行
- おしまい

#作りたいイメージ
##作りたいの
LINEを利用して対話型のアプリケーションを作成します。
こんな感じ

>
「残高教えて」　→　「残高は＊＊円だよ」
「＊＊に＊＊円振り込んで」　→　「＊＊に＊＊円振り込みました。そして残高は＊＊円だよ」

##実現方法
作りたいイメージか実装箇所と技術的な要素を以下のように整理しました。

|#|実装部分|どうやって実装するか？|
|:--:|:--|:--|
|1|LINEで対話型アプリケーション|お題にもしたのでLINEBot|
|２|振込機能|sunabarの振込APIを利用|

#準備
今回も銀行APIはGMOあおぞらネット銀行のsunabar API実験場を利用します。
口座開設しましょう。

#実現方法の調査と準備
##LINEで対話型アプリケーション
LINEで対話型アプリケーションを構築するにはLINEBotを準備します。
「LINE Business ID」を登録→「Messaging API」を作って設定する流れになります。

####Messaging APIの応答設定
デフォルトから変えた設定は以下です。

|設定項目|設定内容|備考|
|:--|:--|:--|
|応答モード|Bot|　|
|応答メッセージ|オフ|　|
|Webhook|オン|WebhookのURLは後述するGASのウェブアプリケーションURL|
|チャネルアクセストークン|発行|発行したトークンは後ほど利用|

##Webhookの取得
Webhookからのメッセージ受けてLINEに応答を返答するにはアプリケーションが必要です。
今回は遊びということもあり、気軽に利用できるGAS(GoogleAppScript)でアプリケーションを公開し、対話型アプリケーションを実装します。
<img width="447" alt="スクリーンショット 2020-05-24 21.00.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/b3482e0b-831e-4ae7-7d0d-833719f3af54.png">
コードを作ってウェブアプリケーションとして公開します。毎回最新のバージョンで誰でも利用できるようにする公開設定にして、発行されたURLをLINEのWebhook取得先URLとして設定します。
<img width="532" alt="スクリーンショット 2020-05-24 21.03.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/c5bfb793-507b-fcce-cfd7-22e50b2edda8.png">
##振込機能
振込機能を調べると、APIでできるのは依頼までで、以下のように色々とステップを踏まないといけません。
sunabarのはじめてガイドに記載してた内容を要約すると。
<img width="707" alt="スクリーンショット 2020-05-24 21.44.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/a8cc9a80-ce76-3ec8-4236-9bd0c9d686a8.png">
ということで、振込依頼APIを行った後に即残高を取得しても意味がないので、振込依頼を行った後にお知らせ画面のリンクを出力して振込を促すような動きに変更しました。
振込依頼のソースはこんな感じです。

```javascript
  var peyload = JSON.stringify({
                     'accountId' : '[振込元アカウントID]',
                     'remitterName' : '[振込名義人名]',
                     'transferDesignatedDate' : Utilities.formatDate(new Date(), 'Asia/Tokyo',　'yyyy-MM-dd'), ←現在日付（当日振込）
                     'transfers' : [
                       {
                         'itemId': 1,
                         'transferAmount' : '[振込金額]',
                         'beneficiaryBankCode' : '[振込先銀行コード]',
                         'beneficiaryBranchCode' : '[振込先支店コード]',
                         'accountTypeCode' : '1',
                         'accountNumber' : '[振込先口座番号]',
                         'beneficiaryName' : '[振込先名]',
                       }
                     ]
                     });

  var url = 'https://api.sunabar.gmo-aozora.com/personal/v1/transfer/request';
 
  var res = UrlFetchApp.fetch(url, {
    'headers':{
      'x-access-token':'[sunabarのアクセストークン]',
      'accept': 'application/json;charset=UTF-8',
      'Content-Type' : 'application/json',
    },
    'method': 'post',
    'payload': peyload,
  });
  
  return JSON.parse(res.getContentText('UTF-8'));
```
今回は、振込銀行コードはGMOあおぞらネット銀行（0310)、支店コード・口座番号は、予めsunabarで提供されている法人口座にしてプログラミングしてみます。

#コーディングと実行
##コーディング
結局以下のような機能にしました。

|メッセージ|出力内容|
|:--|:--|
|残高は？|現在残高を返信する。|
|ﾎｳｼﾞﾝにxxxx円振り込んで|振込依頼してお知らせページのHPリンクを表示|

ソースコードはこんな感じになりました。

```javascript
// GMOあおぞらアクセストークン
const gmo_aozora_access_token = 'sunabarアクセストークン';
// LINEチャンネルアクセストークン
const line_channel_token = 'LINEチャネルアクセストークン';

// 残高取得
function getBalances(){
  // 残高取得処理を実施
  var url = 'https://api.sunabar.gmo-aozora.com/personal/v1/accounts/balances';
 
  var res = UrlFetchApp.fetch(url, {
    'headers':{
      'x-access-token': gmo_aozora_access_token,
      'accept': 'application/json;charset=UTF-8',
    },
    'method': 'get',
  });
  return JSON.parse(res.getContentText('UTF-8'));
}

// 振込依頼（リクエスト当日に振込で依頼）
function doTransferRequest(transferAmount){
  // payloadは必要な箇所のみ
  // transfersはsunabarの場合は実在しない任意の値でもOK。
  var peyload = JSON.stringify({
                     'accountId' : '[accountId]',
                     'remitterName' : 'ﾗｲﾝｶﾗ',
                     'transferDesignatedDate' : Utilities.formatDate(new Date(), 'Asia/Tokyo',　'yyyy-MM-dd'),
                     'transfers' : [
                       {
                         'itemId': 1,
                         'transferAmount' : transferAmount,
                         'beneficiaryBankCode' : '[bankcode]',
                         'beneficiaryBranchCode' : '[BranchCode]',
                         'accountTypeCode' : '1',
                         'accountNumber' : '[accountNo]',
                         'beneficiaryName' : 'ﾎｳｼﾞﾝ',
                       }
                     ]
                     }); 

  // 振込依頼実施
  var url = 'https://api.sunabar.gmo-aozora.com/personal/v1/transfer/request';

  var res = UrlFetchApp.fetch(url, {
    'headers':{
      'x-access-token': gmo_aozora_access_token,
      'accept': 'application/json;charset=UTF-8',
      'Content-Type' : 'application/json',
    },
    'method': 'post',
    'payload': peyload,
  });
  
  return JSON.parse(res.getContentText('UTF-8'));
}

// POST待ち受け
function doPost(e) {
  var replyToken= JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof replyToken === 'undefined') {
    return;
  }
  
  // お知らせに遷移（振込のときのパスワード入力用
  var gmo_aozora_infrmation_url = 'https://bank.sunabar.gmo-aozora.com/bank/notices/important';

  // LINEメッセージを取得
  var input = JSON.parse(e.postData.contents).events[0].message;
  
  // LINE返信用メッセージ
  var messages = '';
  
  // text形式のメッセージに対して反応
  if(input.type == 'text') {
    if(input.text.match(/残高.*/)){
      // 残高から始まる文字の場合は、現在残高を返す。
      var balances = this.getBalances();
      messages = [{
        'type': 'text',
        'text': Number(balances.balances[0].balance).toLocaleString() + '円だよー'
      }];
    }else if(input.text.match(/[ﾎｳｼﾞﾝ,ホウジン,法人].*円.*振?込/)){
      // ﾎｳｼﾞﾝさんに**円振込で**円の振込依頼を行う。
      var amount = Number(input.text.match(/[0-9]+/));
      var transferRequest = this.doTransferRequest(amount);
      messages = [{
        'type': 'text',
        'text': '振込受付完了ーパスワード入力してね→' + gmo_aozora_infrmation_url
      }];
    }else{
      // コマンド違ったらスタンプで
      messages = [{
        'type': 'text',
        'text': '$',
        'emojis': [
          {
            'index': 0,
            'productId': '5ac1bfd5040ab15980c9b435',
            'emojiId': '019'
          }]
      }];
    }
  }else{
    // コマンド違ったらスタンプで
    messages = [{
      'type': 'text',
      'text': '$',
      'emojis': [
        {
          'index': 0,
          'productId': '5ac1bfd5040ab15980c9b435',
          'emojiId': '010'
        }]
    }];
  }
  
  // LINEへのメッセージ返信
  var url = 'https://api.line.me/v2/bot/message/reply';

  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + line_channel_token,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': messages,
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
```

エラーコードが戻ってきた時のハンドリングなど、本当は入れなきゃと思うのですが、今回は動くようにしています。
それでは動かしてみます。

##実行準備

- GASウェブアプリケーションを起動
- LINE Botを友達登録（Messaging APIの設定画面でQRコードを読み込む）
<img width="450" alt="スクリーンショット 2020-05-27 22.14.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/9e2fe051-f7e2-21d1-62f9-c888708c1d60.png">

##実行

- 残高照会
はじめは残高照会をしてみます。プログラム上は「残高」から始まる文章なら何でも残高照会してくれるようにしました。
<img width="450" alt="スクリーンショット 2020-05-27 22.18.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/62765554-298b-299a-9f3c-3568373f6dac.png">

- 振込依頼
振込依頼してみます。「ホウジン」からはじまり「***円」と「振込」や「振り込み」の文章なら何でもホウジンさんに振込依頼をするようにしました。
ここでは、20,000円の振込依頼を行って、OK応答と取引パスワードを入力して欲しいのリンクが返信されます。
<img width="450" alt="スクリーンショット 2020-05-27 22.23.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/ff9ac5da-698f-d756-816c-5654990061ba.png">

- 振込
リンクを押して、sunabarにログインします。
<img width="355" alt="スクリーンショット 2020-05-27 22.42.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/c4ecdf03-ed75-a0c4-b64f-813d39489da7.png">
ログインできたら、お知らせ画面にあるメールトークンを発行しましたリンク、お知らせ詳細画面のリンクを順にクリックすると振込内容の確認画面が表示されます。
<img width="355" alt="スクリーンショット 2020-05-27 22.43.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/7c0deffe-4270-1722-8526-93d822f76e1f.png">
振込依頼の内容が確認できます。入力内容と予めプログラミングしていた内容が確認できました。
<img width="355" alt="スクリーンショット 2020-05-27 22.38.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/5e1cc106-bb15-a072-391b-e0dd5ec66c7f.png">
あとはこの画面の下にある、取引パスワード入力欄に何でもいいので文字を入力して承認ボタンを押すと、振込完了画面が表示され、処理完了です。
<img width="355" alt="スクリーンショット 2020-05-27 22.40.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/ee2640eb-f3f6-c056-3be8-b88d430b30a1.png">
- 残高照会
再度、LINEから残高照会すると20,000円引かれてました。
<img width="450" alt="スクリーンショット 2020-05-27 22.48.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/d118d334-abf0-2845-a5db-40cc19e49b43.png">
- 念のため振り込まれたのか確認
法人側の入出金明細を見ると、しっかり「ラインカラ」さんから20,000円振り込まれてました。
<img width="1105" alt="スクリーンショット 2020-05-27 22.50.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/b7610981-d15c-6b9e-8a8e-68b991c4779c.png">

#おしまい
無事、sunabarの振込依頼機能とLINEBotで対話形のアプリケーションができました。
振込先を学習させて、振込先と金額をLINEに話すだけで振込依頼できるようにするのも面白そうです。
それと、別口座に振込処理が行われたことも感動です。