RSSを読み込んで自動的に定期ツイートしてくれるDockerImageを作って公開した。

はじめに

RSS定期ツイートをiftttで実装してやっていたのですが、制限が厳しかったため自作しました。

完成品

https://hub.docker.com/r/hashito/tweetrss

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_SPANTWEET_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"]