Class: ExactTarget

Inherits:
Object
  • Object
show all
Defined in:
lib/exacttarget.rb,
lib/exacttarget/job.rb,
lib/exacttarget/list.rb,
lib/exacttarget/group.rb,
lib/exacttarget/image.rb,
lib/exacttarget/email.rb

Overview

Ruby wrapper for the ExactTarget XML API.

Author:

Constant Summary

MSG =

Error/warning message header:

'[ExactTarget]'
ERROR =

For error messages:

"#{MSG} Error:"
WARN =

For warning messages:

"#{MSG} Warning:"
FTP_STANDARD_NAME =

The standard FTP name:

'ExactTargetFTP'
FTP_STANDARD_URI =

The standard FTP URI:

'ftp.exacttarget.com'
FTP_STANDARD_PATH =

The standard FTP path (directory):

'/'
FTP_ENHANCED_NAME =

The enhanced FTP name:

'ExactTargetEnhancedFTP'
FTP_ENHANCED_URI =

The enhanced FTP URI:

'ftp1.exacttarget.com'
FTP_ENHANCED_PATH =

The enhanced FTP path (directory):

'/import'

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (ExactTarget) initialize(config)

Create a new ExactTarget API client.

Examples:

# Simple:
client = ExactTarget.new :username => 'username', :password => 'password'

# Using the enhanced FTP:
client = ExactTarget.new(
  :username     => 'username',
  :password     => 'password',
  :ftp_username => '123456',
  :ftp_password => '123456',
  :ftp_name     => ExactTarget::FTP_ENHANCED_NAME,
  :ftp_uri      => ExactTarget::FTP_ENHANCED_URI,
  :ftp_path     => ExactTarget::FTP_ENHANCED_PATH
)

Options Hash (config):

  • :username (String)

    Username (required)

  • :password (String)

    Password (required)

  • :api_uri (String)

    ExactTarget API URI (needs to be the asp path)

  • :ftp_username (String)

    FTP username (default: import)

  • :ftp_password (String)

    FTP password (default: import)

  • :ftp_name (String)

    FTP name (default: ExactTargetFTP)

  • :ftp_uri (String)

    FTP URI (default: ftp.exacttarget.com)

  • :ftp_path (String)

    FTP path (defaults to root '/')



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/exacttarget.rb', line 74

def initialize(config)
  @config = {
    :username     => nil,
    :password     => nil,
    :api_uri      => 'https://api.dc1.exacttarget.com/integrate.asp',
    :ftp_username => 'import',
    :ftp_password => 'import',
    :ftp_name     => FTP_STANDARD_NAME,
    :ftp_uri      => FTP_STANDARD_URI,
    :ftp_path     => FTP_STANDARD_PATH
  }.merge(config)
  
  # Sanity check:
  if @config[:username].nil? || 
     @config[:password].nil?
     raise "#{ERROR} username and password required!"
  end
  
  # Configure/start services:
  ftp_connect
  @uri = URI.parse(@config[:api_uri])
  @api = Net::HTTP.new(@uri.host, @uri.port)
  @api.use_ssl = true
end

Instance Attribute Details

- (hash) :config (readonly)

Configuration hash



22
23
24
# File 'lib/exacttarget.rb', line 22

def :config
  @:config
end

- (Object) config (readonly)

Returns the value of attribute config



45
46
47
# File 'lib/exacttarget.rb', line 45

def config
  @config
end

Instance Method Details

- (Object) email_create(name, subject, html, text = false)

Create an email.

Note: The text version is generated automatically by ExactTarget.
      Just specify one here to overwrite the default.

Examples:

# Simple:
client.email_create 'New', 'Hi there.', '<html><div>Foo</div></html>'

# Realistic:
client.email_create(
  'New',
  'Hi there.',
  htmlString,
  textString
)

See Also:



131
132
133
134
135
# File 'lib/exacttarget/email.rb', line 131

def email_create(name, subject, html, text = false)
  id = email_add_html(name, subject, html)
  email_add_text(id, text) if text
  id
end

- (Object) email_find(options = {})

Find all emails who's attributes match the selected options.

Options Hash (options):

  • :id (int, string)

    Email ID

  • :name (string)

    Name of the email (keyword search)

  • :subject (string)

    Subject of the email (keyword search)

  • :start (date)

    The date at which to start the search

  • :end (date)

    The date at which to end the search

  • :body (bool)

    Whether or not to retrieve the HTML body of the email



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/exacttarget/email.rb', line 60

def email_find(options = {})
  @action     = 'retrieve'
  @sub_action = 'all'
  @type       = ''
  @value      = ''
  
  id          = options[:id]      || false
  name        = options[:name]    || false
  subject     = options[:subject] || false
  start_date  = options[:start]   || false
  end_date    = options[:end]     || false
  get_body    = options[:body]    || false
  list        = []
  
  Nokogiri::Slop(send(render(:email)))
    .exacttarget
    .system
    .email
    .emaillist.each do |email|
      (next if email.emailid.content != id.to_s) if id
      (next if !email.emailname.content.include? name.to_s) if name
      (next if !email.emailsubject.content.include? subject.to_s) if subject
      
      date = Date.strptime(email.emailcreateddate.content, '%m/%d/%Y')
      
      (next if date < start_date) if start_date && start_date.instance_of?(Date)
      (next if date > end_date) if end_date && end_date.instance_of?(Date)
      
      body = email_get_body(email.emailid.content) if get_body
      
      email.instance_eval do
        new = {
          :id           => emailid.content,
          :name         => emailname.content,
          :subject      => emailsubject.content,
          :date         => date,
          :category_id  => categoryid.content
        }
        
        new[:body] = body if get_body
        list << new
      end
  end
  
  list
end

- (Object) email_find_all(body = false)

Find all emails.



9
10
11
# File 'lib/exacttarget/email.rb', line 9

def email_find_all(body = false)
  email_find({ :body => body })
end

- (Object) email_find_by_id(id, options = {})

Retrieve an email by its ID.

See Also:



19
20
21
22
23
24
# File 'lib/exacttarget/email.rb', line 19

def email_find_by_id(id, options = {})
  email_find({
    :id => id,
    :body => true
  }.merge(options))
end

- (Object) email_find_by_name(name, options = {})

Find all emails who's name includes the given keyword.

See Also:



32
33
34
35
36
# File 'lib/exacttarget/email.rb', line 32

def email_find_by_name(name, options = {})
  email_find({
    :name => name,
  }.merge(options))
end

- (Object) email_find_by_subject(subject, options = {})

Find all emails who's subject includes the given keyword.

See Also:



44
45
46
47
48
# File 'lib/exacttarget/email.rb', line 44

def email_find_by_subject(subject, options = {})
  email_find({
    :subject => subject,
  }.merge(options))
end

- (Object) group_find(options = {}) Also known as: group_find_all

Find all groups who's attributes match the selected options.

Options Hash (options):

  • :id (int, string)

    Group ID

  • :name (string)

    Name of the group (keyword search)

  • :desc (string)

    Description of the group (keyword search)



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/exacttarget/group.rb', line 48

def group_find(options = {})
  id     = options[:id]   || false
  name   = options[:name] || false
  desc   = options[:desc] || false
  groups = []
  
  Nokogiri::Slop(send(render(:group)))
    .exacttarget
    .system
    .list
    .groups.each do |group|
      (next if group.groupID.content != id.to_s) if id
      (next if !group.groupName.content.include? name.to_s) if name
      (next if !group.description.content.include? desc.to_s) if desc
      
      group.instance_eval do
        groups << {
          :id   => groupID.content,
          :name => groupName.content,
          :desc => description.content
        }
      end
  end
  groups
end

- (Object) group_find_by_desc(desc, options = {})

Retrieve a group by its description.

See Also:



35
36
37
38
39
# File 'lib/exacttarget/group.rb', line 35

def group_find_by_desc(desc, options = {})
  group_find({
    :desc => desc
  }.merge(options))
end

- (Object) group_find_by_id(id, options = {})

Retrieve a group by its ID.

See Also:



11
12
13
14
15
# File 'lib/exacttarget/group.rb', line 11

def group_find_by_id(id, options = {})
  group_find({
    :id => id
  }.merge(options))
end

- (Object) group_find_by_name(name, options = {})

Retrieve a group by its name.

See Also:



23
24
25
26
27
# File 'lib/exacttarget/group.rb', line 23

def group_find_by_name(name, options = {})
  group_find({
    :name => name
  }.merge(options))
end

- (Object) image_import(file_path)

Upload an image (note: uses the FTP and cleans up afterward).

Supported file types:
bmp, gif, jpeg, jpg, png, tif, tiff

Note: Files must be under 200KB.

--- DON'T PANIC ---
This function may spit out FTP deletion failures.
It seems that ExactTarget locks the image file while
it is moving it (the API call). However, it should
delete the file within the retry limit (15).


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/exacttarget/image.rb', line 20

def image_import(file_path)
  @name  = File.basename(file_path)
  
  ftp_put(file_path.to_s)
  
  result = Nokogiri::XML(send(render(:image)))
  desc   = result.xpath('//filemanagement-description').text
  total  = result.xpath('//filemanagement-totalmoved').text.to_i
  name   = result.xpath('//filemanagement-info').text
  error  = desc.include?('not exist') ? 'File not found' : total < 1 ? 'Unsupported file type' : nil
  
  count  = 0
  limit  = 15
  
  begin
    sleep 0.5
    ftp_delete(@name)
  rescue
    count += 1
    retry if count < limit
  end
  
  {
    :file_path => file_path.to_s,
    :old_name  => @name,
    :new_name  => name,
    :error     => error
  }
end

- (Object) job_send(options) Also known as: email_send

Send an email to a collection of lists or groups.

This function takes its name from the API call it makes,
but it is aliased as "email_send." And for good reason,
as that accurately describes its true function.

Examples:

# Simple:
email_send :id => 123456, :include => [789456, 654789]

# Advanced:
email_send(
  :id         => 123456,
  :include    => [789456, 654789],
  :when       => DateTime.parse('10:22pm'),
  :from_name  => 'Ruby',
  :from_email => 'newsletter@ruby-lang.org',
  :track      => false
)

Options Hash (options):

  • :id (int, string)

    Email ID

  • :include (array)

    The collection of lists or groups to target

  • :exclude (array)

    The collection of lists or groups to skip

  • :from_name (string)

    Name of sender (only if supported by your account)

  • :from_email (string)

    Email address of sender (only if supported by your account)

  • :additional (string)

    Additional information to include

  • :when (date, datetime)

    The date and/or time which to send the email(s)

  • :multipart (bool)

    Whether or not to send in multiple parts (for MIME compatibility)

  • :track (bool)

    Whether or not to track hyperlink clicks

  • :test (bool)

    If true, suppress email(s) from Performance Reports



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/exacttarget/job.rb', line 37

def job_send(options)
  @options = {
    :id         => nil,
    :include    => [],
    :exclude    => [],
    :from_name  => nil,
    :from_email => nil,
    :additional => nil,
    :when       => nil,
    :multipart  => false,
    :track      => true,
    :test       => false
  }.merge(options)
  
  # Sanity check:
  if @options[:id].nil? ||
     @options[:include].empty?
     raise "#{ERROR} id and include array/string required!"
  end
  
  @date =
    (@options[:when].strftime('%-m/%-d/%Y') if
      @options[:when].instance_of?(Date) ||
      @options[:when].instance_of?(DateTime)) || 'immediate'
  
  @time =
    (@options[:when].strftime('%H:%M') if
      @options[:when].instance_of?(DateTime)) || ''
  
  result = Nokogiri::XML(send(render(:job)))
  info   = result.xpath('//job_info').text
  desc   = result.xpath('//job_description').text
  
  raise "#{ERROR} job send failed !" if !info.include? 'success'
  desc
end

- (Object) list_find(options = {}) Also known as: list_find_all

Find all lists who's attributes match the selected options.

Options Hash (options):

  • :id (int, string)

    list ID

  • :name (string)

    Name of the list (keyword search)

  • :type (string)

    Type of the list (keyword search)

  • :start (datetime)

    The date at which to start the search

  • :end (datetime)

    The date at which to end the search



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/exacttarget/list.rb', line 50

def list_find(options = {})
  id         = options[:id]    || false
  name       = options[:name]  || false
  type       = options[:type]  || false
  start_date = options[:start] || false
  end_date   = options[:end]   || false
  list       = list_get_all
  
  list.select do |item|
    (next if item[:id] != id.to_s) if id
    (next if !item[:name].include? name.to_s) if name
    (next if !item[:type].include? type.to_s) if type
    (next if item[:modified] < start_date) if start_date && start_date.instance_of?(DateTime)
    (next if item[:modified] > end_date) if end_date && end_date.instance_of?(DateTime)
    true
  end
end

- (Object) list_find_by_id(id, options = {})

Retrieve a list by its ID.

See Also:



11
12
13
14
15
# File 'lib/exacttarget/list.rb', line 11

def list_find_by_id(id, options = {})
  list_find({
    :id => id
  }.merge(options))
end

- (Object) list_find_by_name(name, options = {})

Find all lists who's name includes the given keyword.

See Also:



23
24
25
26
27
# File 'lib/exacttarget/list.rb', line 23

def list_find_by_name(name, options = {})
  list_find({
    :name => name,
  }.merge(options))
end

- (Object) list_find_by_type(type, options = {})

Find all lists who's type includes the given keyword.

See Also:



35
36
37
38
39
# File 'lib/exacttarget/list.rb', line 35

def list_find_by_type(type, options = {})
  list_find({
    :type => subject,
  }.merge(options))
end