2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

はじめに

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_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"]
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?