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

#概要
仕事で銀行APIに携わる機会が多く、APIを利用して自分自身に何か便利なサービスは作れないかなぁと思っていたところ、最近GMOあおぞらネット銀行からsunabar API実験場が公開されました。
家からも出れないので、このAPI実験上を利用して、簡単なプログラムを作って遊んでみました。

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

#作りたいイメージ
###作りたいもの
最近はメール通知よりもLINEで通知された方が気づくし読むということで、
入金や出金がされたことと、現在残高をLINEに通知するようなサービスを作ってみます。

[入金・出金] → （通知取得 → 残高取得 → LINE通知） → [入金・出金結果と現在残高をLINE通知]

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

|#|実装部分|どうやって実装するか？|
|:-:|:-----|:---|
|1|入金・出金通知の取得|Webhookやメールで取得できる？|
|2|残高の取得|銀行APIから取得|
|3|LINEで通知|LINE Notifyを利用|

#準備
###口座開設
sunabarはGMOあおぞらネット銀行の銀行口座が必要となります。
口座開設は行いましょう。

###アクセストークンの取得
#####sunabarポータルへのログイン

口座開設後は、すぐにsunabar API実験上を利用できます。
「お客さま情報（申込・設定）」＞「開発者向け」タブでポータルサイトのID・パスワードを取得します。
<img width="1116" alt="スクリーンショット 2020-05-05 15.59.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/9a9bd544-9737-48b3-e3a9-2f273cfe2ff0.png">
「sunabar API実験上ポータルサイトへ」のリンクからポータルサイトへ移動し、ログインします。

######アクセストークンの取得
銀行APIを利用するためのアクセストークンを取得します。
ログイン後のメニューから「アカウント確認、追加、トークン更新」ボタンを押します。
<img width="1116" alt="スクリーンショット 2020-05-05 16.10.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/d6e57052-786c-a3fe-b409-3f1315bd98c5.png">
今回は個人口座のアクセストークンを取得します。
コピーできそうなアイコンをクリックするとクリップボードにアクセストークンがコピーされるので、メモ帳などに貼り付ければトークンが取得できます。
<img width="1157" alt="スクリーンショット 2020-05-05 16.15.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/f3baab32-ed72-8547-6d88-5c7db9e40bcd.png">

###その他の準備
- ポータルサイト上から「sunabarはじめてガイド」を一読。
- 「オープンAPI開発者ポータル」にユーザ登録。(https://api.gmo-aozora.com/ganb/developer/api-docs/#/STOP0101)


#実現方法の調査

#####入金・出金通知の取得
sunabarのマニュアルと動きを確認した結果、入出金処理を行ったあとの通知を取得する機能はまだ実装されていないということで、今回は数秒間隔で「入出金明細照会API」を実行し、入出金明細の直近の取引を取得しチェックするようにします。

``` Python
#GMO Aozora Tranasactions Get
def transactionsGet(headers):
    conn = http.client.HTTPSConnection('api.sunabar.gmo-aozora.com')
    conn.request('GET', '/personal/v1/accounts/transactions?accountId=[accountId]', headers=headers)
    resp = conn.getresponse()
    return resp.read().decode("utf-8")
```

当日分の明細のみが欲しいため、オープンAPI開発者ポータルの内容を確認し、クエリパラメータ上は必須項目の口座ID（accountId）のみを設定しました。

#####残高の取得
残高の取得は「残高照会API」を利用します。

``` Python
#GMO Aozora Balances Get
def balancesGet(headers):
    conn = http.client.HTTPSConnection('api.sunabar.gmo-aozora.com')
    conn.request('GET', '/personal/v1/accounts/balances', headers=headers)
    resp = conn.getresponse()
    return resp.read().decode("utf-8")
```

#####LINEで通知
今回は一方的にLINEに通知するので、「LINE Notify」を利用します。
自分のLINEアカウントに対しての友達登録と、トークンの発行を行いました。

https://notify-bot.line.me/ja/


下準備はここまで。実際に作ってみました。

#コーディングと実行
###コーディング
ソースコードはPythonを利用し、API開発者ポータルの記載内容に準拠した書き方で書いてみました。

```Python:notify.py
import http.client
import urllib.parse
import json
import time

LINE_ACCESS_TOKEN = '[LINE Notifyのトークン]'
GMO_AOZORA_ACCESS_TOKEN = '[GMOあおぞらネット銀行のトークン'

#LINE Notify LINEに通知
def lineNotify(message):
    conn = http.client.HTTPSConnection('notify-api.line.me')
    headers = {
	'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN,
	'Content-Type': 'application/x-www-form-urlencoded'
	}
    payload = urllib.parse.urlencode({ "message"  : message} )
    conn.request('POST', '/api/notify', body=payload, headers=headers)
    resp = conn.getresponse()
    print(resp.read())
    return resp 

#GMO Aozora Tranasactions Get 入出金明細の取得
def transactionsGet(headers):
    conn = http.client.HTTPSConnection('api.sunabar.gmo-aozora.com')
    conn.request('GET', '/personal/v1/accounts/transactions?accountId=[accountId]', headers=headers)
    resp = conn.getresponse()
    return resp.read().decode("utf-8")

#GMO Aozora Balances Get 残高の取得
def balancesGet(headers):
    conn = http.client.HTTPSConnection('api.sunabar.gmo-aozora.com')
    conn.request('GET', '/personal/v1/accounts/balances', headers=headers)
    resp = conn.getresponse()
    return resp.read().decode("utf-8")

#main
def main(itemKey):
    gmo_headers = {
        'x-access-token': GMO_AOZORA_ACCESS_TOKEN,
        'accept': 'application/json;charset=UTF-8'
        }

    #入出金明細取得 
    tran_data = json.loads(transactionsGet(gmo_headers))

    #明細数を取得：当日取引なしの場合は0、取引ありの場合は明細数を取得
    count = int(tran_data['count'])

    #当日取引ありの場合のみ処理
    if count > 0:
        #当日取引の最終レコードを取得（取引日の昇順となるため、最終レコードが直近となる）
        current_tran = tran_data['transactions'][count - 1]

        #当日取引の明細キーを取得（判定に利用）
        current_itemKey = int(current_tran['itemKey'])

        #当日取引の明細キーが記録している明細キーよりも大きい（新しい入出金が発生した場合）
        if itemKey < current_itemKey:

            #入金か出金かを判定
            #入出金明細のtransactionTypeが１の場合、入金、２の場合、出金
            tran_str = ''
            if current_tran['transactionType'] == '1':
                tran_str = "入金あったよー"
            elif current_tran['transactionType'] == '2':
                tran_str = "出金したよー"
            else
                tran_str = "謎の取引"

            #残高の取得
            bal_data = json.loads(balancesGet(gmo_headers))

            #LINE Notifyに通知
            line_message = tran_str + "残高は" + "{:,}".format(int(bal_data['balances'][0]['balance'])) + "円"
            lineNotify(line_message)
            return current_itemKey

    return itemKey

#10秒事に取得（サーバ負荷は気になりますが・・・）
if __name__ == '__main__':
    #再起動の考慮はせずとりあえず比較用の明細キーは0で初期化
    itemKey = 0
    while 1:
        itemKey = main(itemKey)
        time.sleep(10)

```

###実験準備
+ Python実行環境：RaspberryPi３#Python 3.5.3で実行しました。

+ sunabarポータル：入出金に利用するのは以下の「入出金シミュレーター」
<img width="472" alt="スクリーンショット 2020-05-09 13.22.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/dc6523f2-17c3-8faa-1848-9302ccf5f21b.png">

###実行
* ATM入金

入金口座を選んで入金金額を入力して確認ボタンを押します。
<img width="979" alt="スクリーンショット 2020-05-09 13.27.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/fada9fab-1642-3dc0-fcd9-fe4a9bddb301.png">

入金確認したら実行ボタンを押します。
<img width="979" alt="スクリーンショット 2020-05-09 13.30.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/7b5b7f98-d4ed-7a22-b009-9ac41a490de3.png">

入金完了です。
<img width="979" alt="スクリーンショット 2020-05-09 13.35.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/55bdad3c-fcba-c958-b857-fdbb7cc3e498.png">

ちょっとすると、LINEに入金通知がされました。
<img width="324" alt="スクリーンショット 2020-05-09 13.55.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/36eecc59-14ed-4486-3960-61db3d354a81.png">


* ATM出金

続いて出金も入金と同じ流れで20,000円出金しました。こちらもLINEに出金通知がされました。
<img width="324" alt="スクリーンショット 2020-05-09 13.40.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/6889bfa4-45b2-5eaf-c5b5-51de5619e81c.png">

* 他行振込

他行振込も同じです。スナバ　タロウさんから20,000円振り込んでいただきます。
<img width="324" alt="スクリーンショット 2020-05-09 13.43.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632040/363f9370-49a6-8cff-e866-5b1cbc43e1ac.png">

想定どおりに動きました。実行停止も忘れずに（Ctrl+C)。

#おしまい
GMOあおぞらネット銀行の口座を持っていれば、個人でも無料で銀行APIのサンドボックス環境を利用でき、プログラムを作って、ポータルサイトと組み合わせて遊ぶということができ、とても贅沢な環境だなぁと思いました。
他にもたくさんAPIが公開されてますので、組みわせて遊んでみようと思います。