lib/chatterbot/client.rb in chatterbot-0.5.1 vs lib/chatterbot/client.rb in chatterbot-0.6.1

- old
+ new

@@ -1,34 +1,82 @@ module Chatterbot # # routines for connecting to Twitter and validating the bot + # module Client + attr_accessor :screen_name, :client, :search_client - # the Twitter client - attr_accessor :client + # + # the main interface to the Twitter API + # + def client + @client ||= Twitter::Client.new( + :endpoint => base_url, + :consumer_key => client_params[:consumer_key], + :consumer_secret => client_params[:consumer_secret], + :oauth_token => client_params[:token], + :oauth_token_secret => client_params[:secret] + ) + end - # track the access token so we can get screen name when - # registering new bots - attr_accessor :access_token + # + # client for running searches -- for some reason Twitter::Client was overwriting + # the endpoint for searches in a destructive fashion, so I had two + # clients. That appears to be fixed, but if not, this takes care of that problem + # + def search_client + client + # return client + # @search_client ||= Twitter::Client.new( + # :endpoint => base_url, + # :consumer_key => client_params[:consumer_key], + # :consumer_secret => client_params[:consumer_secret], + # :oauth_token => client_params[:token], + # :oauth_token_secret => client_params[:secret] + # ) + end + # + # reset the since_id for this bot to the highest since_id we can + # get, by running a really open search and updating config with + # the max_id + # + def reset_since_id + result = search_client.search("a") + update_since_id(result) + end + + + + # + # the URL we should use for api calls + # + def base_url + "https://api.twitter.com" + end + + + # # default options when querying twitter -- this could be extended # with a language, etc. def default_opts - return {} if since_id <= 0 - { - :since_id => since_id, + opts = { :result_type => "recent" } + opts[:since_id] = since_id if since_id > 0 + + opts end # - # Initialize the Twitter client + # Initialize the Twitter client, and check to see if it has credentials or not + # @return true/false depending on if client has OAuth credentials def init_client - @client ||= TwitterOAuth::Client.new(client_params) + client.credentials? end # # Re-initialize with Twitter, handy during the auth process def reset_client @@ -42,57 +90,53 @@ def require_login(do_update_config=true) init_client login(do_update_config) end - # - # print out a message about getting a PIN from twitter, then output - # the URL the user needs to visit to authorize - # - def get_oauth_verifier(request_token) - puts "Please go to the following URL and authorize the bot.\n" - puts "#{request_token.authorize_url}\n" - puts "Paste your PIN and hit enter when you have completed authorization." - STDIN.readline.chomp - rescue Interrupt => e + # + # simple OAuth client for setting up with Twitter + # + def consumer + @consumer ||= OAuth::Consumer.new( + config[:consumer_key], + config[:consumer_secret], + :site => base_url + ) end # - # Ask the user to get an API key from Twitter. - def get_api_key - puts "****************************************" - puts "****************************************" - puts "**** API SETUP TIME! ****" - puts "****************************************" - puts "****************************************" - - puts "Hey, looks like you need to get an API key from Twitter before you can get started." - puts "Please go to this URL: https://twitter.com/apps/new" + # copied from t, the awesome twitter cli app + # @see https://github.com/sferik/t/blob/master/lib/t/authorizable.rb + # + def generate_authorize_url(request_token) + request = consumer.create_signed_request(:get, + consumer.authorize_path, request_token, + {:oauth_callback => 'oob'}) - print "\n\nPaste the 'Consumer Key' here: " - STDOUT.flush - config[:consumer_key] = STDIN.readline.chomp + params = request['Authorization'].sub(/^OAuth\s+/, '').split(/,\s+/).map do |param| + key, value = param.split('=') + value =~ /"(.*?)"/ + "#{key}=#{CGI::escape($1)}" + end.join('&') - print "Paste the 'Consumer Secret' here: " - STDOUT.flush - config[:consumer_secret] = STDIN.readline.chomp - - reset_client - - # - # capture ctrl-c and exit without a stack trace - # - rescue Interrupt => e -# exit + "#{base_url}#{request.path}?#{params}" end + def request_token + @request_token ||= consumer.get_request_token + end + # - # error message for auth - def display_oauth_error - debug "Oops! Looks like something went wrong there, please try again!" + # query twitter for the bots screen name. we do this during the bot registration process + # + def get_screen_name + return unless @screen_name.nil? + + oauth_response = @access_token.get('/1/account/verify_credentials.json') + @screen_name = JSON.parse(oauth_response.body)["screen_name"] end # # handle oauth for this request. if the client isn't authorized, print # out the auth URL and get a pin code back from the user @@ -104,32 +148,30 @@ if needs_api_key? get_api_key end if needs_auth_token? - request_token = client.request_token - - pin = get_oauth_verifier(request_token) + pin = get_oauth_verifier #(request_token) return false if pin.nil? - @access_token = client.authorize( - request_token.token, - request_token.secret, - :oauth_verifier => pin - ) + begin + # this will throw an error that we can try and catch + @access_token = request_token.get_access_token(:oauth_verifier => pin.chomp) + get_screen_name - if client.authorized? config[:token] = @access_token.token config[:secret] = @access_token.secret - update_config unless do_update_config == false - else + update_config unless ! do_update_config + reset_client + + rescue OAuth::Unauthorized => e display_oauth_error return false end end - true + return true end end end