この記事は下記の記事の続きです。
Twitter botを作成していましたが、メンションに反応するために必要なUser Streams APIが2018年に終わっていました。したがってTwitter APIで実現させなければなりません。そこで今回は自前でメンションに反応するスクリプトを作成しました。このスクリプトは、cronで1分ごとに実行しています。前回に引き続きtwitter
gemを使用します。
Twitterの“User Streams API”が完全終了 ~それでもリアルタイム更新を楽しむ方法 - やじうまの杜 - 窓の杜
require "twitter" require "redis" class Card #省略 end def get_image(client) #省略 end client = Twitter::REST::Client.new do |config| config.consumer_key = "" config.consumer_secret = "" config.access_token = "" config.access_token_secret = "" end redis = Redis.new client.mentions_timeline.each do |tweet| tweet_id = tweet.id unless redis.get(tweet_id) pos = tweet.text =~ /ドロー|draw|Draw/ if pos retry_count = 0 card = nil while true card = get_image(client) if card || retry_count > 5 break end retry_count += 1 end if card client.update_with_media("@#{tweet.user.screen_name} あなたが引いたカードは『#{card.name}』", card.img_uri, in_reply_to_status: tweet) end end end redis.set(tweet_id, tweet.user.screen_name) end
メンションされたツイートのタイムラインを取得します
Twitter::REST::Client#mentions_timeline
を呼び出して、メンションされたツイートのタイムラインを取得します。optionで取得件数を制限できるようですが、今回はしませんでした。
client.mentions_timeline.each do |tweet|
Redisで過去に返したメンションを記録します
下記の部分はRedisを用いて、過去にメンションされて返信済みのツイートか判定しています。DBを構築するほどではなかったので、Redisで手軽にできないかどうか模索してい見ました。unless redis.get(tweet_id)
で、過去に返信したツイートを取得できなかった場合は、返信を行った後にredis.set(tweet_id, tweet.user.screen_name)
でRedisのキーにツイートIDを記録します。Valueはなんでもよいので適当にしています。
redis = Redis.new # 省略 unless redis.get(tweet_id) # 省略 redis.set(tweet_id, tweet.user.screen_name)
正規表現で返信するワードを制限します
Twitter::Tweet#text
でツイートの内容を取得できます。すべてのメンションされたツイートに反応するのではなく、特定のワードのみに反応したいので、正規表現を利用しています。ここでは「ドロー」「draw」「Draw」の3つの単語に反応するようにします。
pos = tweet.text =~ /ドロー|draw|Draw/ if pos #省略 end
メンション元のユーザIDを取得します
tweet.user.screen_name
は、メンション元のユーザIDです。したがって、このユーザIDにメンションします。
client.update_with_media("@#{tweet.user.screen_name} あなたが引いたカードは『#{card.name}』", card.img_uri, in_reply_to_status: tweet)
これぐらいの規模であればRDBではなく、Redis(KVS)で十分だと思いましたが、予想通りでした。特にスクリプトを実行するうえで不便はしてません。またこれぐらいの軽い処理を行うときはKVSを用いるかもしれません。