リングフィットアドベンチャーの記録をTwitterに投稿すると、順位がわかるbotを作ってみた

# 🥚 はじめに
おうちで楽しく運動できる「リングフィットアドベンチャー」。
でも、競争相手がいれば、もっとモチベーションが上がるはず。
そんな思いで、リングフィットアドベンチャーの記録をTwitterに投稿すると、ランキングが返ってくるbotを作りました！

下のアカウントをフォローし、<b>#リングフィットアドベンチャー</b> のタグ付きで運動記録を投稿するだけで、ランキングが返ってきます！
<a href="https://twitter.com/RingFitRanker?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="true">Follow @RingFitRanker (リングフィットランカー)</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ソースコードはこちらです。
https://github.com/Nemurino-kai/RingFit_Ranker

## 🐤 機能
**1.** アカウントをフォローしたうえで、<b>#リングフィットアドベンチャー</b> タグを付けて運動結果をツイートすると、順位をリプライします。

![mame](https://user-images.githubusercontent.com/40136659/95277166-196bc600-0888-11eb-8666-43365546de63.jpg)

**2.** 毎日4時に順位を集計し、12時に、フォロワー内での消費カロリー数ランキング Top10を呟きます。

![top10](https://user-images.githubusercontent.com/40136659/84641755-78eb4200-af36-11ea-802d-18bb9300c749.png)

**3.** https://ringfit.work から、全員分の順位が見れます。過去の日付の順位を見ることも可能です。
![rank](https://user-images.githubusercontent.com/40136659/103138235-d0ebd800-4713-11eb-8a1e-607b83daa477.png)

**4.** https://ringfit.work/#/user/ から、Twitterの@ユーザ名を入力することで、いままでの運動記録と、消費カロリーのグラフを見ることができます。
![graph2](https://user-images.githubusercontent.com/40136659/95273961-7020d200-087f-11eb-87d0-e8b76e266791.png)


# 💻 利用技術
## システム構成図
![system](https://user-images.githubusercontent.com/40136659/133296461-ae25e7be-a239-457e-823e-dc5d4092bc61.png)

### フロントエンド [Vue.js + Netlify[^1]]
順位や消費カロリーを表示するWebページになります。
バックエンドで公開しているAPIから情報を取得し、見やすく表示します。
Vue Routerにより、シングルページアプリケーション(SPA)を作成し、Netlify[^1]上にデプロイしています。


### バックエンド [GCE + Docker-Compose[^2]]
次の機能を持つDocker[^3]コンテナを、GCEの仮想マシン上で動かしています。

- 定期的にタイムラインを確認し、運動記録が投稿されていればリプライするコンテナ
    - Tweepy というライブラリを用いてTwitter APIを叩き、ツイートを取得した後、OpenCVによるテンプレートマッチングを用いて、画像からカロリーを読み取っています。文字の位置やフォントが決まっているため、安定して読み取れます。 
- ランキングや消費カロリーの情報を、FastAPI[^4]により、WebAPIとして提供するコンテナ
    - Nginx でHTTPS化[^5]して公開しています。 

永久無料枠の仮想マシン[^6]を使っているので、タダで運用することができています。Google様に感謝。

### 監視 [Cloud Monitoring + SENTRY + UptimeRobot]
- Google のCloud Monitoring は、サーバのリソース状況を監視し、異常時に通知します。
- SENTRY は、プログラム実行中にエラーが発生した場合、自動で通知します。
- UptimeRobot は外形監視を行い、サイトがダウンしていないかをアクセスして確かめます。

# 😖 今後の課題
### ユーザ毎の、いままでの運動記録を表示する際の高速化
全日付分の順位を毎回計算しているため、処理時間が長いです。10秒程度かかります。
過去の日付の順位は保持しておき、再計算をしなければ、高速化できそうです。

### SQLite[^sqlite]からMySQL[^mysql]への移行
今のところ、複数のDockerコンテナから、1つのSQLiteのデータベースファイルを弄る構成になっています。
データベース用のコンテナを別に立てたいところです。

### SQLAlchemy[^8]への全面移行
現時点では、生のSQLを叩いている箇所と、SQLAlchemy[^8]を使っている箇所が混在していますが、SQLAlchemyに統一したいです。
SQLAlchemyはデータベース間の差異を吸収してくれるので、SQLの操作をSQLAlchemyに統一することで、SQLiteからMySQLへの移行もスムーズに行えそうです。

# 👋 おわりに
家に籠りがちな今日この頃、「リングフィットアドベンチャー」でおもいっきり体を動かして、ランキング上位を目指してみてはいかがでしょうか。それでは:wave:

[^1]: Webサイトをホスティングしてくれるサービス。GitHubにコミットすると自動でビルドし、リリースしてくれる。無料で使えて超便利。
[^2]: 複数のコンテナからなる一つのシステムの構築を簡単に行うシステム
[^3]: アプリが動作する仮想化環境（コンテナ）を構築するサービス。環境構築を、ビルドスクリプトを用いて行うので、誰でも同じ環境が作れる。環境設定がブラックボックス化せず、管理がしやすいのがメリット。
[^4]: APIの作成に特化した、PythonのWebフレームワーク。自動で、APIのドキュメントが生成されるのが特徴。
[^5]: NginxをSSLリバースプロキシとして用いているということ。Certbotにより、Let's Encrypt からSSL証明書を取得している。
[^6]: メモリ1GB 2vCPUの仮想マシン『E2-Micro』を無料で使える。使用方法は 『[これから始めるGCP 安全に無料枠を使い倒せ](https://qiita.com/Brutus/items/22dfd31a681b67837a74)』 が分かりやすい。
[^sqlite]: データの保存に単一のファイルのみを使用する、データベースエンジン。 Pythonに最初からライブラリとして組み込まれている。
[^mysql]: クライアント/サーバ型のデータベースエンジン。同時接続の際のパフォーマンスに優れる。
[^8]: Python製のORマッパー ORマッパーとは、テーブルとクラスを対応させて，そのクラスのメソッド経由でデータを取得したり，変更したりできるようにするもの。 DBの種類に依存せず、同じソースコードでデータを操作することができる。