ブログ・ア・ラ・クレーム

技術的なメモとかライフログとか。

TwitterBotらしき何か、一応完成

とりあえず、ID:@jus_bot としてbotを作ってみました。
(僕の金銭的な問題により、常駐はしておりませぬ)


大体、以下の通りの動作をします
・followingしているユーザの中から、手動で反応する相手のIDを、予め指定し、指定ユーザのつぶやきに反応してreplyする
(返答パターンはYAML形式で予め作成し、botのコードと同じディレクトリに入れておく)
・自発的につぶやきを行う
(つぶやきの内容はYAML形式で予め作成)


以下のような問題点も上がってたり
Twitterから502が返され、プログラムが停止することがあった
・作者がRubyに慣れてないので、コードが汚いし無駄な処理がある^q^







つぶやきの内容を記述するYAMLファイルの例は以下のような感じ
post_list:
- words: 妹充したい
- words: 弟充したい
- words: マリアリはジャスティス

reply_list:
- keyword: でっしゃい
reply: でっしゃい
- keyword: jus_bot
reply: こんにちは。@jus_bot です
- keyword: バイト
reply: バイト乙でっしゃい!






以下、僕の作ったコードを貼ってみるなど
(問題点、不明な点があればコメントにでもよろしくです)



#!/usr/bin/ruby
require 'scanf'
require 'twitter'
require 'yaml'
require 'pp'


# ----------------------------------------------------------------
# ここから個人設定
# ----------------------------------------------------------------

# botTwitter userIDとPassword
user = "botID"
pass = "botPW"

# botが反応する対象のTwitter userID
target = [ "target" ]

# 動作間隔[秒](あまり大きな値にしないこと)
WAIT_TIME = 30

# 自発的postを行う周期(動作間隔何回分に1回動作するか指定)
POST_LIMIT = 3

# botの返答パターンを記述したYAMLファイルの名前
yamlname = "keyword.yaml"

# ---------------------------------------------------------------
# ここまで個人設定
# ---------------------------------------------------------------


str = File.read(yamlname)
keyword = YAML.load(str)["reply_list"]
post_list = YAML.load(str)["post_list"]
post_count = 1


# 最後にpostした時間は最古に設定
last_time = Time.mktime(1970, 1, 1, 9, 0, 0)

# 初回のループでは、replyするまで全てのpostを読む
check_flag = true

# 毎回のループの初回に、前の最新のpost時刻を保存する為のフラグ
first_flag = true

# 通信確立
httpauth = Twitter::HTTPAuth.new(user, pass)base = Twitter::Base.new(httpauth)# メインループ
loop{
# TLを取得し、replyする
catch(:reply_end){
base.friends_timeline.each { |tweet|
time = (tweet.created_at).scanf("%s %s %d %d:%d:%d %d %d")
post_time = Time.mktime(time[7], time[1], time[2], time[3], time[4], time[5])

# 最新時刻を保存
if first_flag then
last_time = post_time
first_flag = false
end
# 既に反応したpostに対しては、反応しない
if last_time > post_time && !check_flag then
break
end

# TLの内容をチェックし、replyを行う
target.each{ |target_user|
if tweet.user.screen_name == target_user then
tmp = Kconv.kconv(tweet.text, Kconv::SJIS)
keyword.each { |pattern|
if tmp.index(pattern["keyword"]) != nil then
puts Kconv.kconv("【reply】@" + target_user + " " + pattern["reply"], Kconv::SJIS)
base.update(Kconv.kconv("@" + target_user + " " + pattern["reply"], Kconv::UTF8))
throw :reply_end
end
}
end
}
}
}

# 自発的post用カウンタが溜まったら、リストからランダムに自発的postを行う
if POST_LIMIT <= post_count then
rand_num = rand(post_list.size)
puts Kconv.kconv("【post】" + (post_list[rand_num])["words"], Kconv::SJIS)
base.update(Kconv.kconv*1
post_count = 0
end

# 次のループの為の処理
check_flag = false
first_flag = true
post_count = post_count + 1
puts "【応答完了】次の応答まで待機します"
sleep WAIT_TIME
}

*1:post_list[rand_num])["words"], Kconv::UTF8