Help us understand the problem. What is going on with this article?

特定のツイートをいいねしたらSlackに自動送信するPythonスクリプト

はじめに

Twitterで論文紹介など研究関連のツイートを見つけたら,とりあえずいいねした後,研究室のSlackで共有するというのをよくやります.
「いいねする→URLコピー→Slackに投稿」
という操作すら面倒臭く感じる体になってしまったので,「退屈なことはPythonにやらせよう」という名言に肖って自動化しました.各種APIやHerokuを使ってみたかったというちゃんとした理由もあります.

もっといい書き方や実装方法あったらぜひコメントください!

GitHub:https://github.com/takaya901/likes2slack

実行例

Screen Shot 2020-06-27 at 23.59.12.jpg

仕様

本当はいいねした瞬間に投稿するようにしたくて,こちらのブログを参考にやってたのですが,MyStreamのon_eventがどうやっても発動しなかったので,決まった時刻にまとめて投稿するようにしました.
この辺が関係しているのでしょうか.ご存じの方おられたらコメントいただけると助かります.

いいねした中から研究関連のツイートのみを投稿したいので,「github:」「arxiv:」「pdf:」みたいなワードを含むツイートや,特定の研究紹介系アカウントのツイートを抽出します.

  1. 毎朝9時に,自分がいいねしたツイートを新しい順に30件取得する
  2. その中から24時間以内に呟かれており(2重投稿防止),なおかつ特定のワードを含むor特定のアカウントで呟かれたツイートのURLを取得する
  3. URLをSlackの#interesting_paperチャンネルに投稿する

実装

作業環境

  • macOS Catalina
  • Python 3.7.7
  • Pipenv
  • Tweepy
  • Heroku Scheduler

Herokuにデプロイする場合,Pythonのバージョンは要確認です.
https://devcenter.heroku.com/articles/python-support

APIのキーやトークンの取得

Twitter APIの各種キーと,Slack APIのトークンが必要です.取得方法については先人たちのありがたい記事が沢山ありますので,ここでは割愛させていただきます🙇🏻‍♂️

とりあえずTwitterはこんな感じです.
Screen Shot 2020-06-27 at 21.59.34.jpg

Tweepyのインストール

公式ドキュメントを参考にインストールします.
Getting startedにある以下のコードが動けばOKです.

import tweepy

consumer_key = 'xxx'
consumer_secret = 'xxx'
access_token = 'xxx'
access_token_secret = 'xxx'

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

api = tweepy.API(auth)

public_tweets = api.home_timeline()
for tweet in public_tweets:
    print(tweet.text)

コードを書く

コード全体は最後に紹介します.

Slackへの投稿設定

slack_url = "https://slack.com/api/"
params = {'token': os.environ["SLACK_TOKEN"], 'channel': '#interesting_paper', 'text': '', 'as_user': 'true'}

トークンはHerokuの環境変数に設定しているため,os.environで取得しています.ローカルで動かす際はベタ書きでも構いません.'as_user':'true'とすることで,投稿主がbotではなく自分になり,後から編集したり削除したりできます.

投稿

#ツイートのURLを作成
def create_twitter_url(screen_name, id_str):
    return "https://twitter.com/"+screen_name+"/status/"+str(id_str)

words = ['github:', 'arxiv:', 'pdf:'] #検索ワード
ids = ['slam_hub', 'arxiv_cscv', 'shiropen2', 'ak92501', 'HCI_Comics'] #対象アカウントのid

for status in api.favorites(count=30):
    #検索ワードとidに該当しなければスキップ
    if not any((w in status.text) for w in words) and not any((id in status.user.screen_name) for id in ids):
        continue

    #24時間以内にツイートされていたらSlackにポスト
    yesterday = datetime.now() - timedelta(days=1)
    if status.created_at >= yesterday:
        params['text'] = create_twitter_url(status.user.screen_name, status.id)
        r = requests.post(slack_url + "chat.postMessage", params=params)

検索ワードと対象アカウントのリストはどこか外部に保存したほうがいいかもしれません.中に書くと,追加や削除したときにデプロイし直さないといけません.良い方法があれば教えて下さい.

api.favorites()でいいねしたツイートを取得できます.僕は1日10件くらいしかいいねしないので,ここでは30件のみ取得しています.ふぁぼ魔の人は増やしてください.取得した30件の中から,検索ワードを含んでいるか,もしくは対象のアカウントで呟かれたものを抽出します.

更に,重複投稿を防ぐために24時間以内にツイートされたもののみを抽出します.status.created_atはdatetime型なのでそのまま比較できます.

これらの条件を満たしたら,いよいよSlackにURLを投稿します.
ツイートのURLはこれで得られるっぽいのですが,

status.entities['urls'][0]['expanded_url']
#-> https://twitter.com/i/web/status/1276706344314130432

web用のURLしか取れず,スマホで開けなかったりクライアントアプリで開いてくれなかったりしました.そこでこちらのブログを参考にさせていただき,ユーザIDとツイートのIDからURLを作成する関数を導入しました.ここでややこしいのが,status.idで得られるIDはユーザID(@~)ではなく,ツイート自体に割り振られたIDです.ユーザIDはstatus.user.screen_nameです.
print(status)とすると,statusがどんなメンバを持っているか見れます.

全体

https://github.com/takaya901/likes2slack/blob/master/likes2slack_heroku.py

Herokuにデプロイ

こちらの記事を参考にさせていただきました.APIのキーやトークンはHerokuの環境変数に設定しておきます.Heroku SchedulerでDaily at 12:00 AM UTC,JSTで毎朝9時に実行されるよう設定しました.

おわりに

いいねするのは「後で読む」という意味もあって,結局読まずに他のいいねに埋もれてしまうことも多かったので,Slackに送ることで管理もしやすくなりました.
Herokuデプロイも初めてやりましたが,めっちゃ簡単で感動しました.

takaya901
大阪大学大学院情報科学研究科M2.島根の高専から大学に編入しました.機械学習,画像処理,ARに関する研究をしています.VRゲームを作ったりもしています.
https://www.youtube.com/channel/UCBcv90Q5UN4EgbAIyJwBSaA
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした