Skip to content

Commit

Permalink
add whitelist/blacklist and readonly configuration options
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeff Ching committed Aug 24, 2011
1 parent c4f94f2 commit 66440fa
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/exact_target.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def send_to_exact_target(request)


data = "qf=xml&xml=#{URI.escape(URI.escape(request), "&")}" data = "qf=xml&xml=#{URI.escape(URI.escape(request), "&")}"
uri = URI.parse(configuration.base_url) uri = URI.parse(configuration.base_url)

http = net_http_or_proxy.new(uri.host, uri.port) http = net_http_or_proxy.new(uri.host, uri.port)
http.use_ssl = configuration.secure? http.use_ssl = configuration.secure?
http.open_timeout = configuration.http_open_timeout http.open_timeout = configuration.http_open_timeout
Expand Down
13 changes: 12 additions & 1 deletion lib/exact_target/configuration.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ module ExactTarget
# Used to set up and modify settings for ExactTarget # Used to set up and modify settings for ExactTarget
class Configuration class Configuration


OPTIONS = [:base_url, :username, :password, OPTIONS = [:base_url, :username, :password, :readonly, :email_whitelist, :email_blacklist
:http_method, :http_open_timeout, :http_read_timeout, :http_proxy].freeze :http_method, :http_open_timeout, :http_read_timeout, :http_proxy].freeze
STANDARD_READONLY_CALLS = [:list_add, :list_edit, :list_import, :list_delete,
:subscriber_add, :subscriber_edit, :subscriber_delete, :subscriber_masterunsub,
:email_add, :email_add_text, :job_send].freeze


# The (optional) base URL for accessing ExactTarget (can be http or https). # The (optional) base URL for accessing ExactTarget (can be http or https).
# Defaults to 'https://api.dc1.exacttarget.com/integrate.aspx' # Defaults to 'https://api.dc1.exacttarget.com/integrate.aspx'
Expand All @@ -30,11 +33,19 @@ class Configuration
# The HTTP method to make the request with # The HTTP method to make the request with
attr_accessor :http_method attr_accessor :http_method


# The (optional) readonly flag (defaults to false)
attr_accessor :readonly

# (optional) limiting triggeredsend email addresses
attr_accessor :email_whitelist
attr_accessor :email_blacklist

def initialize def initialize
@base_url = 'https://api.dc1.exacttarget.com/integrate.aspx' @base_url = 'https://api.dc1.exacttarget.com/integrate.aspx'
@http_open_timeout = 2 @http_open_timeout = 2
@http_read_timeout = 5 @http_read_timeout = 5
@http_method = "get" @http_method = "get"
@readonly = []
end end


def valid? def valid?
Expand Down
31 changes: 31 additions & 0 deletions lib/exact_target/error.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,4 +13,35 @@ def to_s
end end


end end

class EmailAddressError < Error
def initialize(email)
@email = email
end
end

class BlacklistError < EmailAddressError
def to_s
"#{@email} is on the email address blacklist"
end
end

class WhitelistError < EmailAddressError
def to_s
"#{@email} is not on the email address whitelist"
end
end

class ReadonlyError < Error
def initialize(name, *args)
@name = name
@args = args
end

def to_s
"#{@name} is not allowed when the client is set to readonly"
end
end


end end
45 changes: 43 additions & 2 deletions lib/exact_target/request_builder.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ def initialize(config)
end end


def accountinfo_retrieve_attrbs def accountinfo_retrieve_attrbs
ensure_executable!("accountinfo_retrieve_attrbs")
build(:accountinfo, :retrieve_attrbs) build(:accountinfo, :retrieve_attrbs)
end end


def list_add(list_name, list_type=nil) def list_add(list_name, list_type=nil)
ensure_executable!("list_add")
list_type = :public unless %w(public private salesforce).include?(list_type.to_s) list_type = :public unless %w(public private salesforce).include?(list_type.to_s)
build(:list, :add) do |li| build(:list, :add) do |li|
li.list_type list_type.to_s li.list_type list_type.to_s
Expand All @@ -20,12 +22,14 @@ def list_add(list_name, list_type=nil)
end end


def list_edit(list_id, new_list_name) def list_edit(list_id, new_list_name)
ensure_executable!("list_edit")
build(:list, :edit, :listid, list_id) do |li| build(:list, :edit, :listid, list_id) do |li|
li.list_name new_list_name.to_s li.list_name new_list_name.to_s
end end
end end


def list_retrieve(id_or_name=nil) def list_retrieve(id_or_name=nil)
ensure_executable!("list_retrieve")
if id_or_name.is_a?(Fixnum) or id_or_name =~ /^\d+$/ if id_or_name.is_a?(Fixnum) or id_or_name =~ /^\d+$/
build(:list, :retrieve, :listid, id_or_name.to_i) build(:list, :retrieve, :listid, id_or_name.to_i)
else else
Expand All @@ -34,6 +38,7 @@ def list_retrieve(id_or_name=nil)
end end


def list_import(list_id, file_name, file_mapping, options={}) def list_import(list_id, file_name, file_mapping, options={})
ensure_executable!("list_import")
options = list_import_default_options(options, file_name) options = list_import_default_options(options, file_name)
build(:list, :import, :listid, list_id) do |li| build(:list, :import, :listid, list_id) do |li|
li.tags_from_options! options, :file_name, :email_address, :file_type, :column_headings li.tags_from_options! options, :file_name, :email_address, :file_type, :column_headings
Expand All @@ -45,6 +50,7 @@ def list_import(list_id, file_name, file_mapping, options={})
end end


def list_importstatus(import_id) def list_importstatus(import_id)
ensure_executable!("list_importstatus")
build( build(
:list, :import, :list, :import,
:sub_action => :importstatus, :sub_action => :importstatus,
Expand All @@ -54,6 +60,7 @@ def list_importstatus(import_id)
end end


def list_retrieve_sub(list_id, status=nil) def list_retrieve_sub(list_id, status=nil)
ensure_executable!("list_retrieve_sub")
unless status.nil? or %w(Active Unsubscribed Returned Undeliverable Deleted).include?(status) unless status.nil? or %w(Active Unsubscribed Returned Undeliverable Deleted).include?(status)
raise "Invalid status: #{status}" raise "Invalid status: #{status}"
end end
Expand All @@ -63,14 +70,17 @@ def list_retrieve_sub(list_id, status=nil)
end end


def list_delete(id) def list_delete(id)
ensure_executable!("list_delete")
build(:list, :delete, :listid, id) build(:list, :delete, :listid, id)
end end


def list_retrievegroups def list_retrievegroups
ensure_executable!("list_retrievegroups")
build(:list, :retrievegroups, :groups) build(:list, :retrievegroups, :groups)
end end


def list_refresh_group(group_id) def list_refresh_group(group_id)
ensure_executable!("list_refresh_group")
build( build(
:list, :refresh_group, :list, :refresh_group,
:sub_action => nil, :sub_action => nil,
Expand All @@ -81,6 +91,7 @@ def list_refresh_group(group_id)
end end


def batch_inquire(batch_id) def batch_inquire(batch_id)
ensure_executable!("batch_inquire")
build( build(
:batch, :inquire, :batchid, batch_id, :batch, :inquire, :batchid, batch_id,
:sub_action => nil, :sub_action => nil,
Expand All @@ -91,10 +102,12 @@ def batch_inquire(batch_id)
################################################################### ###################################################################


def subscriber_add(list_id, subscriber, options={}) def subscriber_add(list_id, subscriber, options={})
ensure_executable!("subscriber_add")
subscriber_edit(list_id, nil, subscriber, options) subscriber_edit(list_id, nil, subscriber, options)
end end


def subscriber_edit(list_id, orig_email, subscriber, options={}) def subscriber_edit(list_id, orig_email, subscriber, options={})
ensure_executable!("subscriber_edit")
options = subscriber_edit_default_options(options) options = subscriber_edit_default_options(options)
subscriber = subscriber.to_et_hash if subscriber.is_a?(Subscriber) subscriber = subscriber.to_et_hash if subscriber.is_a?(Subscriber)
action = orig_email.nil? ? :add : :edit action = orig_email.nil? ? :add : :edit
Expand All @@ -112,16 +125,19 @@ def subscriber_edit(list_id, orig_email, subscriber, options={})
end end


def subscriber_retrieve(id, email=nil) def subscriber_retrieve(id, email=nil)
ensure_executable!("subscriber_retrieve")
type = email.blank? ? :subid : :listid type = email.blank? ? :subid : :listid
build(:subscriber, :retrieve, type, id, :search_value2 => email) build(:subscriber, :retrieve, type, id, :search_value2 => email)
end end


def subscriber_delete(id, email=nil) def subscriber_delete(id, email=nil)
ensure_executable!("subscriber_delete")
type = email.blank? ? :subid : :listid type = email.blank? ? :subid : :listid
build(:subscriber, :delete, type, id, :search_value2 => email) build(:subscriber, :delete, type, id, :search_value2 => email)
end end


def subscriber_masterunsub(*email_addresses) def subscriber_masterunsub(*email_addresses)
ensure_executable!("subscriber_masterunsub")
build(:subscriber, :masterunsub, :emailaddress, :search_value => :omit) do |sub| build(:subscriber, :masterunsub, :emailaddress, :search_value => :omit) do |sub|
sub.search_value do |sv| sub.search_value do |sv|
email_addresses.flatten.each { |a| sv.emailaddress(a) } email_addresses.flatten.each { |a| sv.emailaddress(a) }
Expand All @@ -132,6 +148,7 @@ def subscriber_masterunsub(*email_addresses)
################################################################### ###################################################################


def email_retrieve(name=nil, options={}) def email_retrieve(name=nil, options={})
ensure_executable!("email_retrieve")
name, options = nil, name if name.is_a?(Hash) name, options = nil, name if name.is_a?(Hash)
start_date, end_date = %w(start_date end_date).map do |n| start_date, end_date = %w(start_date end_date).map do |n|
et_date options[n.to_sym] et_date options[n.to_sym]
Expand All @@ -150,6 +167,7 @@ def email_retrieve(name=nil, options={})
end end


def email_add(name, subject, options) def email_add(name, subject, options)
ensure_executable!("email_add")
build(:email, :add, :search_type => :omit, :search_value => :omit, :sub_action => 'HTMLPaste') do |em| build(:email, :add, :search_type => :omit, :search_value => :omit, :sub_action => 'HTMLPaste') do |em|
em.category em.category
em.email_name name em.email_name name
Expand All @@ -163,6 +181,7 @@ def email_add(name, subject, options)
end end


def email_add_text(email_id, options) def email_add_text(email_id, options)
ensure_executable!("email_add_text")
build(:email, :add, :search_type => :emailid, build(:email, :add, :search_type => :emailid,
:search_value => email_id, :sub_action => :text) do |em| :search_value => email_id, :sub_action => :text) do |em|
if options.has_key? :body if options.has_key? :body
Expand All @@ -174,6 +193,7 @@ def email_add_text(email_id, options)
end end


def email_retrieve_body(email_id) def email_retrieve_body(email_id)
ensure_executable!("email_retrieve_body")
build(:email, :retrieve, :emailid, email_id, :sub_action => :htmlemail) do |em| build(:email, :retrieve, :emailid, email_id, :sub_action => :htmlemail) do |em|
em.search_value2 em.search_value2
em.search_value3 em.search_value3
Expand All @@ -183,6 +203,7 @@ def email_retrieve_body(email_id)
################################################################### ###################################################################


def triggeredsend_add(email, customer_key, attributes = {}) def triggeredsend_add(email, customer_key, attributes = {})
ensure_executable!("triggeredsend_add", email)
build(:triggeredsend, :add) do |xml| build(:triggeredsend, :add) do |xml|
xml.TriggeredSend :"xmlns:xsi" => "http://www.w3.org/2001/XMLSchemainstance", xml.TriggeredSend :"xmlns:xsi" => "http://www.w3.org/2001/XMLSchemainstance",
:"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", :"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
Expand All @@ -197,7 +218,7 @@ def triggeredsend_add(email, customer_key, attributes = {})
attributes.each do |key, value| attributes.each do |key, value|
xml.Attributes do xml.Attributes do
xml.Name key.to_s xml.Name key.to_s
xml.Value value xml.Value {|v| v.cdata! value}
end end
end end
end end
Expand All @@ -207,6 +228,7 @@ def triggeredsend_add(email, customer_key, attributes = {})
################################################################### ###################################################################


def job_send(email_id, list_ids, options={}) def job_send(email_id, list_ids, options={})
ensure_executable!("job_send")
options = job_send_default_options(options) options = job_send_default_options(options)


build(:job, :send, :emailid, email_id) do |job| build(:job, :send, :emailid, email_id) do |job|
Expand Down Expand Up @@ -274,7 +296,9 @@ def build(system_name, action, search_type=nil, search_value=nil, options=nil, &
build_system(s, system_name, action, options, &block) build_system(s, system_name, action, options, &block)
end end
end end
%Q[<?xml version="1.0"?>#{xml}] x = %Q[<?xml version="1.0"?>#{xml}]
pp x
x
end end


def parse_options(search_type, search_value, options) def parse_options(search_type, search_value, options)
Expand Down Expand Up @@ -303,5 +327,22 @@ def build_system_option(s, name, value)
end end
end end


def ensure_executable!(method, email = nil)
# stop if the method is readonly
raise ReadonlyError.new(method, args) if @config.readonly && @config.readonly.include?(method.to_sym)

ensure_sendable!(email) if email
end

def ensure_sendable!(email)
if @config.email_whitelist && !@config.email_whitelist.match(email)
raise WhitelistError.new(email)
end

if @config.email_blacklist && @config.email_blacklist.match(email)
raise BlacklistError.new(email)
end
end

end end
end end

0 comments on commit 66440fa

Please sign in to comment.