Created
April 13, 2009 05:17
-
-
Save nurse/94284 to your computer and use it in GitHub Desktop.
twitter bot for nadoka
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*-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