自動SNSサーフィンシステムをクラウド上でサーバーレスに実装


# はじめに

VTuberが好きすぎて、YouTubeとTwitterで何か面白いネタがないか探す毎日を過ごしています。だいたい同じ文言で検索し、同じチャンネル（アカウント）を確認している状況でしたので、自動化できるんじゃないかと思い立ったのが事の始まりです。
設計・構築・実装がある程度形になってきたので、備忘的に書き流してみます。


# 最低限満たしたかった条件(要件定義もどき)

- 費用なし(無料サービスで実現)
将来どうなるか分からないが、まずは個人用システムとして稼働させるため、初期投資なし。
- クラウドサービス利用(できる限り)
サービス設計・製造部分に注力したいため、インフラ部分は外部サービスで実現する。
システム環境についてセキュリティ設計や維持運用に手が取られなくて済むように。
- できればPython・PostgreSQL利用
ちょうど勉強したいと思っていたので。あくまで可能ならば。



# サービス内容
まずは実現した機能の概要を。

## YouTube自動検索
定期的にYouTubeでキーワード検索を行い、その結果を取得、フィルタリングしたうえでWebページ上に表示します。スクリプトを自作しているため、検索方法・フィルタ方法について柔軟な設定が可能です。現在はキーワード４種で１日３回検索し、10000再生超えの動画のみ表示するようにしています。
手動でサーフィンしてた頃は時間が相当かかってた作業ですが、今は一瞬で確認が終わるようになりました。大満足です。


## ツイッター自動投稿
自作ホームページを定期的に宣伝したり、特定のYouTubeチャンネルの投稿情報をツイートしたりします。
後者はYouTube上で新規投稿されたのを検知してツイートする仕組みとなっており、結果タイムライン上に好きなチャンネルの動画情報が自動でまとめられることになります。
チャンネル毎のページを見に行くと手間だし時間も食うので、自動化できて大変満足です。



他にも何か思いついたら随時実装していこうと思っています。



# システム構成
![自作クラウドサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2837795/0634d4a1-d87b-c341-67c4-02a628bf8432.png)
構成イメージ作るの初めてなんですが、それなりに伝わりますでしょうか？
それぞれの簡単な説明は以下のとおりです。

- AWS Lambda
言わずと知れたサーバーレスコンピューティングサービス。プログラム実行環境が提供される。今回特に必要だった機能。
- CloudWatch Events
Lambdaサービスの定期実行。今回特に必要だった機能その２。
- Systems Manager Parameter Store
キー情報等の固有値を管理。
- IAM (Identity and Access Management)
各サービス間のアクセス権限を設定。
- Cloud Watch
Lambdaからのログ出力を管理。容量を圧迫しないよう、２週間で削除する設定に。


- GAS (Google Apps Script)
スクリプトプラットフォーム。Googleが提供する各種サービスを自動サービス化できる。
- Google Spreadsheet
クラウド上で動作する表計算ソフト(Excelのようなもの)。

- GitHub
クラウド上でWebサービスのように振る舞うシステム実現のため利用。
HTMLソース、CSSソースを保管し、発行されたURLにアクセスすることでサービスを利用する。

AWS Lambdaはプログラム言語を選択できますので、今回はもちろんPython 3.9を選択。
各サービスの連携のため、Twitter API (Auth 2.0 with PKCE), YouTube API, GitHub REST APIを利用。
GASは実行可能APIとして構築(一部Pythonライブラリのgspreadを利用してアクセス)。

ここで断っておきたいのですが、業務でこんなの提案したら怒られると思います。2大クラウドを跨いだシステムなんて不安定が過ぎる。
あくまで個人的なシステムで、勉強も兼ねて、無料の範囲で、色々したい…というわがままを実現させた結果こうなっただけで、通常ならシンプルにAWSに寄せる形でいいと思います。


# 解説 (システム設計の経緯)

## バックエンド部分

クラウド上で動作するスクリプト定期実行サービスが必要であったため、無料で柔軟な設定ができるAWSを利用することにしました。herokuは有料化してしまったので…。
スクリプト実行環境はAWS Lambda。キー情報等のパラメータは同じくAWSのParameter Storeに保存し、IAMで利用権限を設定。LambdaからアクセスできるようにAWS IAMを定義しました。
定期実行スクリプトはPythonで記述し、AWS Lambdaにデプロイ。Twitter APIはここで利用しています。

データストア機能をどう実現するかはちょっと悩みました。
AWS内で探すと、Amazon RDS等のデータベースサービス、DynamoDB等のNoSQLデータベースサービス、あるいはS3等のストレージサービス等、無料の範疇で利用できるものもありましたが、データ量・処理量の制限があります。その計算が細かくて難しく、気づいたら利用量が無料の範疇を超えてて課金されてた…というのは避けたいと感じたので、今回は利用を見送りました。
「数年間にわたるデータ完全性」みたいなビジネスシーン並みの要件を満たす必要はなく、ちょっとしたデータを保管できれば良い（最悪失われてもいい）ことから、無料で容易に利用できるGoogle Spreadsheetを選択。この時点でPostgreSQLの利用は断念しました。
（ここがAWSにできるならシステム構成がぐっとシンプルになる。PostgreSQLも利用可）

YouTubeで取得した情報をGoogle Spreadsheetに保存するため、同じくGoogleが提供するサービスであるGASを選択。
GASだとYouTube API利用が比較的容易になります。ただ、AWS Lambdaでも問題なく導入できる部分です。
YouTube APIはGASに記述して、実行可能APIとしてデプロイすることでAWSから実行できるようにしました。
取得データへのアクセスはAWS Lambdaでgspreadライブラリを利用して実現しています。
…変な設計なのは色々試してみたかっただけで、全部GASかAWS Lambdaのどちらかで実現可能です。


## フロントエンド部分

無料で良いサービスがなかなか見つかりませんでした。Webサーバを自室で立ち上げてドメイン取得して…というのも考えましたが、やはりここもクラウドサービスで実現したいです。セキュリティや環境維持運用に手が割かれない環境が欲しかったです。

AWSは有料(Amazon Lightsail)。
GASでのWebアプリケーション構築が実は不可能ではないが、一般的なOauth認証ではなく、Googleアカウントを参照してアクセス可否を分岐するため、設定にコツが必要。他サービスからのアクセスにあまり適していません。
GitHubにHTMLとCSSをアップロードして公開すると、Webページのように振る舞うため、ひとまずこれでなんちゃってWebサービスを実現しました。GitHubはあくまでバージョン管理システム(ファイルストレージシステム)なので本来の用途とは異なりますし、特に動的ページの作成はできないという制限がありますが、静的ページを定期的に作成しコミットすることで疑似的に動的ページを実現しています。
1日3回程度、SNSから情報取得しHTMLソースを生成し、GitHubにアップロードする設定に。個人利用なのでこの程度でもまあ機能しています。

GitHub REST APIをAWS Lambdaで利用するようスクリプトを修正して完了です。

## バックエンド部分(ローカルPC)

上記の構築によりクラウドサービスが実現しましたが、残念ながら一部ローカルで手動起動しているスクリプトがあります。
AWS LambdaもGASもスクリプト実行時間に制限があり、それを超えて作動するような時間のかかるスクリプトなのでクラウド上に移せませんでした。
詳細は割愛しますが、仕様上実行時間が長くなるのは避けられないので、ローカルからたまに動かしてあげるしかないかなーと思っています。

まだプロトタイプなので悠長に構えていますが、将来的にAIも絡めて本格稼働、という可能性も考えており、その際には改めて環境構築しないといけないなと思っています。



# おわりに

そうしてできたシステムが構成図のものです。うーんキメラ。
今回Azureは検討もしていないため、今後ちょっと学んでみて、活用できそうなサービスは取り入れてみたいですね。「GitHub Webアプリケーションサービス」はかなり無理のある実装なので、ここの移行先を考えていきたいです。動的ページが作れないのもネックなのですが、キーの定期的な手動更新が必要で面倒なんです。
ホントはPostgreSQLも試してみたくてシステム構築に取り掛かってたのに、気づけばなくなってたので、DBサーバを利用したサービス構築を今度こそやってみたいです。

実は別件で無料CMS Jimdoを利用したWebページも作ってみたことがありまして、落ち着いたら「iframeタグを利用したwebサービスパーツの提供→Jimdoで実装」というのもやってみたいですね。

以上です。
ここまで読んでいただきありがとうございました。何かの参考になれば幸いです。