さぼてんメモ

さぼてんのメモです。メモなので推敲粗め。趣味:工作やハンドメイド 勉強中:回路っぽいことやプログラミング

ミスミメンテbotを改良した~pythonで直接ツイート~

前作ったこれを改良しました

cactus-k.hatenablog.com

  • 上記記事でiftttというサービスを利用して簡単なbotを作った
  • おかげ様でわりと見てもらってるぽい(うれしい)
  • 調整作業をしたり,意見をもらう中で改善点がたまってきたので改良することにした

今回作ったもの

メンテがあるときつぶやくbot twitter.com

メンテがないときつぶやくbot twitter.com

実際のツイート

前回からの改善点

  • メンテがあるときとないときのアカウントを分けた
    • ツイートのpush通知をONにして使ってもうるさくない(利用者にうれしい)
  • ツイート内容のカスタマイズが楽になった(私がうれしい)
    • プログラム上で直接ツイート内容を記述・投稿できるようにした
    • これに伴いツイート内容に渡せる引数の数の制限もなくなった

なぜわざわざ作り直したのか・今回の目標

  • 2019年3月から運用を続けた結果,以下のように改善点・不満点がたくさんでてきた.
    • ツイートの内容を細かくカスタマイズできない
      • iftttで提供されているツイートフォーマットに従うツイートしかできない
      • iftttのwebhookからツイートに渡せる引数は3つまで
    • メンテがあるときとないときでTwitterアカウントを分けたい
      • iftttアカウント1つに対し,Twitterアカウントは1つしか登録できない(はず)
      • つまり複数アカウントからツイートしたい場合同数のiftttアカウントを作る必要があり管理が面倒
    • botメンテが面倒
      • ツイートの種類数分,iftttのappletを独立に新規作成している
      • bot改修のたびにプログラムと機能数分のappletを矛盾なく変更するのが面倒

つまり今回やりたいこと:iftttを使わずに複数アカウントからツイートできるようにする

Step1. システムのしくみ

  • iftttを利用しないしくみに変えた.
  • 同時にメンテの有無によってアカウントを分けるように変更した.

以前のシステム

f:id:cactus_k:20190708171006p:plain
以前のしくみ

新しいシステム

f:id:cactus_k:20190708171019p:plain
新しいしくみ

Step2. プログラムからのツイート

Twitter appの作成とアクセストークンの取得

Consumer Key
Consumer Secret
Access Token
Accesss Token Secert

の4つの英数字列がアクセストークンで,これをあとで使う.

python3からのツイート

  • 前記事のpython3で書いたメンテ判定のプログラムを使いたい為,python3を利用する前提で作成.

    基本的なしくみ

    これ↓を参考にした.

qiita.com

上で紹介されているコードで使われているライブラリが↓.

requests-oauthlib.readthedocs.io

Requests-OAuthlib uses the Python Requests and OAuthlib libraries to provide an easy-to-use Python interface for building OAuth1 and OAuth2 clients.

というものらしく, pythonで画像付きツイートをしたい人はだいたいこれを使っていた.

複数アカウント対応

一つのコードから複数のアカウントを利用するので,アカウント切り替えがしやすいように整備.

アクセストークンの登録

入れ子にした辞書型を使うと便利. 以下のように別ファイルsecret_cactus.pyに記述.

twDict = {'mainte':{
    'consumer_key' : 'xxxxxxxxxxxxxxxx',
    'consumer_secret' : 'xxxxxxxxxxxxxxxx',
    'access_token_key' : 'xxxxxxxxxxxxxxxx',
    'access_token_secret' : 'xxxxxxxxxxxxxxxx'
    },
    'nomainte':{
    'consumer_key' : 'xxxxxxxxxxxxxxxx',
    'consumer_secret' : 'xxxxxxxxxxxxxxxx',
    'access_token_key' : 'xxxxxxxxxxxxxxxx',
    'access_token_secret' : 'xxxxxxxxxxxxxxxx'
    }
}

これを以下のように取り込む.

(別ファイルimportだけして直接右辺の形で使ってもよいのだが,長くなるので以下のようにした)

import secret_cactus
pw = {}
pw['mainte'] = secret_cactus.twDict['mainte']
pw['nomainte'] = secret_cactus.twDict['nomainte']
ツイート関数

先述の記事を参考にしてアカウント切り替えがしやすい関数を作成した.

以下のように添付画像pic,投稿文字列messageに加えアカウント名tw_acを引数にとる関数を作成.引数で指定したアカウントのトークンを辞書から探してきてOAuth認証する.

def tweet_with_pic(tw_ac, pic, message): # 文字列,文字列,文字列
    # OAuth認証 セッションを開始
    tweet_ac = OAuth1Session(pw[tw_ac]['consumer_key'], pw[tw_ac]['consumer_secret'], pw[tw_ac]['access_token_key'], pw[tw_ac]['access_token_secret'])

    # 画像投稿
    files = {"media" : open(pic, 'rb')}
    req_media = tweet_ac.post(url_media, files = files)

    # レスポンスを確認
    if req_media.status_code != 200:
        print ("画像アップデート失敗: %s", req_media.text)
        exit()

    # Media ID を取得
    media_id = json.loads(req_media.text)['media_id']
    print ("Media ID: %d" % media_id)

    # Media ID を付加してテキストを投稿
    params = {'status': message, "media_ids": [media_id]}
    req_media = tweet_ac.post(url_text, params = params)

    # 再びレスポンスを確認
    if req_media.status_code != 200:
        print ("テキストアップデート失敗: %s", req_text.text)
        exit()

    print ("OK")

プログラムの定期自動実行

ミスミメンテbotをつくった(簡易版) - さぼてんメモ

と同じくherokuを利用.

利用するライブラリが増えたら忘れずにrequirements.txtに書き足すことに注意.

Step3. できたコード全体

以前のプログラムをベースに作成したもの. メンテ予告メッセージ取得や状況に応じた投稿内容はほぼそのまま.

  • 本体
  • requirements.txt
django
gunicorn
django-heroku
lxml
requests
requests_oauthlib

参考文献

OAuthのイメージがわかりやすかった記事 https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be