lib/sailthru.rb in sailthru-client-2.0.0 vs lib/sailthru.rb in sailthru-client-3.0.0

- old
+ new

@@ -7,15 +7,18 @@ require 'digest/md5' require 'net/http/post/multipart' module Sailthru - Version = VERSION = '2.0.0' + Version = VERSION = '3.0.0' class SailthruClientException < Exception end + class SailthruUnavailableException < Exception + end + module Helpers # params: # params, Hash # returns: # Array, values of each item in the Hash (and nested hashes) @@ -100,17 +103,18 @@ # api_key, String # secret, String # api_uri, String # # Instantiate a new client; constructor optionally takes overrides for key/secret/uri and proxy server settings. - def initialize(api_key, secret, api_uri=nil, proxy_host=nil, proxy_port=nil) + def initialize(api_key, secret, api_uri=nil, proxy_host=nil, proxy_port=nil, opts={}) @api_key = api_key @secret = secret @api_uri = if api_uri.nil? then 'https://api.sailthru.com' else api_uri end @proxy_host = proxy_host @proxy_port = proxy_port @verify_ssl = true + @opts = opts end # params: # template_name, String # email, String @@ -124,11 +128,11 @@ # # Send a transactional email, or schedule one for the near future # http://docs.sailthru.com/api/send def send(template_name, email, vars={}, options = {}, schedule_time = nil) warn "[DEPRECATION] `send` is deprecated. Please use `send_email` instead." - send_email(template_name, email, vars={}, options = {}, schedule_time = nil) + send_email(template_name, email, vars, options, schedule_time) end # params: # template_name, String # email, String @@ -136,17 +140,18 @@ # options, Hash # replyto: override Reply-To header # test: send as test email (subject line will be marked, will not count towards stats) # returns: # Hash, response data from server - def send_email(template_name, email, vars={}, options = {}, schedule_time = nil) + def send_email(template_name, email, vars={}, options = {}, schedule_time = nil, limit = {}) post = {} post[:template] = template_name post[:email] = email post[:vars] = vars if vars.length >= 1 post[:options] = options if options.length >= 1 post[:schedule_time] = schedule_time if !schedule_time.nil? + post[:limit] = limit if limit.length >= 1 return self.api_post(:send, post) end def multi_send(template_name, emails, vars={}, options = {}, schedule_time = nil, evars = {}) @@ -319,11 +324,11 @@ data[:vars] = vars unless vars.empty? data[:lists] = lists unless lists.empty? data[:templates] = templates unless templates.empty? self.api_post(:email, data) end - + # params: # new_email, String # old_email, String # options, Hash mapping optional parameters # returns: @@ -334,11 +339,11 @@ data = options data[:email] = new_email data[:change_email] = old_email self.api_post(:email, data) end - + # params: # template_name, String # returns: # Hash of response data. # @@ -382,10 +387,11 @@ [:action, :email, :send_id, :sig].each { |key| return false unless params.has_key?(key) } return false unless params[:action] == :verify sig = params.delete(:sig) + sig = sig.delete_if {|key, value| key == :controller} return false unless sig == get_signature_hash(params, @secret) _send = self.get_send(params[:send_id]) return false unless _send.has_key?(:email) @@ -407,17 +413,18 @@ [:action, :email, :sig].each { |key| return false unless params.has_key?(key) } return false unless params[:action] == 'optout' sig = params.delete(:sig) + sig = sig.delete_if {|key, value| key == :controller} return false unless sig == get_signature_hash(params, @secret) return true else return false end end - + # params: # params, Hash # request, String # returns: # TrueClass or FalseClass, Returns true if the incoming request is an authenticated hardbounce post. @@ -426,10 +433,11 @@ [:action, :email, :sig].each { |key| return false unless params.has_key?(key) } return false unless params[:action] == 'hardbounce' sig = params.delete(:sig) + sig = sig.delete_if {|key, value| key == :controller} return false unless sig == get_signature_hash(params, @secret) return true else return false end @@ -573,30 +581,30 @@ end # params # list, String # - # Get information about a list. + # Get information about a list. def get_list(list) return api_get(:list, {:list => list}) end # params # - # Get information about all lists + # Get information about all lists def get_lists() - return api_get(:list, {}) + return api_get(:list, {}) end # params # list, String # options, Hash # Create a list, or update a list. def save_list(list, options = {}) data = options data[:list] = list - return api_post(:list, data) + return api_post(:list, data) end # params # list, String # @@ -667,46 +675,46 @@ if !postback_url.nil? data['postback_url'] = postback_url end api_post(:job, data, binary_key) end - + # params # emails, String | Array - # implementation for import_job - def process_import_job(list, emails, report_email = nil, postback_url = nil) - data = {} + # implementation for import_job + def process_import_job(list, emails, report_email = nil, postback_url = nil, options = {}) + data = options data['list'] = list data['emails'] = Array(emails).join(',') process_job(:import, data, report_email, postback_url) end - + # implementation for import job using file upload - def process_import_job_from_file(list, file_path, report_email = nil, postback_url = nil) - data = {} + def process_import_job_from_file(list, file_path, report_email = nil, postback_url = nil, options = {}) + data = options data['list'] = list data['file'] = file_path process_job(:import, data, report_email, postback_url, 'file') end # implementation for update job using file upload - def process_update_job_from_file(file_path, report_email = nil, postback_url = nil) - data = {} + def process_update_job_from_file(file_path, report_email = nil, postback_url = nil, options = {}) + data = options data['file'] = file_path process_job(:update, data, report_email, postback_url, 'file') end # implementation for snapshot job - def process_snapshot_job(query = {}, report_email = nil, postback_url = nil) - data = {} + def process_snapshot_job(query = {}, report_email = nil, postback_url = nil, options = {}) + data = options data['query'] = query process_job(:snapshot, data, report_email, postback_url) end # implementation for export list job - def process_export_list_job(list, report_email = nil, postback_url = nil) - data = {} + def process_export_list_job(list, report_email = nil, postback_url = nil, options = {}) + data = options data['list'] = list process_job(:export_list_data, data, report_email, postback_url) end # get status of a job @@ -714,98 +722,98 @@ api_get(:job, {'job_id' => job_id}) end # Get user by Sailthru ID def get_user_by_sid(id, fields = {}) - api_get(:user, {'id' => id, 'fields' => fields}) + api_get(:user, {'id' => id, 'fields' => fields}) end # Get user by specified key def get_user_by_key(id, key, fields = {}) - data = { - 'id' => id, - 'key' => key, - 'fields' => fields - } - api_get(:user, data) + data = { + 'id' => id, + 'key' => key, + 'fields' => fields + } + api_get(:user, data) end # Create new user, or update existing user def save_user(id, options = {}) - data = options - data['id'] = id - api_post(:user, data) + data = options + data['id'] = id + api_post(:user, data) end - # params - # Get an existing trigger + # params + # Get an existing trigger def get_triggers() - api_get(:trigger, {}) + api_get(:trigger, {}) end - # params - # template, String - # trigger_id, String - # Get an existing trigger + # params + # template, String + # trigger_id, String + # Get an existing trigger def get_trigger_by_template(template, trigger_id = nil) - data = {} - data['template'] = template - if trigger_id != nil then data['trigger_id'] = trigger_id end - api_get(:trigger, data) + data = {} + data['template'] = template + if trigger_id != nil then data['trigger_id'] = trigger_id end + api_get(:trigger, data) end - # params - # event, String - # Get an existing trigger + # params + # event, String + # Get an existing trigger def get_trigger_by_event(event) - data = {} - data['event'] = event - api_get(:trigger, data) + data = {} + data['event'] = event + api_get(:trigger, data) end - # params - # template, String - # time, String - # time_unit, String - # event, String - # zephyr, String - # Create or update a trigger + # params + # template, String + # time, String + # time_unit, String + # event, String + # zephyr, String + # Create or update a trigger def post_template_trigger(template, time, time_unit, event, zephyr) - data = {} - data['template'] = template - data['time'] = time - data['time_unit'] = time_unit - data['event'] = event - data['zephyr'] = zephyr - api_post(:trigger, data) + data = {} + data['template'] = template + data['time'] = time + data['time_unit'] = time_unit + data['event'] = event + data['zephyr'] = zephyr + api_post(:trigger, data) end - # params - # template, String - # time, String - # time_unit, String - # zephyr, String - # Create or update a trigger + # params + # template, String + # time, String + # time_unit, String + # zephyr, String + # Create or update a trigger def post_event_trigger(event, time, time_unit, zephyr) - data = {} - data['time'] = time - data['time_unit'] = time_unit - data['event'] = event - data['zephyr'] = zephyr - api_post(:trigger, data) + data = {} + data['time'] = time + data['time_unit'] = time_unit + data['event'] = event + data['zephyr'] = zephyr + api_post(:trigger, data) end - # params - # id, String - # event, String - # options, Hash (Can contain vars, Hash and/or key) - # Notify Sailthru of an Event + # params + # id, String + # event, String + # options, Hash (Can contain vars, Hash and/or key) + # Notify Sailthru of an Event def post_event(id, event, options = {}) - data = options - data['id'] = id - data['event'] = event - api_post(:event, data) + data = options + data['id'] = id + data['event'] = event + api_post(:event, data) end # Perform API GET request def api_get(action, data) api_request(action, data, 'GET') @@ -868,11 +876,11 @@ if (!binary_key.nil?) binary_data = data[binary_key] if binary_data.is_a?(StringIO) data[binary_key] = UploadIO.new( - binary_data, "text/plain" + binary_data, "text/plain", "local.path" ) else data[binary_key] = UploadIO.new( File.open(binary_data), "text/plain" ) @@ -922,16 +930,22 @@ http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(_uri.host, _uri.port) if _uri.scheme == 'https' http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify_ssl != true # some openSSL client doesn't work without doing this + http.ssl_timeout = @opts[:http_ssl_timeout] || 5 end + http.open_timeout = @opts[:http_open_timeout] || 5 + http.read_timeout = @opts[:http_read_timeout] || 10 + http.close_on_empty_response = @opts[:http_close_on_empty_response] || true response = http.start { http.request(req) } + rescue Timeout::Error, Errno::ETIMEDOUT => e + raise SailthruUnavailableException.new(["Timed out: #{_uri}", e.inspect, e.backtrace].join("\n")); rescue Exception => e raise SailthruClientException.new(["Unable to open stream: #{_uri}", e.inspect, e.backtrace].join("\n")); end if response.body @@ -940,20 +954,20 @@ raise SailthruClientException.new("No response received from stream: #{_uri}") end end def http_multipart_request(uri, data) - req = Net::HTTP::Post::Multipart.new url.path, + Net::HTTP::Post::Multipart.new url.path, "file" => UploadIO.new(data['file'], "application/octet-stream") end def prepare_json_payload(data) - payload = { - :api_key => @api_key, - :format => 'json', #<3 XML - :json => data.to_json - } - payload[:sig] = get_signature_hash(payload, @secret) - payload + payload = { + :api_key => @api_key, + :format => 'json', #<3 XML + :json => data.to_json + } + payload[:sig] = get_signature_hash(payload, @secret) + payload end end end