ツイッターの告知を自動でGoogleカレンダーに登録する

ツイッターのライブ告知をChat GPTで処理して整形してGoogleカレンダーに登録するサービスを作りました。
サーバレスにこだわったので、月々の維持費がほぼ0円＆メンテナンスフリーです！

# 作ったものイメージ

いっぱいある告知を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/86d15a96-2585-a945-3d6c-089db599a627.png)

↓
カレンダー化！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/12d8b9bf-a531-3f1a-eb68-55c589c73c4b.png)

https://calendar.google.com/calendar/u/0/embed?src=7737d0c3914041a0c1b808194d9c0cd9a17bd0f724f6cbf8ba5c4f23c4b1c1f4@group.calendar.google.com&ctz=Asia/Tokyo

# アーキテクチャ概要

ポンチ絵
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/85728492-d0cb-26eb-2dfd-6da4f03d04e9.png)

# 詳細

データの流れに着目して、アーキテクチャを紹介していきます。

## Twitter→S3: lobstr.io利用

ツイッターから情報をスクレイピングするのに、lobstr.ioというサービスを利用しました。
以下の記事を参考に設定しました。

https://www.lobstr.io/blog/scrape-tweets-without-coding

取得結果のCSVファイルをAWS S3に転送しています。lobstr.ioの機能でS3に配置できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/01d5e0e6-9218-34bc-4347-7f087468e5b8.png)

### 苦労・工夫

- 当初、APIFYというサービスを利用していました。無料だと1ヶ月程度で自動処理が使えなくなったため※、lobstr.ioに切り替えました。月50ドル払う余裕があればAPIFYの方が良いでしょう。（※そういう仕様か、仕様変更があったかは不明）
- lobstr.ioでは処理の都合上、長文ツイートは末尾が切れ、重要な情報が後半にある場合情報を取得できないケースがある、、というデメリットはあります。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/ce2a92b5-09f2-8cf3-aee5-bda509ca5262.png)

## S3→投稿履歴（DynamoDB）

lobstr.ioでは投稿履歴のCSVを取得・S3に配置できるので、その結果を構造化して蓄積しています。
Lambda(Python)で定期的に加工して蓄積しています。

### 苦労・工夫

- DynamoDBでは「ツイートに固有なID」をキーに設定すると、昨日の投稿がUPSERT的に処理されるので便利でした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/82589165-aca9-a20e-a7a5-97fbca9db4aa.png)

- NoSQL初心者だったため、最初は色々戸惑いました。特に、データベースの中身を探索する際に全件スキャンしがちなので、その課金がまだ怖いです。
**ビッグデータでないなら、全件スキャンしても大した金額にならず、DBを常に起動しておくほうがトータルコストかかる**、と自分に言い聞かせて使っています。

## 投稿履歴→ライブ情報（DynamoDB→DynamoDB）

ツイッターの告知文章（自由入力のテキスト）から、ライブの名称・時間・場所などを抽出して、構造化データに変換しています。
**「自由入力の情報から必要情報を要約・抽出」というタスクは、LLMがEnablerとなってくれているなと感じます。**
以下のようなプロンプトを入れています。
https://diuxamlfu3f0g.cloudfront.net/files/20241229_prompt.txt

### 苦労・工夫

#### モデル選定
当初、Anthropic Claude3 Haikuを利用していましたが、ハルシネーションが発生するケースがありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/cfc436bb-a67d-ea5b-8643-c29b6dc8ab2f.png)

色々調べるとClaude系のAIはハルシネーションしやすいという記事があったりして、 **「モデルごと特性があって、中身が一緒じゃない」** ということを学びました。
さらに、Claude3.5-Sonnetに切り替えたところ、一発で上手くいくケースが増えたので、 **「モデルの賢さはすべてを解決する」** という要素があることを学びました。
なお、現在はOpenAIに切り替えて、GPT-4o-miniを使っています。

GPT-4o-miniでもハルシネーションは稀にあります。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/3dadf926-729c-21ae-f4f8-ee963e8cfd3f.png)

#### AWS固有の問題
当初、AWS上の生成AIサービスであるBedrockを使っていましたが、AWS側の都合で、2024年11月上旬になぜか利用できなくなってしまいました。
こちらと同じ事象でした・・・

https://qiita.com/minorun365/items/c1706f91ce6490697451

AWS側の対応が遅く、別にAWSに拘る必要もないので、OpenAIのAPIを利用するようにして、回避しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/61f41083-cb3d-e634-1f15-89e61590bcd3.png)


## DynamoDB→Googleカレンダー

構造化されたライブ情報をLambda(Python)を用いてGoogleカレンダーに登録しています。
以下の記事などを参考に、Google CloudのAPIで、無料かつ比較的簡単にできました。

https://dev.classmethod.jp/articles/google-calendar-api-create-schedule/

### 苦労・工夫

- オンラインでのカレンダーサービスはいくつかありますが、ChatGPTに情報収集してもらって、一番安定していそう＆使いやすそうなGoogle Calendarを選定しました。
- 時間未定なライブ情報（日付だけわかっているもの）は、全日の予定として登録しています。
- 重複登録を確認する仕組みがなく、告知を何回も行われると、その回数登録されてしまっています（あまりにも勘違いしやすい・見にくい場合は手動で消しています）

# いくらかかる？

**トータルで、月々のコストは約5円でした。**（24年12月実績）
サーバを立てて動かすサービスであれば月500円は最低限でもかかるので、クラウド・サーバレスの恩恵を感じています。
（Sin直後1ヶ月の金額ではあるので、、安定運用してきたら、後日更新したいと思います）

### lobstr.io、Google Calendar：無料

### AWS：無料

- DynamoDB
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/0754c97f-3c6a-c3da-43ad-164a61d39176.png)

- Lambda（別件で使っている分が加算されてしまっています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/efd9b426-b64d-97f1-3686-9ab6599c7201.png)


### OpenAI：$0.03
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/3c67f117-fd20-178f-f5a0-7a1a84ce23da.png)