鳥小屋.txt

主に自作ゲームをつくったりしているよ。制作に関することやそうじゃないことのごった煮ブログ

RubyでTwitterBotを簡単(※当社比)につくるRTwBot

最近、開発者に対してツンツン全開のTwitterさんですが、
なんか突然、前に作って止めたまま放置していたbotを動かしたくなりました!(

ちなみに前のbotが止まった理由は、botを動かしていたマシンを
うっかりそのまま初期化してしまい、ソースコードをふっ飛ばしたせいです。
いや、そもそも研究室のPCでTwitterのbot動かしてたことがおかしいんですが。

前回は外部に正規表現とツイート候補を書いたJSON形式の
辞書ファイル的なものを用意してやっていました。
でも、このやり方だと、ツイート以外の動作を求める場合、
(例えば「フォローして」というリプライに対してフォローしてあげる)
結局辞書に動作を書けずにハードコーディングすることになったり、
処理があっちこっちに行って頭が沸騰しちゃうよぉ><という問題が……

そこで、Sinatraみたいに「RubyだけどRubyじゃない!でもRuby!」とような感じに
botを作ることができたら、前回より簡単に作れるかも!(※当社比)
DSLとか言うんですか? いまいち定義がよくわからんです。

そんなわけで本題

RTwBotっていうのを作ってみました。*1

RTwBot · GitHub

これを使うと、こんな感じに記述できます。

※Ubuntu12.04 + Ruby1.9.3です

#!/usr/bin/env ruby
# coding: utf-8
require './rtwbot.rb'

# 設定ファイル(APIキーとかを書いたYAMLファイル)を読み込む
RTwBot.load('./bot_setting.yaml') do
  # 自分からツイート
  own do
    # 前回発言から30分(60x60x30秒)経っていなければ中止
    return if Time.now - save_data.last_own_time < 60 * 60 * 30

    # ツイート候補に追加(add)
    add '@ru_shalm (笑)'
    add '@ru_shalm 働けニート!'
    add '@ru_shalm 無能乙'
  end 
end

これは30分に1回、@ru_shalmをdisリプライを送るbotです。
own doの中でaddされた文字列の中から最終的に1つを選択してツイートします。
save_data.last_own_timeに前回のツイート時刻が入っているので、
それを参考に30分以上経っているか調べています。

このスクリプトをcronかなんかで定期的に叩いてれば、
僕をdisり続けることができるわけですね! 無能乙!

TLへの反応、リプライ反応

own以外にも、TLに反応するtl、リプライに反応するreplyがあります。
ありますというか、付けました。

RTwBot.load('./bot_setting.yaml') do
  # TLへの反応
  tl do |tweet|
    # @ru_shalm以外のツイートには反応しない
    return unless tweet.user.screen_name == 'ru_shalm'
    # とにかくdisる
    add 'ツイートすんな'
    add '垢消せ'
    add '^^'
  end

  # リプライへの反応
  reply do |tweet|
    # @ru_shalmからのリプライはシカト
    return if tweet.user.screen_name == 'ru_shalm'

    # @ru_shalmじゃないので、とりあえず褒めてみる
    add 'かっこいいですね!'
    add 'すごい!'
  end
end

反応系は自動的に頭に「@相手のアカウント名」が付きます。
公式/非公式RTにして晒し上げる方法は考えてませんでした。そのうち付けますん。

設定ファイルはこんな感じ

RTwBot.loadで読み込ませる設定ファイルはこんな感じ。
APIキーとデータ保存先を指定するだけです。
あとテストモード用のフラグがあります。実験中に他の人に変なリプライ送ると困るので。

# APIキーの設定
consumer_key:        '自分のを入力'
consumer_key_secret: '自分のを入力'
access_token:        '自分のを入力'
access_token_secret: '自分のを入力'

# botのデータ保存先
savefile: 'save/bot.dat'

# 本文末尾につける文字列
footer: ''

# テストモード(0:本番 1:投稿処理をパス)
testmode: 0

機能紹介おわり

他にもsave_dataの中にデータいろいろ保存できたり、いろいろ機能ある気もしますが、
そもそもRTwBotは僕がbotを動かすために使うだけのシステムなので、
僕の思いつきで仕様が決定/変更されるため、ドキュメントがありません!!

1週間くらい実験で動かしてたbotのコードを貼っておくので、
それがドキュメントってことでいいんじゃないかな(投げやり)

あと、間違っても上のサンプル(?)を実行しないでください。凹むので。

おまけ:しゃるむ@保守botのコード

#!/usr/bin/env ruby
# coding: utf-8
#

require './rtwbot.rb'

RTwBot.load('./shalm_config.yaml') do
  # 自分からツイート
  own do
    # 次回予定時刻以内の場合中断
    return if save_data['next_own'] and Time.now < save_data['next_own']
    # 次回予定時刻の作成(30〜90分後)
    save_data['next_own'] = Time.now + (60 * 45 + rand(60))

    # 就寝開始
    if time?("0:00〜5:59")
      # 就寝の挨拶を設定
      add 'そろそろ寝るね、おやすみー'
      add 'おやすみなさい……'
      add 'ぴーががぴー、システムを終了します。'
      # 明日の起床時間を決定(午前8時)
      now = Time.now
      save_data['next_own'] = Time.local(now.year, now.month, now.day, 8, 0)
      # 就寝フラグを立てる
      save_data['sleeping'] = true
      return # 中断
    end

    # 起床
    if save_data['sleeping']
      # 起床の挨拶を設定
      add 'おはよー'
      add 'しゃるむむくりなう'
      add 'ぴーがぴぴー、システム起動中です。'
      # 就寝フラグを下ろす
      save_data['sleeping'] = false
      return # 中断
    end
 
    # 時間帯別ツイート
    if time?("6:00〜11:59")
      add '眠いよー'
    elsif time?("12:00〜12:59")
      add 'お昼だよー'
    elsif time?("13:00〜16:29")
      add '裏山なう'
    elsif time?("16:30〜18:59")
      add '夕方だね'
      add 'そろそろ帰ろうかな'
    elsif time?("19:00〜19:59")
      add 'ごはんだよ'
      add 'おなかすいたなー'
    elsif time?("20:00〜22:59")
      add 'もう真っ暗だね'
      add '明日は晴れるかな?'
    elsif time?("23:00〜2:00")
      add 'うとうと…'
      add '...zzZ'
    end

    # 時間関係無しのランダム発言

    # 旧しゃるむbotより
    add '定期発言するよー'
    add '葉っぱってゆーな!'
    add 'めっせつーけーめんーつよんでーRuが……葉っぱってゆーな!'
    add '[背を伸ばす方法    ] [Google 検索]'
    add 'ねねむい'
    add '……zz……ね、寝てないよ'
    add '3、2、1、はじむ!'
    add '定期発言、と思うじゃん? しないんですねー'
    add '【急.募】うちの無能作者を少しマシにできる薬'
    add 'ついったーなう?'

    # 機械的な
    add 'ぴーががぴー'
    add '異常ありません'
    add '例外が発生しました。が、握りつぶしました。'
    
    # Ruたんをdisるだけの簡単なお仕事
    add '毎日ネトゲばっかりやってる男の人って……'
    add '制作もロクにしない男の人って……'
    add '@ru_shalm 働けニート!!'

    # ステマ(
    add '【ステマ】ブラウザでできるパズルゲームだよー ◆ 探して!4羽 -retry- http://hazimu.com/saga4rt/'
  end

  # TLに反応
  tl do |tweet|
    # 寝てる時は反応しない
    return if save_data['sleeping']

    # ツイート文章を調べる
    case tweet.text
    when /おはよ|むくり/
      add 'おはよー'
      # 明らかに朝ではない時間帯
      if time?('12:00〜4:00')
        add 'おはよう?'
        add 'お、おそよう?'
      end
    when /おやすみ/
      add 'おやすみー'
      add 'またね'
    when /(おなか|お腹)(|いた)|\#ponponpain/
      add '大丈夫?'
      add '大丈びーがが'
    end
  end

  # Replyに反応
  reply do |tweet|
    # 寝てる時は反応しない
    return if save_data['sleeping']
    
    # ツイート文章を調べる
    case tweet.text
    when /フォローして/
      # Tweet元の相手をフォローする
      follow(tweet.user.screen_name)
      add 'フォローしたよ'
      add 'うん、わかったよ'
      return # 中断
    when /(|)っぱ/
      add '葉っぱってゆーな!'
      add '葉っぱじゃない!'
      return # 中断
    end

    # なんて返せばいいかわからないのでテケトーに
    add 'そだね'
    add 'うん?'
    add 'へー'
    add 'あんまり変なこと言ってると突っつくよ?'
  end
end

*1:RuたんのTwitterのBotの略です。RuたんじゃなくてRubyでもいいけど。