はじめに
RSS定期ツイートをiftttで実装してやっていたのですが、制限が厳しかったため自作しました。
完成品
docker run -it --rm \
-e RSS_URL=https://news.google.com/rss/search?hl=ja&gl=JP&ceid=JP:ja&q=twitter \
-e CONSUMER_KEY=x \
-e CONSUMER_SECRET=x \
-e ACCESS_TOKEN=x \
-e ACCESS_TOKEN_SECRET=x \
-e 'ADD_TEXT="#rss2tweet"' \
hashito/tweetrss
上から
- RSSのURL
- TwitterのCONSUMER_KEY
- TwitterのCONSUMER_SECRET
- TwitterのACCESS_TOKEN
- TwitterのACCESS_TOKEN_SECRET
- 追加されるテキスト
を入れれば出来ます。
Tweet周期を変更したい場合はSCAN_SPAN
とTWEET_DELAY
をいじってください。(両方とも秒です)
あんまりツイートすると怒られるので注意…
あと、内部でcash値を持っていて再構築すると前回どこまでRSSを読んだか忘れてしまいます。
下記のようなファイルを作ってマウントさせてあげましょう。
中身
{}
-v {you chash file}:/root/cash
(この辺ダサいですね…いつか直します)
ソースコード
ソースは単純です。
定期的にRSSを読み出し、Tweetする。
RSSはIDを保持し同一IDは対象としない、一定期間同一IDの受信なければID破棄という感じ。
import feedparser
import json
import os
import time
import datetime
import json
from requests_oauthlib import OAuth1Session
RSS_URL=os.environ["RSS_URL"]
CONSUMER_KEY=os.environ["CONSUMER_KEY"]
CONSUMER_SECRET=os.environ["CONSUMER_SECRET"]
ACCESS_TOKEN=os.environ["ACCESS_TOKEN"]
ACCESS_TOKEN_SECRET=os.environ["ACCESS_TOKEN_SECRET"]
CASH_FILE=os.environ["CASH_FILE"]
ADD_TEXT=os.environ["ADD_TEXT"]
SCAN_SPAN=int(os.environ["SCAN_SPAN"])
TWEET_DELAY=int(os.environ["TWEET_DELAY"])
def cash_read():
with open(CASH_FILE) as f:
return json.loads(f.read())
def cash_write(data):
with open(CASH_FILE,mode="w") as f:
f.write(json.dumps(data,ensure_ascii=False))
def read_rss():
return feedparser.parse(RSS_URL)
def send_tweet(text):
twitter = OAuth1Session(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) #認証処理
url = "https://api.twitter.com/1.1/statuses/update.json" #ツイートポストエンドポイント
params = {"status" : text}
res = twitter.post(url, params = params) #post送信
return res.status_code == 200
if(__name__ == '__main__'):
cash=cash_read()
print("cash:",cash)
while(1):
tm=datetime.datetime.now().timestamp()
rss=read_rss()
for i in rss["entries"]:
if(not i["id"] in cash):
print("tweet:",f"{i['title']} {i['link']} {ADD_TEXT}")
send_tweet(f"{i['title']} {i['link']} {ADD_TEXT}")
time.sleep(TWEET_DELAY)
cash[i["id"]]=tm
cash_write(cash)
for k in list(cash.keys()):
if((cash[k]+60)<tm):
print("delete:",k,cash[k],tm)
cash.pop(k)
time.sleep(SCAN_SPAN)
docker file
こちらも単純ですね。
python3のイメージを使ってrequirements.txt
をインストール。
環境変数を準備して、起動してあげる感じです。
FROM python:3
COPY . /root/
RUN pip install -r /root/requirements.txt
ENV RSS_URL=https://news.google.com/rss/search?hl=ja&gl=JP&ceid=JP:ja&q=twitter \
CONSUMER_KEY=x \
CONSUMER_SECRET=x \
ACCESS_TOKEN=x \
ACCESS_TOKEN_SECRET=x \
CASH_FILE=/root/cash \
ADD_TEXT="#rss2tweet" \
SCAN_SPAN=600 \
TWEET_DELAY=150
CMD ["python","/root/main.py"]