Twitterのいいね欄を取得してリーディングリストを作る
一通りやりたかったことはできた〜
やったこと
- Twitterのいいね欄のうち、記事(URL)を含むものから最新10件を抽出、Gmailに自動送信するスクリプトを作成
- このスクリプトをCloud Schedulerで定期実行した
- 「いいね」から自動でニュースレターが作られ、送られてくるシステムみたいな感じです
やり方
真似するときは以下をすればOK
- このフォルダ構成でファイルを作る
- .env.yaml
- .gcloudignore
- main.py
- requirements.txt
yamalにはTwitterAPIのクレデンシャルを書いている。
main.pyはこれです。いろんなコードの継ぎはぎだからきれいにできるところがあるかもしれない。
import requests
import pandas as pd
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
import functions_framework
import os
bearer_token = os.environ.get("bearer_token")
def create_url():
"""
API エンドポイントになるurlを生成
"""
tweet_fields = "tweet.fields=created_at"
# user_id
id = "1104275583171624960"
# API request
url = "https://api.twitter.com/2/users/{}/liked_tweets".format(id)
return url, tweet_fields
def bearer_oauth(r):
"""
oauthトークンの生成
"""
r.headers["Authorization"] = f"Bearer {bearer_token}"
r.headers["User-Agent"] = "v2LikedTweetsPython"
return r
def connect_to_endpoint(url, tweet_fields):
"""
エンドポイントに接続
"""
response = requests.request(
"GET", url, auth=bearer_oauth, params=tweet_fields)
print(response.status_code)
if response.status_code != 200:
raise Exception(
"Request returned an error: {} {}".format(
response.status_code, response.text
)
)
return response.json()
def df_to_body_text(df):
"""
データフレームから文面を作成
"""
body_text = ""
for d in df["text"]:
body_text = body_text + d + "\n\n\n"
return body_text
def send_mail(body_text):
"""
メールを送信
"""
# SMTPサーバー名とポート番号指定
smtp = smtplib.SMTP("smtp.gmail.com",587)
# サーバーと接続を確立
smtp.ehlo()
smtp.starttls()
my_mail = os.environ.get("mail_from")
app_password = os.environ.get("mail_pw")
smtp.login(my_mail,app_password)
charset = "iso-2022-jp"
From = my_mail
To = os.environ.get("mail_to")
Kenmei = "オラッ!今週のリーディングリストだぞ!"
Body = f'最新のお気に入りを送るよ!ちゃんと読めよ!!\n\n{body_text}'
#メール本文を読み込み
msg = MIMEMultipart()
msg.attach(MIMEText(Body))
msg["Subject"] = Header(Kenmei.encode(charset),charset)
smtp.sendmail(From,To,msg.as_string())
smtp.quit()
@functions_framework.http
def trigger(request):
url, tweet_fields = create_url()
json_response = connect_to_endpoint(url, tweet_fields)
df_latest = pd.DataFrame(json_response["data"])
df_latest_with_article = df_latest[df_latest["text"].str.contains("https://")][0:11]
send_mail(df_to_body_text(df_latest_with_article))
return "SUCCESS"
- 以下のデプロイコマンドでCloud functionsにデプロイ(未認証リクエストをOKにしないとcurlとか通らないので注意)
gcloud functions deploy likes-to-newsletter \
--gen2 \
--region=asia-northeast1 \
--runtime=python310 \
--entry-point=trigger \
--trigger-http \
--env-vars-file=.env.yaml \
--allow-unauthenticated
- Cloud Schedulerでジョブ設定。これはGUIでつまらずにできた。UNIX CRON記法はじめてみた。
課題
- Twitterでシェアされた記事に「いいね」してストックするが、検索性が低かったり既読管理に困ったりする
- 結局記事を読まずに忘れる
- 時事ネタっぽいモノもあるのでコンスタントに消費できるようにしたい
やりたいこと
- Twitterでシェアされた記事を「いいね」したら自動でストックされていき、消化できるような環境を作りたい
さらに課題設定
- 自分はブラウザで色々するのに快適さを覚えるっぽく、アプリで読もうとするとめんどくさくなってしまう
- NotionやSpreadsheetでリーディングリストを作ったことがあるが、めんどくさくなってメンテしなくなってしまう
- FeedlyやPocketもちょっとめんどくさい
- 常用するアプリで言うと、ブラウザ・Slack・メーラーがあるので、これらに小さいバッチで来ると読むかもしれない
- どかっと来るとめんどくさくて読まない
- 大体一週間に一回くらいのペースでいくつかの記事がまとまっていると読めそう
- ALL STAR SAAS FUNDのSAAS WEEKLYくらいの単位で来てくれると嬉しい
自分をユーザーに見立てて分析すると面白いな
課題設定改
記事の取得元 - Twitter
Twitterのいいね機能でニュースを収集することが多いが、検索性に乏しく、どの記事をストックしたかわからなくなる。
記事の取得 - アプリの利用習慣
もともとめんどくさがりで、複数のアプリを日常的に触るわけではない。よく触るブラウザ/Slack/メーラーといった手段で閲覧できないと記事を抽出しても読まなくなりそう。
取得頻度
毎日といった単位でリマインドされたりするのはちょっと鬱陶しく、大体週次で来ないとうんざりして形骸化してしまう。
ゴール設定
- Twitterで「いいね」で収集した記事を何らかの手段でリスト化
- メールにその週いいねした物だけを毎週送信
とりあえずPythonでいいねリストを取得して、Spreadsheetに保存してみるか
秒でできた。
ツイートのcreated_atはパラメーターで制御できるっぽい
サンプルコードで一瞬でJSON取得できたのでFlattenしてみる
さっきのサンプルコード、Unicordに変換されてしまい日本語が読めなくなるので、以下のコメント部にオプションを加えると良い。
url, tweet_fields = create_url()
json_response = connect_to_endpoint(url, tweet_fields)
# サンプルのコードにensure_ascii=Falseを追加
print(json.dumps(json_response, indent=4, sort_keys=True, ensure_ascii=False))
呼び出したJSONをPandasでDataFrameにして表示までできた。
最新99件までっぽいな
明日以降やる
- httpsが含まれるアドレスだけ検索する
- GメールAPI経由でHTMLメールを送信する
- Cloud functionsで関数化
Spreadsheet経由しないで普通にできた
Cloud functionsで定期実行するぞい
pythonの環境構築でめちゃ詰まっちゃった
みてたドキュメントのpipの記述がちょっと古かったっぽい。
いっぱいググってこれにたどり着いた。感謝。
記法が変わっている!!!
基本はチュートリアル通りでOK
環境変数の記述はこちら
Cloud functions gen2はCloud run上に構築しているのでCloud run APIをオンにしないといけない
ローカルのエミュレータがバチくそ便利。めっちゃデバッグできた