公式銀行アプリを使えなくされたので銀行アプリをRN使って作ってみた話

Thursday, March 19, 2020
#React#React Native

はいどうも ねじわさ です。
夜風が涼しくなるこの頃ですね。また、桜が楽しみですがこの情勢だと花見しに行くのは厳しいかなぁ...と悩んでいる所です。

ところで、皆さんは銀行口座、どのように管理してますでしょうか。
例えば、私の親はインターネット依存するのに抵抗があるようで、キャッシュカードを持たず通帳のみで運用してるらしいです。 私は全部家から出ずにやりたいので、キャッシュカードに全部移行して通帳いらないやつやってます。 いわゆるオンラインバンキングってやつですね。

オンラインバンキングは、(大抵クソダサい UI な)Web と、(最近ブームなのかスマホ UI だけリニューアルして異常にイキってる事が多い)アプリを用いて履歴を見る事ができます。

ウェブ版は大体勝手にログアウトされてめったに使わないので、普段アプリしか見てないのですが、先月こんな悲劇が起こりました。

このニュースを見て、最初は使いやすい UI になってやったぜって思ったのですが、いざ配信開始してインストールしてみると、まさかのこの現象が発生しました。

この新しいアプリ、 開発者向けオプションを有効にしていると起動できません。 古いアプリは出来てたのに。
私はオプションを有効にしていないと死ぬ人間なので、実質的に使わなくされました。

例えば家計簿アプリとか使えば、間接的に銀行口座の残高を取得できるのですが、 得体のしれない会社にオンラインバンキングのログイン情報を提供する事の恐怖と、更新速度の遅さから諦めました。

そこでどうしようかなぁ...と悩んでた所、何を思ったのか 案外自作できそうじゃね? と考えたので作ってみました。

このプロジェクトで作ったもの

  • nzws/bank-js: オンラインバンキングのスクレイピングを処理する全ての土台となるクライアント
  • nzws/bank-bot: ↑ を何を思ったのか Discord Bot にしたもの(???) (使い勝手が悪すぎたのでやめた)
  • nzws/turtle-action: Expo のビルドを GitHub Actions 上で動かせるようにした Action (作った理由は後述)
  • nzws/bank-monitor: React Native でアプリにしたもの / サーバーとアプリの monorepo

土台となる bank-js の first commit(最初の活動)が 2020/03/03 なので、17 日で完成した事になります。

nzws/bank-js

Puppeteer というブラウザをプログラムを用いて制御できる物を使って、
オンラインバンキングのウェブ版を人間に代わってプログラムがログインし、情報を収集します。
今回のプロジェクトの全ての土台になります。

ただ、スクレイピング(というかこれに限らず他のサーバーにアクセスする物)自体は設計をミスると最悪捕まるので、慎重に実装する必要があります。(参考: 岡崎市立中央図書館事件 - Wikipedia)
そこで、bank-js ではデフォルトでボタンを押したりテキストを入力したりする速度を人間以上に遅くするようにしていたり、 またアクセス頻度も 30 分に一回程度など配慮し、他サーバーにアクセスしたログは必ずファイルに出力されるようにして異常な挙動がないかチェックできるようにしています。

nzws/bank-js を使う事で、例えば口座残高を取得するのを数行で実装できるようになります。

import bankJs from '@nzws/bank-js';

(async () => {
  const bank = new bankJs('my-bank');
  await bank.init();

  await bank.login('username', 'password');

  const balance = await bank.getBalance(); // 残高がintで取得できます
})();

nzws/bank-bot

これは後々考えると何をしたかったんだ感しかないのですが、口座履歴の照会や残高取得を Discord 上で行えます。
まあフロントエンド作るのが面倒で Discord に任せればよくね?って思って作ってみたものです。

img

nzws/turtle-action

こちらはこのプロジェクトに直接的というよりかは間接的に関係があるだけですが、この一連の作業の中で作ったものです。

後述の nzws/bank-monitor では Expo というものを使用するのですが、Expo は expo build:android(or ios) ってコマンドを叩くだけで 特に PC に何かインストールする必要もなく、勝手に Expo のサーバーでアプリをビルドしてくれます。

その公式ビルドサーバーなのですが、まあとにかくめちゃくちゃ遅いんですよね。
特に日本の深夜は世界の裏側の人が活動してるのか 200 人くらい待機列が並んでて、ビルドに 4 時間くらいかかります。
また、お金を払えば優先サーバーにアクセスできるそうですが 3000円/月 だそうなので中々キツイです。

そこで、GitHub Actions の力を借りればいいじゃない?って思って作ってみました。

GitHub Actions は、GitHub が提供する CI/CD ツールです。
コードをコミット(投稿)した時に、GitHub 上でマシンが動き、ワークフローという動き方を書いたファイルを元になんやかんやしてくれるサービスです。
例えば、コードに問題がないかチェックさせたり、コードからビルドして成果物をアップロードしたり(今回の用途)できます。

GitHub Actions は、Windows(Windows Server)、Linux(Ubuntu)、macOS を使用でき、マシンスペックは全て 2コアCPU, 7GB RAM, 14GB SSD です。
公開されたリポジトリでは全て無料です。(プライベートリポジトリでは実行時間の制限があります。)

まあ内部では turtle-cli のコマンドを叩いてるだけの Action です。
この Action を使うことで、最大 4 時間かかっていたビルドが、20 分で済むようになりました。やったね!!!!!!!!

nzws/bank-monitor

さてさて、これは今回の本題ですが、React Native で作った銀行アプリです。これの first commit は 3/9(10 日前)でした。

↑ こんな感じ

何ができるの?

  • 複数口座の残高照会
  • 履歴照会
  • (楽天) ゆうちょから入金
  • 新たな取引があった際、プッシュ通知
  • 自分でサーバー動かせる

大変だったこと

  • React Native を「ただの React やんけ!foo ~~~!!!」って書いてると変な所でコケる(それなりの知識は必要だった)
  • 「こういう UI にしたい」って思っても CSS そのまま書いても RN は完全対応してる訳ではないそうで、中々自分の思い通りの UI にならない
  • Expo に OTA アップデート(バージョンを勝手に上げてくれるやつ)を知らずに「毎回ビルドしても内容が変わらないのなんでだ...?」って思ったら勝手に古いバージョンに巻き戻されてるだけだったってのを数時間掛けて知った
  • Expo のプッシュ通知と FCM は別物らしい (FCM のノリで実装してたらエンドポイント全然違った)
  • Expo はデバッグ用のクライアントがあるけど、たまに Expo クライアントだと動かなくてビルドしないとだめだよ!ってのがあった(めんどい)

まあ色々な事がありましたが、なんやかんや自分がやりたかった機能は完成できたので良かったです。

最後に

この記事書くのが一番大変でした。(だんだん書くのが飽きてきて後になるほど内容が薄くなってった顔)