MENU

溶けかけてるうさぎ HP BLOG TOP RECENT ARTICLES POPULAR ARTICLES ABOUT THIS BLOG

CATEGORY

大学 (85) 航空宇宙 (55) 写真 (25) 旅行 (14) 飯・酒 (11) コンピュータ (88) その他 (13)

TAG

ARCHIVE

2018 (92) 2017 (80) 2016 (0)

RECENT

【駅メモ】4年目に突入して,ようやく3000駅突破 【WebRTC】Raspberry Pi搭載ロボットをWebRTCで遠隔操作しようとして失敗した 【航空宇宙】航空宇宙アドベントカレンダー 始まります! 【Perl】YAPC::Tokyo 2019 のチケットを確保しました! 【カメラ】Canonから富士フイルムに乗り換えました

【Twitter Bot】TLの334ツイートに対して,ツイート時刻をミリ秒精度でReplyする

2017-08-05

334ツイート競争において,自分や他人のツイートの正確な時間が知りたいことがある.

公式クライアントからでは分単位でしかわからないので,ミリ秒単位でリプを飛ばしてくれるBotを作成した.

 

トップ画像の出典はこちら

1.はじめに

この記事は,「」の」の続きである.

Twitter APIなどの環境構築については,こちらを参照のこと.

2.動作環境

Ubuntu Server 16.04.2 LTS

Python 2.7.12

3.Pythonスクリプト

TLより334を含むツイートを取得し,ツイート時刻を返すスクリプトは下のようになる.

ツイートIDから時刻を取得する方法は,を参考にした.(はおそらくRubyで実装していた.)

 

また,APIを叩いて返ってくるJSONは,どうやらユニコード文字列のようだ.(つまりPythonのstr関数は使えない.)

# coding: UTF-8
import sys
import os
from requests_oauthlib import OAuth1Session
import json
import time
import datetime
import locale

CONSUMER_KEY        = '*************************'
CONSUMER_SECRET     = '**************************************************'
ACCESS_TOKEN        = '**************************************************'
ACCESS_TOKEN_SECRET = '*********************************************'
LOG_FILE = '${path}/log_334.log'

def main(args):
    twitter = OAuth1Session(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

    # TL取得
    params =  { "count"           : 200,       # ツイートを最新から何件取得するか(最大200件)
                "exclude_replies" : "true",    # リプライを含めないか
              }
    req = twitter.get("https://api.twitter.com/1.1/statuses/home_timeline.json", params = params)
    timeline = json.loads(req.text)

    if (str(req) != "<Response [200]>"):
        # 追記モードで出力
        f = open(LOG_FILE, "a")
        try:
            # 文字列を出力
            f.write(GetStringTime()+"\t"+str(req)+"\tat home_timeline.json\n")
              #=> test12345test
        finally:
            f.close()

    ps(req)
    ps("\n")
    ps("##############################\n")

    i = 0;
    for tlTweet in timeline:
        ps("["+str(i)+"]\n")
        i += 1;
        ps(tlTweet["id"])
        ps("\n")
        ps(tlTweet["user"]["screen_name"])
        ps("\n")
        # 基本的にユニコード文字列? 取得できるJsonって.
        ps(tlTweet["text"].encode('utf-8'))
        # pu(tlTweet["text"])
        ps("\n")
        if (tlTweet["text"].find(u'334') > -1):
            # リプ飛ばす
            st = TweetId2Time(int(tlTweet["id"]))
            params =   {"status"                : "@" + tlTweet["user"]["screen_name"] + u"\nついーと時刻は,\n" + st + u"\nです.\n[Bot]",
                        "in_reply_to_status_id" : tlTweet["id"],
                        }
            req = twitter.post("https://api.twitter.com/1.1/statuses/update.json", params = params)
            if (str(req) != "<Response [200]>"):
                # 追記モードで出力
                f = open(LOG_FILE, "a")
                try:
                    # 文字列を出力
                    f.write(GetStringTime()+"\t"+str(req)+"\tat update.json\n")
                finally:
                    f.close()
            ps(req)
            ps("\n==================================\n")
            ps("\n\n")


    ps("\n")
    ps("\n")


def ps(output):
    sys.stdout.write(str(output))
    sys.stdout.flush()


def pu(output):
    sys.stdout.write(output)
    sys.stdout.flush()


def TweetId2Time(id):
    epoch = ((id >> 22) + 1288834974657) / 1000.0
    d = datetime.datetime.fromtimestamp(epoch)
    stringTime = ""
    stringTime += str(d.year)
    stringTime += '-'
    stringTime += '{0:02d}'.format(d.month)
    stringTime += '-'
    stringTime += '{0:02d}'.format(d.day)
    stringTime += ' '
    stringTime += '{0:02d}'.format(d.hour)
    stringTime += ':'
    stringTime += '{0:02d}'.format(d.minute)
    stringTime += ':'
    stringTime += '{0:02d}'.format(d.second)
    stringTime += '.'
    stringTime += '{0:03d}'.format(d.microsecond / 1000)
    return stringTime


def GetStringTime():
    d = datetime.datetime.today()
    stringTime = str(d.year)
    stringTime += '.'
    stringTime += '{0:02d}'.format(d.month)
    stringTime += '.'
    stringTime += '{0:02d}'.format(d.day)
    stringTime += '-'
    stringTime += '{0:02d}'.format(d.hour)
    stringTime += '.'
    stringTime += '{0:02d}'.format(d.minute)
    stringTime += '.'
    stringTime += '{0:02d}'.format(d.second)
    stringTime += '.'
    stringTime += '{0:02d}'.format(d.microsecond / 10000)
    return stringTime


if __name__ == '__main__':
    main(sys.argv)
334timechecker.py

今回も例によって例の如くソースコード編集ユーザーと実行ユーザーが違ったので,適当にパーミッションを変更.

$ sudo chmod 767 334timechecker.py

4.cronに定期実行の登録

今回は3:35と3:40に実行するようにした.

重複してReplyを送ってしまいそうだが,Twitterでは短い時間内に同じ内容を投稿できず,APIを叩いたときに403が返ってくるので,ひとまずは問題ない.

まあ,暇な時にでもきちんと実装します.

# バックアップは重要
$ crontab -l > ~/crontab.backup

$ crontab -e

# 以下を追記
35,40 3 * * * python /home/share/script/twitter/334timechecker.py > /dev/null 2>&1

5.関連記事

6.参考サイト

GitHub. requests/requests-oauthlib. Retrieved August 3, 2017, from https://github.com/requests/requests-oauthlib
Twitter Developer Documentation. POST statuses/update. Retrieved August 3, 2017, from https://dev.twitter.com/rest/reference/post/statuses/update
Twitter Developer Documentation. GET statuses/home_timeline. Retrieved August 3, 2017, from https://dev.twitter.com/rest/reference/get/statuses/home_timeline
ソフトウェアエンジニアのためのtips. Python > 時間の処理. Retrieved August 3, 2017, from http://sweng.web.fc2.com/ja/program/python/time.html
Qiita. ツイートIDからツイート時刻をミリ秒まで算出(ついでに時刻からツイートIDを作成). Retrieved August 3, 2017, from http://qiita.com/riocampos/items/e5544325211976f2cfc1

コメントを投稿

名前

Email (※公開されることはありません)

コメント