Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to savon 2.1.0 #3

Open
wants to merge 59 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
5d412e1
List added
Saicheg Apr 26, 2012
cd2a854
fix result id bug
Saicheg Apr 26, 2012
a0d20ed
Email added
Saicheg Apr 27, 2012
f4f599c
Email added
Saicheg Apr 27, 2012
8c40b46
Merge branches 'additional-objects' and 'fix-result-id-field' into ad…
Saicheg Apr 28, 2012
b270f44
add some basic ApiObject fields and work with ApiObject properties a …
Saicheg Apr 28, 2012
f233448
change field types for APIObject
Saicheg Apr 30, 2012
8ed764e
pack of objects for EmailSendDefinition implementation
Saicheg Apr 30, 2012
6465920
SimpleOperatorEnum added
Saicheg May 2, 2012
bc7cc48
remove validations from objects, cause it fails retrieve and other ac…
Saicheg May 2, 2012
e3b7868
add new Schedule request to client
Saicheg May 2, 2012
3f44fdf
remove validation from EmailSendDefinition
Saicheg May 2, 2012
9fd17e2
add results to perfrom response and add objects for scheduling
Saicheg May 2, 2012
40be2f9
add some more objects for scheduling
Saicheg May 2, 2012
77bac46
bounce_event and send objects added
Saicheg May 2, 2012
50dbcec
Merge branches 'master' and 'additional-objects'
Saicheg May 2, 2012
3388047
move method for before_validation to block to prevent rails errors
Saicheg May 3, 2012
1e1d91b
add additional property to ESD
Saicheg May 4, 2012
2667175
add couple more fields for email_send_definition and send_definition_…
Saicheg May 7, 2012
8055f32
remove validation from subscriber(error)
Saicheg May 7, 2012
ccf09d4
handle id and object_id methods
Saicheg May 7, 2012
faf4e8b
add some fields and enum for delivery profile
Saicheg May 7, 2012
13109b2
add new enum to autoload folder
Saicheg May 8, 2012
8dfc87d
add some fields to data_extension
Saicheg May 8, 2012
79f3583
add couple more fields for data_extension and send_definition_list an…
Saicheg May 10, 2012
623ae33
Add property for SenderProfile to enable AutoForward feature
Saicheg May 15, 2012
c48de45
fix typo for DeliveryProfile
Saicheg May 15, 2012
6f93858
add SenderProfile to EmailSendDefinition
Saicheg May 16, 2012
477105a
remove handling UnknowError from execute_request call
Saicheg May 17, 2012
4212a72
add LogicalOperators enum
Saicheg May 17, 2012
ab8e7d7
Add couple fields to DataExtensionObject
Saicheg May 17, 2012
68d6f67
make object and id available for UpdateResult
klochner May 19, 2012
5448e3b
add SubscriberList object
Saicheg May 21, 2012
f8c0cc7
make object and id available for UpdateResult
klochner May 19, 2012
49cb13d
typo
Saicheg May 21, 2012
73d038a
Merge branches 'master' and 'new-feature'
Saicheg May 21, 2012
93dd7a5
Merge branch 'master' of github.com:Saicheg/exact_target_sdk
klochner May 21, 2012
2600b45
gitignore updated
Saicheg May 24, 2012
ff54ab1
add objects for SpamAssasin integration
Saicheg May 25, 2012
430f6b5
rework Email model
Saicheg Jun 11, 2012
2b59df2
use ExactTargetSDK.config instead config
Saicheg Jun 11, 2012
1948e20
fix couple more config options
Saicheg Jun 11, 2012
e96308f
add option for enabling logs
Saicheg Jun 11, 2012
1ec397a
downgrade savon version and remove enabling login option
Saicheg Jun 11, 2012
6a2de6b
remove default rails logger
Saicheg Jun 11, 2012
4ea10ec
roll back previous savon version
Saicheg Jun 11, 2012
b207521
revert back rails logger and setup dependencies
Saicheg Jun 11, 2012
0b32702
add click open and sent events objects
Saicheg Jun 13, 2012
a058725
add one more abstraction level to implement Options class
Saicheg Jun 20, 2012
8b82cb0
add all classes to implement options
Saicheg Jun 20, 2012
7c71b90
result_message added
Saicheg Jun 21, 2012
a92b20f
implement options feature for requests
Saicheg Jun 21, 2012
7576037
nested_children for subsctibers in content_validation
Saicheg Jun 21, 2012
80e079e
update rspec
Saicheg Jul 9, 2012
4e0acab
skip validation if object is existing object with some id given
Saicheg Jul 9, 2012
9a1b492
put some validations back and fix all the tests + add some color to r…
Saicheg Jul 9, 2012
73b44fd
update all gems
Saicheg Jul 9, 2012
e101854
Merge branches 'master' and 'fix-broken-savon'
Saicheg Jul 9, 2012
c725a6b
* update savon
gregory Feb 11, 2013
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -2,3 +2,6 @@
/gems_dev
/.rbx
.*.swp
.idea/
temp/
.rvmrc
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ source 'http://rubygems.org'
gem 'activemodel', '~> 3.0'
gem 'activesupport', '~> 3.0'
gem 'guid', '~> 0.1'
gem 'savon', '~> 0.9'
gem 'savon', '~> 2.1.0'

group :rake do
gem 'simple_gem', :require => 'tasks/simple_gem'
@@ -12,4 +12,3 @@ end
group :test do
gem 'rspec', '~> 2.8'
end

56 changes: 29 additions & 27 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,48 +1,50 @@
GEM
remote: http://rubygems.org/
specs:
activemodel (3.2.1)
activesupport (= 3.2.1)
activemodel (3.2.6)
activesupport (= 3.2.6)
builder (~> 3.0.0)
activesupport (3.2.1)
activesupport (3.2.6)
i18n (~> 0.6)
multi_json (~> 1.0)
akami (1.0.0)
akami (1.2.0)
gyoku (>= 0.4.0)
builder (3.0.0)
nokogiri (>= 1.4.0)
builder (3.0.4)
diff-lcs (1.1.3)
guid (0.1.1)
gyoku (0.4.4)
gyoku (1.0.0)
builder (>= 2.1.2)
httpi (0.9.5)
httpi (2.0.2)
rack
i18n (0.6.0)
multi_json (1.0.4)
nokogiri (1.5.0)
nori (1.0.2)
rack (1.4.1)
multi_json (1.3.6)
nokogiri (1.5.6)
nori (2.0.3)
rack (1.5.2)
rake (0.9.2.2)
rspec (2.8.0)
rspec-core (~> 2.8.0)
rspec-expectations (~> 2.8.0)
rspec-mocks (~> 2.8.0)
rspec-core (2.8.0)
rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.8.0)
savon (0.9.7)
akami (~> 1.0)
rspec (2.11.0)
rspec-core (~> 2.11.0)
rspec-expectations (~> 2.11.0)
rspec-mocks (~> 2.11.0)
rspec-core (2.11.0)
rspec-expectations (2.11.1)
diff-lcs (~> 1.1.3)
rspec-mocks (2.11.0)
savon (2.1.0)
akami (~> 1.2.0)
builder (>= 2.1.2)
gyoku (>= 0.4.0)
httpi (~> 0.9)
gyoku (~> 1.0.0)
httpi (~> 2.0.2)
nokogiri (>= 1.4.0)
nori (~> 1.0)
wasabi (~> 2.0)
nori (~> 2.0.3)
wasabi (~> 3.0.0)
simple_gem (0.0.2)
activesupport (~> 3.0)
rake (>= 0.8.7)
rspec (~> 2.8)
wasabi (2.0.0)
wasabi (3.0.0)
httpi (~> 2.0)
nokogiri (>= 1.4.0)

PLATFORMS
@@ -53,5 +55,5 @@ DEPENDENCIES
activesupport (~> 3.0)
guid (~> 0.1)
rspec (~> 2.8)
savon (~> 0.9)
savon (~> 2.1.0)
simple_gem
4 changes: 2 additions & 2 deletions exact_target_sdk.gemspec
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
s.email = %q{daws23@gmail.com}
s.homepage = %q{https://github.com/daws/exact_target_sdk}
s.require_paths = [ 'lib' ]

# documentation
s.has_rdoc = true
s.extra_rdoc_files = %w( README.rdoc CHANGELOG.rdoc LICENSE.txt )
@@ -27,6 +27,6 @@ Gem::Specification.new do |s|
s.add_dependency 'activemodel', '~> 3.0'
s.add_dependency 'activesupport', '~> 3.0'
s.add_dependency 'guid', '~> 0.1'
s.add_dependency 'savon', '~> 0.9'
s.add_dependency 'savon', '~> 2.1.0'

end
46 changes: 46 additions & 0 deletions lib/exact_target_sdk.rb
Original file line number Diff line number Diff line change
@@ -4,27 +4,73 @@
module ExactTargetSDK

autoload :APIObject, 'exact_target_sdk/api_object'
autoload :AsyncResponse, 'exact_target_sdk/async_response'
autoload :AsyncResponseType, 'exact_target_sdk/async_response_type'
autoload :APIProperty, 'exact_target_sdk/api_property'
autoload :Attribute, 'exact_target_sdk/attribute'
autoload :Base, 'exact_target_sdk/base'
autoload :BounceEvent, 'exact_target_sdk/bounce_event'
autoload :Client, 'exact_target_sdk/client'
autoload :ClickEvent, 'exact_target_sdk/click_event'
autoload :ComplexFilterPart, 'exact_target_sdk/complex_filter_part'
autoload :ContentArea, 'exact_target_sdk/content_area'
autoload :ContentValidation, 'exact_target_sdk/content_validation'
autoload :CreateOptions, 'exact_target_sdk/create_options'
autoload :CreateResponse, 'exact_target_sdk/create_response'
autoload :CreateResult, 'exact_target_sdk/create_result'
autoload :DailyRecurrence, 'exact_target_sdk/daily_recurrence'
autoload :DailyRecurrencePatternTypeEnum, 'exact_target_sdk/daily_recurrence_pattern_type_enum'
autoload :DataExtension, 'exact_target_sdk/data_extension'
autoload :DataExtensionField, 'exact_target_sdk/data_extension_field'
autoload :DataExtensionFieldType, 'exact_target_sdk/data_extension_field_type'
autoload :DataExtensionObject, 'exact_target_sdk/data_extension_object'
autoload :DeleteOptions, 'exact_target_sdk/delete_options'
autoload :DeleteResponse, 'exact_target_sdk/delete_response'
autoload :DeleteResult, 'exact_target_sdk/delete_result'
autoload :DeliveryProfile, 'exact_target_sdk/delivery_profile'
autoload :DeliveryProfileSourceAddressTypeEnum, 'exact_target_sdk/delivery_profile_source_address_type_enum'
autoload :Email, 'exact_target_sdk/email'
autoload :EmailSendDefinition, 'exact_target_sdk/email_send_definition'
autoload :FilterPart, 'exact_target_sdk/filter_part'
autoload :PerformResponse, 'exact_target_sdk/perform_response'
autoload :PerformResult, 'exact_target_sdk/perform_result'
autoload :List, 'exact_target_sdk/list'
autoload :LogicalOperators, 'exact_target_sdk/logical_operators'
autoload :OpenEvent, 'exact_target_sdk/open_event'
autoload :Options, 'exact_target_sdk/options'
autoload :Priority, 'exact_target_sdk/priority'
autoload :PerformOptions, 'exact_target_sdk/perform_options'
autoload :RecurrenceRangeTypeEnum, 'exact_target_sdk/recurrence_range_type_enum'
autoload :RecurrenceTypeEnum, 'exact_target_sdk/recurrence_type_enum'
autoload :Result, 'exact_target_sdk/result'
autoload :ResultMessage, 'exact_target_sdk/result_message'
autoload :RespondWhen, 'exact_target_sdk/respond_when'
autoload :RetrieveResponse, 'exact_target_sdk/retrieve_response'
autoload :RetrieveOptions, 'exact_target_sdk/retrieve_options'
autoload :RetrieveResult, 'exact_target_sdk/retrieve_result'
autoload :RequestType, 'exact_target_sdk/request_type'
autoload :SalutationSourceEnum, 'exact_target_sdk/salutation_source_enum'
autoload :SaveAction, 'exact_target_sdk/save_action'
autoload :SaveOption, 'exact_target_sdk/save_option'
autoload :SimpleFilterPart, 'exact_target_sdk/simple_filter_part'
autoload :Send, 'exact_target_sdk/send'
autoload :ScheduleDefinition, 'exact_target_sdk/schedule_definition'
autoload :ScheduleOptions, 'exact_target_sdk/schedule_options'
autoload :ScheduleResponse, 'exact_target_sdk/schedule_response'
autoload :ScheduleResult, 'exact_target_sdk/schedule_result'
autoload :SendClassification, 'exact_target_sdk/send_classification'
autoload :SendDefinitionList, 'exact_target_sdk/send_definition_list'
autoload :SendDefinitionListTypeEnum, 'exact_target_sdk/send_definition_list_enum'
autoload :SenderProfile, 'exact_target_sdk/sender_profile'
autoload :SentEvent, 'exact_target_sdk/sent_event'
autoload :SimpleOperator, 'exact_target_sdk/simple_operator'
autoload :SpamAssassinValidation, 'exact_target_sdk/spam_assassin_validation'
autoload :Subscriber, 'exact_target_sdk/subscriber'
autoload :SubscriberList, 'exact_target_sdk/subscriber_list'
autoload :TriggeredSend, 'exact_target_sdk/triggered_send'
autoload :TriggeredSendDefinition, 'exact_target_sdk/triggered_send_definition'
autoload :ValidationAction, 'exact_target_sdk/validation_action'
autoload :UpdateOptions, 'exact_target_sdk/update_options'
autoload :UpdateResponse, 'exact_target_sdk/update_response'
autoload :UpdateResult, 'exact_target_sdk/update_result'

157 changes: 4 additions & 153 deletions lib/exact_target_sdk/api_object.rb
Original file line number Diff line number Diff line change
@@ -1,163 +1,14 @@
require 'active_model'
require 'active_support/inflector'

module ExactTargetSDK

# Parent class of all ExactTarget API objects (listed here:
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects). Provides
# class-level declarations, validation, and rendering that makes modeling
# each object easy.
class APIObject

include ::ActiveModel::Validations
include ::ActiveModel::Validations::Callbacks

class << self

# Declares a property of this object, optionally requiring it upon
# validation.
#
# Provides a getter and setter for this property, keeping track of
# whether or not it has been set and registering it for rendering.
def property(name, options = {})
options = {
:required => false
}.merge(options)

name = name.to_s
attr_reader name.to_sym
class_eval <<-__EOF__
def #{name}=(value)
@_set_#{name} = true
@#{name} = value
end
__EOF__
if options[:required]
validates name.to_sym, :presence => true
end
register_property!(name, options)
end

# Declares a property as an array of values.
#
# Provides a getter and setter for this property. The getter will
# always return an array (not null), so the client may simply append
# to this property.
#
# Note that once the property has been either read or written to, it
# will be rendered.
def array_property(name, options = {})
# TODO: type validation would be nice
name = name.to_s

options = {
:nest_children => false,
:singular => name.singularize
}.merge(options)

class_eval <<-__EOF__
def #{name}
@_set_#{name} = true
@#{name} ||= []
end
def #{name}=(value)
@_set_#{name} = true
@#{name} = value
end
__EOF__
register_property!(name, options)
end

# Same as #property, adding validation the the provided value is an
# integer.
def int_property(name, options = {})
options = {
:required => false
}.merge(options)
property(name, options)
validates name.to_sym, :numericality => { :allow_nil => true, :only_integer => true }
end

# Returns an array of all registered properties.
def properties
@properties || {}
end

def type_name
name.split('::').last
end

private

# Stores the given property name to be used at render time.
def register_property!(name, options = {})
@properties ||= {}
@properties[name] = options
end
class APIObject < Base

end

# By default, any properties may be passed and set.
#
# May be overridden.
def initialize(properties = {})
properties.each do |key, value|
self.send "#{key}=", value
end
end

# By default, returns the name of the class.
#
# May be overridden.
def type_name
self.class.type_name
end

# By default, runs validation and executes #render_properties!.
#
# If overridden, the child class should check wehter or not the
# object is valid, and then render the object. In general,
# the render_properties! method should be overridden instead.
def render!(xml)
raise(InvalidAPIObject, self) if invalid?
render_properties!(xml)
end
property 'ID'
property 'ObjectID'
property 'CustomerKey'

# By default, loops through all registered properties, and renders
# each that has been explicitly set.
#
# May be overridden.
def render_properties!(xml)
self.class.properties.each do |property, options|
next unless instance_variable_get("@_set_#{property}")
property_value = self.send(property)
render_property!(property, property_value, xml, options)
end
end

def render_property_array!(property_name, array, xml)
array.each do |current|
render_property!(property_name, current, xml)
end
end

def render_property!(property_name, property_value, xml, options = {})
if property_value.is_a?(APIObject)
xml.__send__(property_name, { "xsi:type" => property_value.type_name } ) do
property_value.render!(xml)
end
elsif property_value.is_a?(Array)
if options[:nest_children]
xml.__send__(property_name) do
render_property_array!(options[:singular], property_value, xml)
end
else
render_property_array!(property_name, property_value, xml)
end
else
xml.__send__(property_name, property_value.to_s)
end
end

end
end
24 changes: 24 additions & 0 deletions lib/exact_target_sdk/async_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/AsyncResponse
module ExactTargetSDK
class AsyncResponse < Base

# Indicates whether the APIObject should be included in the response.
property 'IncludeObjects'

# Determines whether the Result objects will be included in the response when an asynchronous API call completes processing.
property 'IncludeResults'

# Reduce object to base APIObject information. Includes basic reference data associating object and request.
property 'OnlyIncludeBase'

# Specifies event triggers the AsyncResponse object action.
property 'RespondWhen'

# Email address or public URL to receive POST response to asynchronous request.
property 'ResponseAddress'

# Specifies type of response associated with an asynchronous operation.
property 'ResponseType'

end
end
17 changes: 17 additions & 0 deletions lib/exact_target_sdk/async_response_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/AsyncResponseType
module ExactTargetSDK
module AsyncResponseType
# Default email address for object. Indicates if subscriber information can be used for email sends.
EMAIL = "email"

# Reserved for future use.
FTP = "FTP"

# Indicates the response will be sent using the Post method of the HTTP protocol to the URL specified in the call when the asynchronous API call completes processing.

HTTP_POST = "HTTPPost"

#Default response type for AsyncResponseType.
NONE = "None"
end
end
177 changes: 177 additions & 0 deletions lib/exact_target_sdk/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
require 'active_model'
require 'active_support/inflector'

module ExactTargetSDK

class Base
# Properties that can be used as object id to perform update, delete,
# perform and schedule actions
ID_PROPERTIES = %w(ID ObjectID CustomerKey)

include ::ActiveModel::Validations
include ::ActiveModel::Validations::Callbacks

class << self

# Declares a property of this object, optionally requiring it upon
# validation.
#
# Provides a getter and setter for this property, keeping track of
# whether or not it has been set and registering it for rendering.
def property(name, options = {})
options = {
:required => false
}.merge(options)

name = name.to_s
attr_reader name.to_sym
class_eval <<-__EOF__
def #{name}=(value)
@_set_#{name} = true
@#{name} = value
end
__EOF__
if options[:required]
validates name.to_sym, :presence => true, :if => :new_record?
end
register_property!(name, options)
end

# Declares a property as an array of values.
#
# Provides a getter and setter for this property. The getter will
# always return an array (not null), so the client may simply append
# to this property.
#
# Note that once the property has been either read or written to, it
# will be rendered.
def array_property(name, options = {})
# TODO: type validation would be nice
name = name.to_s

options = {
:nest_children => false,
:singular => name.singularize
}.merge(options)

class_eval <<-__EOF__
def #{name}
@_set_#{name} = true
@#{name} ||= []
end
def #{name}=(value)
@_set_#{name} = true
@#{name} = value
end
__EOF__
register_property!(name, options)
end

# Same as #property, adding validation the the provided value is an
# integer.
def int_property(name, options = {})
options = {
:required => false
}.merge(options)
property(name, options)
validates name.to_sym, :numericality => {:allow_nil => true, :only_integer => true}, :if => :new_record?
end

# Returns an array of all registered properties of current class.
def properties
@properties || {}
end

# Returns an array of all registered properties, including parent classes
def all_properties
properties = {}
self.ancestors.each do |klass|
properties.merge!(klass.properties) if klass.respond_to? :properties
end
properties
end

def type_name
name.split('::').last
end

private

# Stores the given property name to be used at render time.
def register_property!(name, options = {})
@properties ||= {}
@properties[name] = options
end

end

# By default, any properties may be passed and set.
#
# May be overridden.
def initialize(properties = {})
properties.each do |key, value|
self.send "#{key}=", value
end
end

# By default, returns the name of the class.
#
# May be overridden.
def type_name
self.class.type_name
end

# By default, runs validation and executes #render_properties!.
#
# If overridden, the child class should check wehter or not the
# object is valid, and then render the object. In general,
# the render_properties! method should be overridden instead.
def render!(xml)
raise(InvalidAPIObject, self) if invalid?
render_properties!(xml)
end

# By default, loops through all registered properties, and renders
# each that has been explicitly set.
#
# May be overridden.
def render_properties!(xml)
self.class.all_properties.each do |property, options|
next unless instance_variable_get("@_set_#{property}")
property_value = self.send(property)
render_property!(property, property_value, xml, options)
end
end

def render_property_array!(property_name, array, xml)
array.each do |current|
render_property!(property_name, current, xml)
end
end

def render_property!(property_name, property_value, xml, options = {})
if property_value.is_a?(APIObject)
xml.__send__(property_name, {"xsi:type" => property_value.type_name}) do
property_value.render!(xml)
end
elsif property_value.is_a?(Array)
if options[:nest_children]
xml.__send__(property_name) do
render_property_array!(options[:singular], property_value, xml)
end
else
render_property_array!(property_name, property_value, xml)
end
else
xml.__send__(property_name, property_value.to_s)
end
end

def new_record?
ID_PROPERTIES.each {|property| return false if instance_variable_get("@_set_#{property}")}
true
end

end

end
25 changes: 25 additions & 0 deletions lib/exact_target_sdk/bounce_event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module ExactTargetSDK
class BounceEvent < APIObject

# Date when a tracking event occurred.
property "EventDate"

# Contains identifier for a specific send.
property "SendID"

# Contains SMTP code related to a bounced email.
property "SMTPCode"

# Contains SMTP reason associated with a bounced email.
property "SMTPReason"

# Identification of a specific subscriber.
property "SubscriberKey"

# Identifies the triggered send definition associated with an event.
# This value also appears in tracking events to allow you to tie those events to a specific triggered send.
property "TriggeredSendDefinitionObjectID "


end
end
14 changes: 14 additions & 0 deletions lib/exact_target_sdk/click_event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module ExactTargetSDK
class ClickEvent < APIObject

# Date when a tracking event occurred.
property 'EventDate'

# Contains identifier for a specific send.
property 'SendID'

# Identification of a specific subscriber.
property 'SubscriberKey'

end
end
164 changes: 121 additions & 43 deletions lib/exact_target_sdk/client.rb
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ module ExactTargetSDK
# outlined in the guide linked above are used. This is done in an attempt to be
# as transparent as possible, so that the API may be used by referring only to
# the guide linked above.

class Client

# Constructs a client.
@@ -21,13 +22,7 @@ class Client
# Since ExactTarget's API is stateless, constructing a client object will not
# make any remote calls.
def initialize(options = {})
self.config = {
}.merge!(ExactTargetSDK.config).merge!(options)

Savon.configure do |c|
c.logger = config[:logger]
c.raise_errors = false
end
self.config = {}.merge!(ExactTargetSDK.config).merge!(options)

initialize_client!
end
@@ -47,17 +42,23 @@ def initialize(options = {})
def Create(*args)
# TODO: implement and accept CreateOptions

api_objects = args
api_objects, options = filter_options(args)

response = execute_request 'Create' do |xml|
xml.CreateRequest do
xml.Options # TODO: support CreateOptions

api_objects.each do |api_object|
xml.Objects "xsi:type" => api_object.type_name do
api_object.render!(xml)
end
end

options.each do |option|
xml.Options do
option.render!(xml)
end
end

end
end

@@ -80,12 +81,14 @@ def Create(*args)
# InvalidAPIObject if any of the provided objects don't pass validation
#
# Returns a RetrieveResponse object.
def Retrieve(object_type_name, filter, *properties)
def Retrieve(object_type_name, filter, *args)
object_type_name = object_type_name.type_name if object_type_name.respond_to?(:type_name)

properties, options = filter_options(args)

response = execute_request 'Retrieve' do |xml|
xml.RetrieveRequestMsg do
xml.RetrieveRequest do
xml.Options

xml.ObjectType object_type_name

@@ -96,6 +99,13 @@ def Retrieve(object_type_name, filter, *properties)
xml.Filter "xsi:type" => filter.type_name do
filter.render!(xml)
end

options.each do |option|
xml.Options do
option.render!(xml)
end
end

end
end
end
@@ -116,19 +126,24 @@ def Retrieve(object_type_name, filter, *properties)
#
# Returns an UpdateResponse object.
def Update(*args)
# TODO: implement and accept UpdateOptions

api_objects = args
api_objects, options = filter_options(args)

response = execute_request 'Update' do |xml|
xml.UpdateRequest do
xml.Options # TODO: support UpdateOptions

api_objects.each do |api_object|
xml.Objects "xsi:type" => api_object.type_name do
api_object.render!(xml)
end
end

options.each do |option|
xml.Options do
option.render!(xml)
end
end

end
end

@@ -148,19 +163,23 @@ def Update(*args)
#
# Returns a DeleteResponse object.
def Delete(*args)
# TODO: implement and accept DeleteOptions

api_objects = args
api_objects, options = filter_options(args)

response = execute_request 'Delete' do |xml|
xml.DeleteRequest do
xml.Options # TODO: support DeleteOptions

api_objects.each do |api_object|
xml.Objects "xsi:type" => api_object.type_name do
api_object.render!(xml)
end
end

options.each do |option|
xml.Options do
option.render!(xml)
end
end

end
end

@@ -180,9 +199,7 @@ def Delete(*args)
#
# Returns a PerformResponse object.
def Perform(action, *args)
# TODO: implement and accept PerformOptions

definitions = args
definitions, options = filter_options(args)

response = execute_request 'Perform' do |xml|
xml.PerformRequestMsg do
@@ -194,31 +211,83 @@ def Perform(action, *args)
definition.render!(xml)
end
end
end
end

xml.Options # TODO: support PerformOptions
options.each do |option|
xml.Options do
option.render!(xml)
end
end
end
end

PerformResponse.new(response)
end


# Invokes the Schedule method.
#
# The provided arguments should each be definitions that are sub-classes
# of APIObject.
#
# Possible exceptions are:
# HTTPError if an HTTP error (such as a timeout) occurs
# SOAPFault if a SOAP fault occurs
# Timeout if there is a timeout waiting for the response
# InvalidAPIObject if any of the provided objects don't pass validation
#
# Returns a ScheduleResponse object.
def Schedule(action, schedule, *args)

interactions, options = filter_options(args)

response = execute_request 'Schedule' do |xml|
xml.ScheduleRequestMsg do
xml.Action action

xml.Schedule do
schedule.render!(xml)
end

xml.Interactions do
interactions.each do |interaction|
xml.Interaction "xsi:type" => interaction.type_name do
interaction.render!(xml)
end
end
end

options.each do |option|
xml.Options do
option.render!(xml)
end
end

end
end

ScheduleResponse.new(response)
end


def logger
config[:logger]
ExactTargetSDK.config[:logger]
end

private

attr_accessor :config, :client

# Constructs and saves the savon client using provided config.
def initialize_client!
self.client = ::Savon::Client.new do
wsdl.endpoint = config[:endpoint]
wsdl.namespace = config[:namespace]
http.open_timeout = config[:open_timeout]
http.read_timeout = config[:read_timeout]
end
self.client = ::Savon::Client.new({
wsdl: ExactTargetSDK.config[:endpoint],
namespace: ExactTargetSDK.config[:namespace],
logger: ExactTargetSDK.config[:logger],
raise_errors: false,
open_timeout: ExactTargetSDK.config[:open_timeout],
read_timeout: ExactTargetSDK.config[:read_timeout]
})
end

# Builds the SOAP request for the given method, delegating body
@@ -229,11 +298,10 @@ def initialize_client!
#
# Returns the raw savon response.
def execute_request(method)
begin
response = client.request(method) do
soap.xml do |xml|
xml.s :Envelope,
"xmlns" => config[:namespace],
"xmlns" => ExactTargetSDK.config[:namespace],
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:s" => "http://www.w3.org/2003/05/soap-envelope",
@@ -246,11 +314,11 @@ def execute_request(method)
xml.a :ReplyTo do
xml.a :Address, "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"
end
xml.a :To, config[:endpoint], "s:mustUnderstand" => "1"
xml.a :To, ExactTargetSDK.config[:endpoint], "s:mustUnderstand" => "1"
xml.o :Security, "s:mustUnderstand" => "1" do
xml.o :UsernameToken, "o:Id" => "test" do
xml.o :Username, config[:username]
xml.o :Password, config[:password]
xml.o :Username, ExactTargetSDK.config[:username]
xml.o :Password, ExactTargetSDK.config[:password]
end
end
end
@@ -271,13 +339,23 @@ def execute_request(method)
end

response
rescue ::Timeout::Error => e
timeout = ::ExactTargetSDK::TimeoutError.new("#{e.message}; open_timeout: #{config[:open_timeout]}; read_timeout: #{config[:read_timeout]}")
timeout.set_backtrace(e.backtrace)
raise timeout
rescue Exception => e
raise ::ExactTargetSDK::UnknownError, e
end
rescue ::Timeout::Error => e
timeout = ::ExactTargetSDK::TimeoutError.new("#{e.message}; open_timeout: #{config[:open_timeout]}; read_timeout: #{config[:read_timeout]}")
timeout.set_backtrace(e.backtrace)
raise timeout
end

def filter_options(args)
options = find_options(args)
options.each{|opt| args.delete(opt)}
[args,options]
end


def find_options(args)
options = []
args.each { |arg| options << arg if arg.is_a? Options }
options
end

end
14 changes: 14 additions & 0 deletions lib/exact_target_sdk/content_validation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module ExactTargetSDK
class ContentValidation < APIObject

# Default email address for object. Indicates if subscriber information can be used for email sends.
property 'Email'

# Specifies the validation action to run on content. Valid values include SpamAssassinValidation.
property 'ValidationAction'

# Indicates subscribers associated with an object.
array_property 'Subscribers', :nest_children => true

end
end
6 changes: 6 additions & 0 deletions lib/exact_target_sdk/create_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/CreateOptions
module ExactTargetSDK
class CreateOptions < Options

end
end
10 changes: 10 additions & 0 deletions lib/exact_target_sdk/daily_recurrence.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module ExactTargetSDK
class DailyRecurrence < APIObject

# Specifies the type of daily recurrence (either Interval or EveryWeekDay)
property "DailyRecurrencePatternType"

# Specifies the number of days on which to execute a daily recurrence.
property "DayInterval"
end
end
6 changes: 6 additions & 0 deletions lib/exact_target_sdk/daily_recurrence_pattern_type_enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module ExactTargetSDK
module DailyRecurrencePatternTypeEnum
EVERY_WEEK_DAY = "EveryWeekDay"
INTERVAL = "Interval"
end
end
16 changes: 16 additions & 0 deletions lib/exact_target_sdk/data_extension.rb
Original file line number Diff line number Diff line change
@@ -5,5 +5,21 @@ class DataExtension < APIObject
array_property 'Fields', :nest_children => true
property 'Name'

# Indicates whether you can use a data extension as part of an audience for a message send.
property 'IsSendable'

# Indicates whether a sendable data extension can be used within tests sends for a message.
property 'IsTestable'

# Indicates the field within a sendable data extension to use as an address as part of a send.
# Possible values include SubscriberID, CustomerKey, or EmailAddress.
# The application uses this field to establish a data relationship between a value specified by the
# SendableSubscriberField property and a value within a sendable data extension.
property 'SendableDataExtensionField'

# Indicates field to use as sending address. The application uses this field to establish a data relationship
# between a subscriber field and a value specified by the SendableDataExtentionField property.
property 'SendableSubscriberField'

end
end
14 changes: 14 additions & 0 deletions lib/exact_target_sdk/data_extension_field_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module ExactTargetSDK
module DataExtensionFieldType

TEXT = "Text"
NUMBER = "Number"
DATA = "Data"
BOOLEAN = "Boolean"
EMAIL_ADDRESS = "EmailAddress"
PHONE = "Phone"
DECIMAL = "Decimal"
LOCALE = "Locale"

end
end
2 changes: 2 additions & 0 deletions lib/exact_target_sdk/data_extension_object.rb
Original file line number Diff line number Diff line change
@@ -2,7 +2,9 @@ module ExactTargetSDK
class DataExtensionObject < APIObject

property 'CustomerKey'
property 'SubscriberKey'
array_property 'Properties', :nest_children => true
array_property 'Keys', :nest_children => true

end
end
6 changes: 6 additions & 0 deletions lib/exact_target_sdk/delete_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/DeleteOptions
module ExactTargetSDK
class DeleteOptions < Options

end
end
15 changes: 15 additions & 0 deletions lib/exact_target_sdk/delivery_profile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module ExactTargetSDK
class DeliveryProfile < APIObject

property 'Name', :required => true

property 'SourceAddressType'

# Defines source of a footer salutation to use as part of a delivery profile or send definition (Default, Content Library, or None)
property 'FooterSalutationSource'

# Defines source of header salutation for a delivery profile or send definition.
property 'HeaderSalutationSource'

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module ExactTargetSDK
module DeliveryProfileSourceAddressTypeEnum
CUSTOM_PRIVATE_IP_ADDRESS = "CustomPrivateIPAddress"
DEFAULT_PRIVATE_IP_ADDRESS = "DefaultPrivateIPAddress"
end
end
21 changes: 21 additions & 0 deletions lib/exact_target_sdk/email.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/Email
module ExactTargetSDK
class Email < APIObject

# Name of the object or property.
property 'Name', :required => true

# Contains subject area information for a message.
property 'Subject', :required => true

# Contains HTML body of an email message.
property 'HTMLBody'

# Contains raw text body of a message.
property 'TextBody'

# Indicates if email message was created via pasted HTML.
property 'IsHTMLPaste'

end
end
51 changes: 51 additions & 0 deletions lib/exact_target_sdk/email_send_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module ExactTargetSDK
class EmailSendDefinition < APIObject

property 'Name', :required => true

# Indicates the send classification to use as part of a send definition.
property 'SendClassification'

# Indicates the subscriber list to use as part of an email send definition.
array_property 'SendDefinitionList'

# Default email address for object. Indicates if subscriber information can be used for email sends.
property 'Email'

# Defines an email address to which to send a test message as part
# of an email send definition. Use the Test action when sending a
# test email to an email send definition.
property 'TestEmailAddr'

# Defines account users with access to tracking information for that send definition.
property 'TrackingUsers'

# Defines blind carbon copy email address to which to send a message as
# part of an email send definition.
property 'AutoBccEmail'

# Indicates email addresses to receive blind carbon copy of a message.
property 'BccEmail'

# CC
property 'CCEmail'

# Defines scheduled data and time for a send related to an email send definition.
property 'DeliveryScheduledTime'

# Subject for an email send
property 'EmailSubject'

# Defines an email address to which to send a test message as part of an email send definition.
# Use the Test action when sending a test email to an email send definition.
property "TestEmailAddr"

#Identifies the sender profile included in the send classificiation.
property 'SenderProfile'


end
end



8 changes: 8 additions & 0 deletions lib/exact_target_sdk/list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module ExactTargetSDK
class List < APIObject

property 'ListName', :required => true
array_property 'Subscribers'

end
end
6 changes: 6 additions & 0 deletions lib/exact_target_sdk/logical_operators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module ExactTargetSDK
module LogicalOperators
AND = "AND"
OR = "OR"
end
end
14 changes: 14 additions & 0 deletions lib/exact_target_sdk/open_event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module ExactTargetSDK
class OpenEvent < APIObject

# Date when a tracking event occurred.
property 'EventDate'

# Contains identifier for a specific send.
property 'SendID'

# Identification of a specific subscriber.
property 'SubscriberKey'

end
end
33 changes: 33 additions & 0 deletions lib/exact_target_sdk/options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/Options
module ExactTargetSDK
class Options < Base

# Represents the number of calls that must be received before the conversation support in the asynchronous API will begin processing.
int_property "CallsInConversation"

# Specifies the account ownership and context of an object.
property "Client"

# Unique ID of initial async API call; All requests that should be processed as a single unit will have the same ConversationID.
property "ConversationID"

# Defines the priority for a triggered send. Valid values include Low, Medium, and High.
property "Priority"

# Defines request as synchronous or asynchronous API.
property "RequestType"

# Keeps requests in asynchronous queue until time specified in the call.
property "ScheduledTime"

# Specifies the processing sequence of a multi-step conversation. This optional property requires the use of ConversationID.
property "SequenceCode"

# Allows upsert on selected objects.
array_property "SaveOptions"

# Defines how responses are returned and under what conditions. Optional.
array_property "SendResponseTo"

end
end
6 changes: 6 additions & 0 deletions lib/exact_target_sdk/perform_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/PerformOptions
module ExactTargetSDK
class PerformOptions < Options

end
end
14 changes: 13 additions & 1 deletion lib/exact_target_sdk/perform_response.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
module ExactTargetSDK
class PerformResponse

attr_reader :OverallStatus, :OverallStatusMessage, :RequestID
attr_reader :OverallStatus, :OverallStatusMessage, :RequestID, :Results

def initialize(response)
response = response.to_hash[:perform_response_msg]
@OverallStatus = response[:overall_status]
@OverallStatusMessage = response[:overall_status_message]
@RequestID = response[:request_id]
@Results = []

results = if response[:results].is_a? Array
response[:results]
elsif response[:results].is_a? Hash
[response[:results]]
else
[]
end
results.each do |result|
@Results << PerformResult.new(result)
end
end

end
4 changes: 4 additions & 0 deletions lib/exact_target_sdk/perform_result.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module ExactTargetSDK
class PerformResult < Result
end
end
13 changes: 13 additions & 0 deletions lib/exact_target_sdk/priority.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/Priority
module ExactTargetSDK
module Priority
# Specifies high priority for API process.
HIGH = "High"

# Specifies medium priority on API processes.
MEDIUM = "Medium"

# Specifies low priority for API process.
LOW = "Low"
end
end
6 changes: 6 additions & 0 deletions lib/exact_target_sdk/recurrence_range_type_enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module ExactTargetSDK
module RecurrenceRangeTypeEnum
END_AFTER = "EndAfter"
END_ON = "EndOn"
end
end
11 changes: 11 additions & 0 deletions lib/exact_target_sdk/recurrence_type_enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module ExactTargetSDK
module RecurrenceTypeEnum
DAILY = "Daily"
HOURLY = "Hourly"
MINUTELY = "Minutely"
MONTHLY = "Monthly"
SECONDLY = "Secondly"
WEEKLY = "Weekly"
YEARLY = "Yearly"
end
end
10 changes: 10 additions & 0 deletions lib/exact_target_sdk/request_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/RequestType
module ExactTargetSDK
module RequestType
# Specifies that the API request should be processed asynchronously.
ASYNCHRONOUS = "Asynchronous"

# Specifies that the process should be processed synchronously.
SYNCHRONOUS = "Synchronous"
end
end
23 changes: 23 additions & 0 deletions lib/exact_target_sdk/respond_when.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/RespondWhen
module ExactTargetSDK
module RespondWhen
# Always send the response.
ALWAYS = "Always"

# Specifies that a response should never be set for an asynchronous process.
NEVER = "Never"

# Specifies that a response should be sent when an asynchronous call is complete.
ON_CALL_COMPLETE = "OnCallComplete"

# Specifies that a response should be sent when an asynchronous conversation is complete.
ON_CONVERSATION_COMPLETE = "OnConversationComplete"

# Specifies that a response should be sent when an asynchronous conversation returns an error.
ON_CONVERSATION_ERROR = "OnConversationError"

# Specifies that a response should be send when an asynchronous process returns an error.
ON_ERROR = "OnError"
end
end

24 changes: 16 additions & 8 deletions lib/exact_target_sdk/result.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
require 'active_support/inflector'

module ExactTargetSDK
class Result
class Result

def initialize(hash)
@result = hash
end
def id
@result[:id] || self.id
end

def method_missing(symbol, *args)
@result[symbol.to_s.underscore.to_sym]
end
def object_id
@result[:object_id] || self.object_id
end

end
def initialize(hash)
@result = hash
end

def method_missing(symbol, *args)
@result[symbol.to_s.underscore.to_sym]
end

end
end
63 changes: 63 additions & 0 deletions lib/exact_target_sdk/result_message.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/ResultMessage
module ExactTargetSDK
class ResultMessage < APIObject

# Number of calls within an async API conversation.
property 'CallsInConversation'

# Specifies the account ownership and context of an object.
property 'Client'

# Unique ID of initial async API call.
property 'ConversationID'

# Identifies correlation of objects across several requests.
property 'CorrelationID'

# Read-only date and time of the objects creation.
property 'CreatedDate'

# Identifies the error of an API request.
property 'ErrorCode'

# Last time object information was modified.
property 'ModifiedDate'

# Reserved for future use.
property 'ObjectState'

# Represents overall status of conversation via async API.
property 'OverallStatusCode'

# Describes account ownership of subscriber in an on-your-behalf account.
property 'Owner'

# Unique identifier provided by partner for an object, accessible only via API.
property 'PartnerKey'

# A collection of metadata supplied by client and stored by system - only accessible via API.
array_property 'PartnerProperties'

# Unique ID of initial async API call.
property 'RequestID'

# Defines request as synchronous or asynchronous API.
property 'RequestType'

# Contains details of operation result in XML format.
property 'ResultDetailXML'

# Defines result as coming from synchronous or asynchronous API.
property 'ResultType'

# Specifies the processing sequence of a multi-step conversation.
property 'SequenceCode'

# Status of async API request.
property 'StatusCode'

# Describes the status of an API call.
property 'StatusMessage'

end
end
15 changes: 15 additions & 0 deletions lib/exact_target_sdk/retrieve_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/RetrieveOptions
module ExactTargetSDK
class RetrieveOptions < Options

# Number of records to return in each batch as part of a Retrieve call. Reserved for future use.
property 'BatchSize'

# Indicates whether the APIObject should be included in the response.
property 'IncludeObjects'

# Reduce object to base APIObject information. Includes basic reference data associating object and request.
property 'OnlyIncludeBase'

end
end
7 changes: 7 additions & 0 deletions lib/exact_target_sdk/salutation_source_enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module ExactTargetSDK
module SalutationSourceEnum
CONTENT_LIBRARY = "ContentLibrary"
DEFAULT = "Default"
NONE = "None"
end
end
23 changes: 23 additions & 0 deletions lib/exact_target_sdk/save_action.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/SaveAction
module ExactTargetSDK
module SaveAction
# Indicates that data should only be added and not updated during a save action.
ADD_ONLY = "AddOnly"

#Specifies default source of salutation when building an email (SalutationSourceEnum) Use the default action when saving an object. (SaveAction)
DEFAULT = "Default"

#Indicates whether an object should be deleted.
DELETE = "Delete"

#Indicates no save action should take place.
NOTHING = "Nothing"

#Indicates an UpdateAdd type for a save action. If this property is specified, the save action will update existing information and add new information.
UPDATE_ADD = "UpdateAdd"

#Indicates an UpdateOnly type for a save action. If this property is specified, the save action with update existing information only.
UPDATE_ONLY = "UpdateOnly"

end
end
12 changes: 12 additions & 0 deletions lib/exact_target_sdk/save_option.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/SaveOption
module ExactTargetSDK
class SaveOption < Base

# String object to which the SaveOption object applies.
property "PropertyName"

# Behavior specified for SaveAction object.
property "SaveAction"

end
end
20 changes: 20 additions & 0 deletions lib/exact_target_sdk/schedule_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module ExactTargetSDK
class ScheduleDefinition < APIObject

# Specifies type of recurrence, such as daily or hourly.
property "RecurrenceType"

# Defines how a recurrence type ends.
property "RecurrenceRangeType"

# Specifies start time of schedule definition
property "StartDateTime"

# Specifies number of times to run a schedule definition.
property "Occurrences"

# Interval of recurrence type.
property "Recurrence"

end
end
8 changes: 8 additions & 0 deletions lib/exact_target_sdk/schedule_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/ScheduleOptions
module ExactTargetSDK
class ScheduleOptions < Options

end
end


26 changes: 26 additions & 0 deletions lib/exact_target_sdk/schedule_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module ExactTargetSDK
class ScheduleResponse

attr_reader :OverallStatus, :OverallStatusMessage, :RequestID, :Results

def initialize(response)
response = response.to_hash[:schedule_response_msg]
@OverallStatus = response[:overall_status]
@OverallStatusMessage = response[:overall_status_message]
@RequestID = response[:request_id]
@Results = []

results = if response[:results].is_a? Array
response[:results]
elsif response[:results].is_a? Hash
[response[:results]]
else
[]
end
results.each do |result|
@Results << ScheduleResult.new(result)
end
end

end
end
5 changes: 5 additions & 0 deletions lib/exact_target_sdk/schedule_result.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ExactTargetSDK
class ScheduleResult < Result

end
end
71 changes: 71 additions & 0 deletions lib/exact_target_sdk/send.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
module ExactTargetSDK
class Send < APIObject

property 'Name'

# Default email address for object. Indicates if subscriber information can be used for email sends.
property "Email"

# Specifies the name of an email message associated with a send.
property "EmailName"

# Indicates email send definition to which the send object is attached.
property "EmailSendDefinition"

# Indicates From address associated with a object.
# Deprecated for email send definitions and triggered send definitions.
property "FromAddress"

# Specifies the default email message From Name.
# Deprecated for email send definitions and triggered send definitions.
property "FromName"

# Indicates number of hard bounces associated with a send.
property "HardBounces"

# List associated with an object.
property "List"

# Number of sent emails that did not bounce.
property "NumberDelivered"

# Number of emails not sent as part of a send because an error occurred while trying to build the email.
property "NumberErrored"

# Indicates the number recipients excluded from an email send because of a held,
# unsubscribed, master unsubscribed, or global unsubscribed status.
property "NumberExcluded"

# Number of emails actually sent as part of an email send.
# This number reflects all of the sent messages and may include bounced messages.
property "NumberSent"

# Specifies number of Other-type bounces in a send.
property "OtherBounces"

# Indicates URL used to preview the message associated with a send.
property "PreviewURL"

# Indicates date on which a send took place.
property "SentDate"

# Indicates number of soft bounces associated with a specific send.
property "SoftBounces"

# Defines status of object. Status of an address.
property "Status"

# Contains subject area information for a message.
property "Subject"

# Indicates number of unique clicks on message.
property "UniqueClicks"

# Indicates number of unique opens resulting from a triggered send.
property "UniqueOpens"

# Indicates the number of unsubscribe events associated with a send.
property 'Unsubscribes'

end
end
11 changes: 11 additions & 0 deletions lib/exact_target_sdk/send_classification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module ExactTargetSDK
class SendClassification < APIObject

property 'Name', :required => true

property 'SenderProfile', :required => true

property 'DeliveryProfile', :required => true

end
end
19 changes: 19 additions & 0 deletions lib/exact_target_sdk/send_definition_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module ExactTargetSDK
class SendDefinitionList < APIObject

property 'DataSourceTypeID'
property 'List'

property 'Name'

# Indicates the specified send is a test send. A value of true indicates a test send.
property 'IsTestObject'

# Represents the ID of the sendable data extension used as part of a send.
property 'CustomObjectID'

# Defines type of send definition list.
property 'SendDefinitionListType'

end
end
12 changes: 12 additions & 0 deletions lib/exact_target_sdk/send_definition_list_type_enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module ExactTargetSDK
module SendDefinitionListTypeEnum

LIST = "List"
CUSTOM_OBJECT = "CustomObject"
DOMAIN_EXCLUSION = "DomainExclusion"
SALES_FORCE_CAMPAIGN = "SalesForceCampaign"
FILTER_DEFINITION = "FilterDefinition"
OPT_OUT_LIST = "OptOutList"

end
end
22 changes: 22 additions & 0 deletions lib/exact_target_sdk/sender_profile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module ExactTargetSDK
class SenderProfile < APIObject

property 'Name'

# Specifies the default email message From Name. Deprecated for email send definitions and triggered send definitions.
property 'FromName'

# Indicates From address associated with a object. Deprecated for email send definitions and triggered send definitions.
property 'FromAddress'

# Indicates the To name to use on automatically forwarded email messages.
property 'AutoForwardToName'

# Indicates the email address to use with automatically forwarded email messages.
property 'AutoForwardToEmailAddress'

# Indicates whether a sender profile uses the default RMM rules for that account.
property 'UseDefaultRMMRules'

end
end
14 changes: 14 additions & 0 deletions lib/exact_target_sdk/sent_event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module ExactTargetSDK
class SentEvent < APIObject

# Date when a tracking event occurred.
property 'EventDate'

# Contains identifier for a specific send.
property 'SendID'

# Identification of a specific subscriber.
property 'SubscriberKey'

end
end
15 changes: 15 additions & 0 deletions lib/exact_target_sdk/simple_operator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module ExactTargetSDK
module SimpleOperator
EQUALS = 'equals'
NOT_EQUALS = 'notEquals'
GREATER_THAN = 'greaterThan'
LESS = 'lessThan'
IS_NOT_NULL = 'isNotNull'
IS_NULL = 'isNull'
GREATER_THAN_EQUAL = 'greaterThanOrEqual'
LESS_THAN_EQUAL = 'lessThanOrEqual'
BETWEEN = 'between'
IN = 'IN'
LIKE = 'like'
end
end
5 changes: 5 additions & 0 deletions lib/exact_target_sdk/spam_assassin_validation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ExactTargetSDK
class SpamAssassinValidation < ValidationAction

end
end
9 changes: 2 additions & 7 deletions lib/exact_target_sdk/subscriber.rb
Original file line number Diff line number Diff line change
@@ -17,14 +17,9 @@ class Subscriber < APIObject
property 'EmailAddress', :required => true
property 'EmailTypePreference'
array_property 'Attributes'
array_property 'Lists'

before_validation :sync_subscriber_key_and_email_address

validates 'EmailTypePreference', :inclusion => { :allow_nil => true, :in => %w( HTML Text ) }

private

def sync_subscriber_key_and_email_address
before_validation do
self.SubscriberKey = self.EmailAddress if self.SubscriberKey.nil?
self.EmailAddress = self.SubscriberKey if self.EmailAddress.nil?
end
17 changes: 17 additions & 0 deletions lib/exact_target_sdk/subscriber_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module ExactTargetSDK
class SubscriberList < APIObject

# Defines the action to take for the specified object.
property 'Action'

# List associated with an object.
property 'List'

# Defines status of object. Status of an address.
property 'Status'

# Defines status of object. Status of an address.
property 'Subscriber'

end
end
7 changes: 7 additions & 0 deletions lib/exact_target_sdk/update_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# http://docs.code.exacttarget.com/020_Web_Service_Guide/Objects/UpdateOptions
module ExactTargetSDK
class UpdateOptions < Options
#Defines the action to take for the specified object.
property 'Action'
end
end
11 changes: 9 additions & 2 deletions lib/exact_target_sdk/update_result.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
module ExactTargetSDK
class UpdateResult < Result
end
class UpdateResult < Result
def object
@result[:object]
end

def id
object && object[:id]
end
end
end
11 changes: 11 additions & 0 deletions lib/exact_target_sdk/validation_action.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module ExactTargetSDK
class ValidationAction < APIObject

# Options for validation object. Type: APIProperty[]
array_property 'ValidationOptions'

# Specified type of validation
property 'ValidationType'

end
end
25 changes: 25 additions & 0 deletions spec/delivery_profile_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'spec_helper'
include ExactTargetSDK

describe DeliveryProfile do
context 'a bare DeliveryProfile' do

it { should_not be_valid }

end

context ' a validated DeliveryProfile with Name and SourceAddressType' do
before(:each) do
@delivery_profile = DeliveryProfile.new 'Name' => 'Test Profile',
'SourceAddressType' => DeliveryProfileSourceAddressTypeEnum::DEFAULT_PRIVATE_IP_ADDRESS
@delivery_profile.valid?
end

subject { @delivery_profile }

it { should be_valid }

end


end
45 changes: 45 additions & 0 deletions spec/email_send_definition_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'spec_helper'
include ExactTargetSDK

describe EmailSendDefinition do
context 'a bare EmailSendDefinition' do

it { should_not be_valid }

end

context 'a validated EmailSendDefinition' do
before(:each) do

# Create List
list = ExactTargetSDK::List.new('ID' => "273",
'ListName' => "Test list")

# Create SendClassification
send_classification = ExactTargetSDK::SendClassification.new('ObjectID' => "1234b99-b592-e111-b32b-984be17c0e6c")

# Create SendDefinitionList
send_definition_list = ExactTargetSDK::SendDefinitionList.new('DataSourceTypeID' => 'List', 'List' => list)


#Create Email
email = ExactTargetSDK::Email.new('ID' => '239',
'Name' => 'test',
'Subject' => 'TestSubject',
'HTMLBody' => '<h1>Body</h1>',
'TextBody' => 'Body')

@email_send_definition = ExactTargetSDK::EmailSendDefinition.new('Name' => 'test',
'Email' => email,
'SendClassification' => send_classification,
'SendDefinitionList' => send_definition_list)
@email_send_definition.valid?
end

subject { @email_send_definition }

it { should be_valid }

end

end
47 changes: 47 additions & 0 deletions spec/email_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'spec_helper'
include ExactTargetSDK

describe Email do
context 'a bare Email' do

it { should_not be_valid }

end

context ' a validated Email with Name and Subject set' do
before(:each) do
@email = Email.new 'Name' => 'Welcome email', 'Subject' => 'Welcome to the Dark Side'
@email.valid?
end

subject { @email }

it {should be_valid}

end

context ' an invalid Email with Name and Subject set' do
before(:each) do
@email = Email.new 'Subject' => 'Welcome to the Dark Side'
@email.valid?
end

subject { @email }

it {should_not be_valid}

end

context 'a Email object with given ID' do
before(:each) do
@email = Email.new 'ID' => '587'
@email.valid?
end

subject { @email }

it {should be_valid}

end

end
35 changes: 35 additions & 0 deletions spec/list_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'spec_helper'
include ExactTargetSDK

describe List do
context 'a bare List' do

it { should_not be_valid }

end

context ' a validated List with ListName set' do
before(:each) do
@list = List.new 'ListName' => 'My Favourite List'
@list.valid?
end

subject { @list }

it {should be_valid}

end

context ' an invalid List without ListName' do
before(:each) do
@list = List.new
@list.valid?
end

subject { @list }

it {should_not be_valid}

end

end
10 changes: 10 additions & 0 deletions spec/result_spec.rb
Original file line number Diff line number Diff line change
@@ -22,4 +22,14 @@

end

context 'a result initialized with id field ' do

subject { Result.new(:id => "42") }

it 'should respond to id with "42"' do
subject.id.should == "42"
end

end

end
27 changes: 27 additions & 0 deletions spec/send_classification_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'spec_helper'
include ExactTargetSDK

describe SendClassification do
context 'a bare SendClassification' do

it { should_not be_valid }

end

context 'a validated SendClassification' do
before(:each) do
sp = ExactTargetSDK::SenderProfile.new 'ObjectID' => "some-object-id"
dp = ExactTargetSDK::DeliveryProfile.new 'ObjectID' => "some-object-id"
@send_classification = ExactTargetSDK::SendClassification.new('Name' => 'Test Classification',
'SenderProfile' => sp,
'DeliveryProfile' => dp )
@send_classification.valid?
end

subject { @send_classification }

it { should be_valid }

end

end
25 changes: 25 additions & 0 deletions spec/sender_profile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'spec_helper'
include ExactTargetSDK

describe SenderProfile do
context 'a bare SenderProfile' do

it { should_not be_valid }

end

context ' a validated SenderProfile ' do
before(:each) do
@sender_profile = SenderProfile.new 'Name' => 'Test Profile',
'FromName' => 'Bob',
'FromAddress' => 'bob@example.com'
@sender_profile.valid?
end

subject { @sender_profile }

it { should be_valid }

end

end
9 changes: 9 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -6,3 +6,12 @@
# clear environment variables to have clean environment
ENV['EXACT_TARGET_SDK_USERNAME'] = nil
ENV['EXACT_TARGET_SDK_PASSWORD'] = nil


RSpec.configure do |config|
# Use color in STDOUT
config.color_enabled = true

# Use color not only in STDOUT but also in pagers and files
config.tty = true
end