Skip to content

Instantly share code, notes, and snippets.

@nurse
Created April 13, 2009 05:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nurse/94284 to your computer and use it in GitHub Desktop.
Save nurse/94284 to your computer and use it in GitHub Desktop.
twitter bot for nadoka
# -*-ruby-*-
#
# Acknowledgement
# @ko1_twitter
# http://uno.ac/d/20070727.html
# http://iseebi.half-done.net/diary/?date=20070417#p01
# http://mono.kmc.gr.jp/~yhara/d/?date=20070421#p02
# http://www.rubyist.net/~nobu/t/20051013.html#p02
require 'cgi'
require 'net/http'
require 'nkf'
require 'rexml/document'
require 'time'
class TwitterBot < Nadoka::NDK_Bot
def bot_initialize
@ch = @bot_config.fetch(:ch, nil)
@user = @bot_config.fetch(:user, nil)
@passwd = @bot_config.fetch(:passwd, nil)
@pattern = @bot_config.fetch(:pattern, /\s\.$/)
@timeout = @bot_config.fetch(:timeout, 60)
@proxy_addr = @bot_config.fetch(:proxy_addr, nil)
@proxy_port = @bot_config.fetch(:proxy_port, 80)
@data = {
:timeline => {
:req => Net::HTTP::Get.new("/statuses/friends_timeline.xml"),
:xpath => '/statuses/status',
:sender => 'user',
:id => -1
},
:direct => {
:req => Net::HTTP::Get.new("/direct_messages.xml"),
:xpath => '/direct-messages/direct_message',
:sender => 'sender',
:id => -1
}
}.each_value{|d|d[:req].basic_auth @user,@passwd}
end
def bot_state
"<#{self.class.to_s} user: #{@user}>"
end
def slog(msg, nostamp = false)
current_method = caller.first[/:in \`(.*?)\'/, 1].to_s
msg.each_line do |line|
@logger.slog "#{self.class.to_s}##{current_method} #{line}", nostamp
end
end
def on_timer(t)
results = []
Net::HTTP::Proxy(@proxy_addr, @proxy_port).start('twitter.com', 80) do |http|
@data.each_value do |data|
current_id = data[:id]
body = http.request(data[:req]).body
doc = REXML::Document.new(body)
doc.each_element(data[:xpath]) do |elem|
id = elem.elements['id'].text.to_i
next unless current_id < id
data[:id] = id if data[:id] < id
time = Time.parse(elem.elements['created_at'].text)
text = elem.elements['text'].text
user = elem.elements[data[:sender]].elements['screen_name'].text
results << [id, time, text, user]
end
end
end
results.sort_by{|v|v[1]}.each do |id, time, text, user|
text = NKF.nkf('--ic=UTF-8 --oc=CP50221', CGI.unescapeHTML(text).gsub(/\n/," "))
send_notice @ch, "#{time.strftime('%H:%M')} #{user}: #{text}"
end
rescue Exception => e
slog "Exception\n" + e.message
end
def send_twitter(status)
req = Net::HTTP::Post.new('/statuses/update.json')
req.basic_auth @user, @passwd
req.body = 'status=' + URI.encode(NKF.nkf('--ic=CP50221 --oc=UTF-8', status))
Net::HTTP::Proxy(@proxy_addr, @proxy_port).start('twitter.com',80) {|http|
http.read_timeout = @timeout
res = http.request(req)
@logger.dlog res.body
}
return true
rescue Exception => e
slog "Exception\n" + e.message
return false
end
def on_client_privmsg(client, ch, message)
return unless @ch.nil? or @ch.upcase == ch.upcase
return unless @pattern =~ message
status = message.sub(@pattern, '')
msg = send_twitter(status) ? 'sent to twitter: ' : 'twitter send faild: '
msg << status
slog msg
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment