にたまごほうれん草アーカイブ

はてなダイアリーで書いてた「にたまごほうれん草」という日記のアーカイブです。現在は「にたまごほうれん草ブログ」を運営中です。

nadokaのBOTを作ってみる

IRCプロキシmadokaRubyクローンであるnadoka用のBOTプログラムを作成してみました。携帯などからIRCに発言できるものを作りたかったから。(keitaircを使えば簡単なんでしょうけど、一応Rubyの勉強がてら、ということで)

今回作成したのは、外部からの発言を受け付けるプラグインnadokaを起動すると同時にスレッドを作成し、TCPServerで受信待機し、受け取ったコメントを発言します。あとはこれに対してメッセージを投げるためのインタフェースを作らないといけませんが、もう少しかかりそうです。

メッセージはハッシュで作成し、YAML形式の文字列に変換してやりとりします。これが一番通信量が減っていいかと。JSONも試してみたいところですが。(あんまり変わらないかな)

# -*-ruby-*-
require 'socket'
require 'yaml'
require 'kconv'

=begin

BotConfig example:
    {
      :name => 'WebGateBot',
      :port => '10080',
      :default_name => 'no name',
      :channel => {
        :web => '#webdev',
        :bt   => '#bottest',
      }
    },

=end

class WebGateBot < Nadoka::NDK_Bot
  def bot_initialize
    @channel = @bot_config[:channel]
    @port = @bot_config[:port].to_i || 10080
    @default_name = @bot_config[:default_name] || 'anony'

    @socket = nil
    @th = start_thread
    @th_flag = true
  end

  def bot_destruct
    @th_flag = false
    @socket.close if @socket

    if @th.alive?
      @th.join
    end
  end

  def start_thread
    th = Thread.start {
      server_loop
    }
    th
  end

  def server_loop
    @socket = TCPServer.open('localhost', @port)
    @socket.listen(5)

    while true
      Thread.start(@socket.accept) {|rs|
        input = rs.read

        begin
          yaml = YAML.load(input)
          mode = yaml['mode']
          case mode
          when 'post'
            post_msg yaml
          else
          end
        rescue
          puts "Unformatted Message"
        ensure
          rs.close
        end
      }
      break if @th_flag == false
    end
  end

  def post_msg yaml
    ch_id = yaml['ch_id']
    user = yaml['user']
    if user == ''
      user = @default_name
    end
    msg  = yaml['msg']

    unless msg == ''
      send_privmsg get_channel(ch_id), make_msg(user, msg).tojis
    end
  end

  def get_channel ch_id
    ret = nil
    @channel.each {|k,v|
#      if k == ch_id.intern
      if k.to_s == ch_id
        ret = v.tojis
      end
    }
    ret
  end

  def make_msg user, msg
    str = "(#{user}) #{msg}"
    str
  end
end

途中箇所でmodeでpostに振り分けているのは、将来的にここからログを取得できるようにgetも追加しようかどうかとかいうそういう考え。