とある趣味よりプロジェクトで、連休中に久々にハッカソンレベルで突貫なサービスを作っていたので、そこで学んだことをまとめておきます。
なんかしてました
LINE Botで動かすサービスで、GCPのAPI, AWS S3等を使って色々やるスタートアップ向けのサービスです。
LINEBot自体はLINE公式アカウントの管理機能である程度やり取りは可能ですが、裏でサービスと連携したいときなどなどは専用のサービス(アプリケーション)は必須ですね。
今回突貫なのでherokuで用意しましたが、PyCon mini Shizuokaでherokuをじっくり触ったおかげで、デプロイはスムーズでした。スタートアップなサービスならherokuで良いでしょう。無料だし。
備忘録レベルのメモ
LINE Bot
- pythonのSDKがある: line/line-bot-sdk-python: LINE Messaging API SDK for Python
- ヘルプは微妙でサンプルコードを見ながらやったほうがいいと思う。api documentがREDAMEにあるのでたどりながら見るのがしんどい
- readme.rstなので、sphinxでAPIドキュメント用意できるのでは? と思ったり
- 各種機能がまとまったキッチンシンクアプリ :line-bot-sdk-python/examples/flask-kitchensink at master · line/line-bot-sdk-python
- オウム返しのサンプルボット: line-bot-sdk-python/examples/flask-echo at master · line/line-bot-sdk-python
Line messasing API
Messaging APIの概要 | LINE Developers
Messaging APIを始めよう | LINE Developers
- メッセージの受信はwebhookと言われている。Slackbotと同じようにサービス側で受信するためのwebhook用urlが必要。サービス側に
https://[servive-url]/callback
の形式を受け取る必要あり。要件もあるのでこちら参照: https://developers.line.biz/ja/reference/messaging-api/#webhooks - メッセージ送信について詳しくはこちら: メッセージを送信する | LINE Developers
- リプライメッセージはメッセージをハンドルした後に一度しか送れない(そのユーザーに対して送るってイメージ
- プッシュメッセージは誰に対しても送付可能
- LINEのドキュメントは、基本全部curl+REST APIな説明なので、Pythonの事情で見ようとすると頭の変換が必要。
- というかjsonで見られるサンプルのメッセージデータをそのままPythonでつかえるようにしてほしい...
- ユーザーへメッセージ送信するぐらいではユーザー管理は必要ないけど、ユーザーの操作を記録してコンテンツを返す場合は、セッション管理しないとだめだと思います(というかダメなはずです、むしろ普通のはずです)
- LINE公式アカウントのカードタイプや確認ダイアログやボタンメッセージ系はテンプレートメッセージと呼ばれるもので操作する。
- メッセージのやり取りは基本非同期推奨とのこと
- 参考: Python + HerokuでLINE BOTを作ってみた - Qiita
AWS IAM
- IAM でのセキュリティのベストプラクティス - AWS Identity and Access Management: AWSやGCPはサービス作るたびにIAM用意したほうが良いと思うけど、操作面倒すぎないか... みんなどうしてるんだろ。
- MFA必須機能を入れると、アクセスキー周りが使えなくなるかも: IAM ユーザーの MFA を有効化した後、アクセスキーを使用する既存処理に影響があるか教えてください | DevelopersIO
- MFAが必要なポリシーと分けたほうがいいような気がする
- この方法も悪くないけど、アクセストークンの時間が36時間なので、そこをどう見るかですね。。。(ちゃんと調べてないので今の事情は違うかもしれない?)
aws-mfa
: broamski/aws-mfa: Manage AWS MFA Security Credentials
AWS S3のセキュリティ
- boto3のクレデンシャルの利用される順序: Credentials — Boto3 Docs 1.21.22 documentation
- 特定のユーザー(グループ)に対して、特定のバケットのみアクセスを許したいとき: 特定のバケットへの Amazon S3 コンソールのアクセス権をユーザーに付与する
- デプロイ先では通常MFAは使えないので、ポリシーの工夫が必要: 今回突貫なので設定はあきらめた
- もしかしたらこれで行けるかも -> Amazon S3: S3 バケットアクセス、しかし最新の MFA がなく、本番バケットが拒否された - AWS Identity and Access Management
- S3バケットをパブリックアクセスにする: StaticなWebサイトならよくやるやつ
- まずはこれをみて危険性をかんがえてから。Amazon S3 ストレージへのパブリックアクセスのブロック - Amazon Simple Storage Service
AWS S3
- Boto3でS3にオブジェクトをGet・Putする方法まとめ | DevelopersIO
- boto3 -> S3 — Boto3 Docs 1.21.22 documentation: 正直読むのがしんどいドキュメント。
heroku
- LINE Botはherokuで動くようなチュートリアルがあるので、そちらを見るのをお勧め。(javaだけど)
- Herokuでサンプルボットを作成する | LINE Developers
- GCPなAPIの認証でサービスアカウントを使いたいとき: herokuのConfigVarにjsonの中身を全部つっこんで、.profileをリポジトリのルートディレクトリ畳に設置。その中にファイルを復元するbashスクリプトを書くといいらしい。
- Heroku で Google Cloud API の認証を通す方法
- Herokuでデプロイ時にスクリプトを実行したい - Qiita
- 公式解説: Dynos and the Dyno Manager | Heroku Dev Center
- heroku buildpackは複数指定可能。一番最後にメインで使う言語のbuildpackを指定することを推奨してる: アプリの複数の buildpack の使用 | Heroku Dev Center
- S3を使う方法が公式(しかも寄稿記事)に載ってる: Python での S3 へのファイルの直接アップロード | Heroku Dev Center
- Heroku CLIは使えるほうが便利
- CLI の使用法 | Heroku Dev Center
- コマンド実行時のアプリ紐付けは、Gitのリポジトリを見て自動的にしてくれるらしいけど、なぜかうまく行かない。 heroku側のgitリポジトリでやれば行けるらしいけど、手動で後付けする手段があったらいいのに。
Flask
- デバッグモードはコード上の
app.run(debug=True)
以外にも、flaskコマンドでflask run --debugger --relod
も行ける。 しかもコード上にdebugフラグを立てる必要はないとのこと - Flaskでソースの変更を検知して、Webアプリを自動リロードする[Python Tips]-スケ郎のお話
- ただWinで自環境だと環境変数が謎の挙動をしていたので、flaskコマンドは使わず。
python
- Pythonのデータクラスは便利: dataclasses --- データクラス — Python 3.10.0b2 ドキュメント
- Pythonのregexでグループ+グループ名を付ける(毎回忘れる): Pythonの正規表現マッチオブジェクトでマッチした文字列や位置を取得 | note.nkmk.me
- regex検証はこちらを使う。Pythonモードがあるので便利: regex101: build, test, and debug regex
- バイト列をインメモリーでファイルっぽく使うなら
io.BytesIO
とっても便利なのでおススメ - Pythonでリスト>辞書の構造で辞書の中身を調べて該当する辞書オブジェクトを取り出す、うまい手段
- リストに対して、next関数を使う手段: https://twitter.com/seratch_ja/status/1505749442011734016 -> https://github.com/seratch/jp-holidays-for-slack/blob/main/app/workflow_step.py#L70 @seratch_ja 大変感謝
そのほか
- herokuのFreeプランってdynoがスリープした後にURLアクセスがあると動くけど、動く時間ってどの程度遅いのか気になる
- LINE Botでやってみた限りだと復帰がそれほど遅いとは思わなかった。
- そういう意味でherokuは神サービスです。
- 人間の集中力は数時間しか持たないのもあって、コーディングやコードリーディングするときは定期的に場所を変えたほうが捗る