exact-target 0.0.5 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +18 -0
- data/Manifest +1 -0
- data/README.rdoc +10 -0
- data/Rakefile +2 -2
- data/exact-target.gemspec +5 -5
- data/lib/exact_target.rb +14 -4
- data/lib/exact_target/configuration.rb +26 -2
- data/lib/exact_target/error.rb +30 -0
- data/lib/exact_target/request_builder.rb +175 -0
- data/lib/exact_target/response_classes.rb +3 -0
- data/lib/exact_target/response_handler.rb +30 -3
- data/spec/exact_target_data.yml +6 -0
- data/spec/exact_target_spec.rb +14 -4
- metadata +7 -5
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,21 @@ | |
| 1 | 
            +
            v0.1.8. Bump version to 0.1 to reflect use in production environments.  Also incorporate
         | 
| 2 | 
            +
            enhancements from Jeff Ching:
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            The "adddefinition" and "updatedefinition" API calls were not documented clearly
         | 
| 5 | 
            +
            enough to implement a clean solution.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            v0.0.6. Pull in enhancements from Paul Nock and add as contributor:
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            I added some triggered send support, and also switched 'send_to_exact_target' to
         | 
| 10 | 
            +
            http POST instead of GET. In our case, we were starting to generate some long xml
         | 
| 11 | 
            +
            parameters and we didn't want to run into size limits for GET. I'm not completely
         | 
| 12 | 
            +
            sure how generic the triggered send xml is, but it works well in our case. I'm not
         | 
| 13 | 
            +
            sure if the different Exact Target Account types affect this.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            Additionally, we were seeing some issues trying to register Facebook proxy email
         | 
| 16 | 
            +
            addresses with Exact Target, for example app+asdfadsfasdfasdf@proxymail.facebook.com.
         | 
| 17 | 
            +
            It was easier to simply POST this data than trying to properly escape the + in the data.
         | 
| 18 | 
            +
             | 
| 1 19 | 
             
            v0.0.5. Fix corrupted gem
         | 
| 2 20 | 
             
            v0.0.4. Fix gem to include CHANGELOG
         | 
| 3 21 | 
             
            v0.0.3. Allow for passing ExactTarget::Subscriber into subscriber_add and subscriber_edit
         | 
    
        data/Manifest
    CHANGED
    
    
    
        data/README.rdoc
    CHANGED
    
    | @@ -164,6 +164,16 @@ tracking functionality is yet implemented. | |
| 164 164 | 
             
                                   :send_time => '17:35',
         | 
| 165 165 | 
             
                                   :test_send => true)
         | 
| 166 166 |  | 
| 167 | 
            +
            === Triggered Sends
         | 
| 168 | 
            +
             | 
| 169 | 
            +
              # Kick off a triggered send
         | 
| 170 | 
            +
              ExactTarget.triggered_send_add(external_key, 
         | 
| 171 | 
            +
                                             channel_member_id,
         | 
| 172 | 
            +
                                             email_addresses =[],
         | 
| 173 | 
            +
                                             options = {})
         | 
| 174 | 
            +
              email_addresses is an array of addresses of subscribers
         | 
| 175 | 
            +
              options is a hash of name value attributes to pass to the triggered send to add custom data to the email message
         | 
| 176 | 
            +
             | 
| 167 177 | 
             
            ---
         | 
| 168 178 | 
             
            Author::   David McCullars <mailto:dmccullars@ePublishing.com>
         | 
| 169 179 | 
             
            Copyright:: (C) 2011 ePublishing
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -6,9 +6,9 @@ require 'spec/rake/spectask' | |
| 6 6 | 
             
            task :default => :gem
         | 
| 7 7 |  | 
| 8 8 | 
             
            Echoe.new("exact-target") do |s|
         | 
| 9 | 
            -
              s.author = "David McCullars"
         | 
| 9 | 
            +
              s.author = ["David McCullars", "Paul Nock", "Jeff Ching"]
         | 
| 10 10 | 
             
              s.project = "exact-target"
         | 
| 11 | 
            -
              s.email = "dmccullars@ePublishing.com"
         | 
| 11 | 
            +
              s.email = ["dmccullars@ePublishing.com", "nocksf@gmail.com"]
         | 
| 12 12 | 
             
              s.url = "http://github.com/ePublishing/exact_target"
         | 
| 13 13 | 
             
              s.docs_host = "http://rdoc.info/github/ePublishing/exact_target/master/frames"
         | 
| 14 14 | 
             
              s.rdoc_pattern = /README|TODO|LICENSE|CHANGELOG|BENCH|COMPAT|exceptions|behaviors|exact-target.rb/
         | 
    
        data/exact-target.gemspec
    CHANGED
    
    | @@ -2,15 +2,15 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            Gem::Specification.new do |s|
         | 
| 4 4 | 
             
              s.name = "exact-target"
         | 
| 5 | 
            -
              s.version = "0. | 
| 5 | 
            +
              s.version = "0.1.8"
         | 
| 6 6 |  | 
| 7 7 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
         | 
| 8 | 
            -
              s.authors = ["David McCullars"]
         | 
| 9 | 
            -
              s.date = " | 
| 8 | 
            +
              s.authors = ["David McCullars, Paul Nock, Jeff Ching"]
         | 
| 9 | 
            +
              s.date = "2012-02-09"
         | 
| 10 10 | 
             
              s.description = "This is a pure-ruby implementation of the ExactTarget api.\nFor more information consule http://www.exacttarget.com/.\n"
         | 
| 11 | 
            -
              s.email = "dmccullars@ePublishing.com"
         | 
| 11 | 
            +
              s.email = ["dmccullars@ePublishing.com", "nocksf@gmail.com"]
         | 
| 12 12 | 
             
              s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "lib/exact-target.rb"]
         | 
| 13 | 
            -
              s.files = ["CHANGELOG", "Gemfile", "Gemfile.lock", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "lib/exact-target.rb", "lib/exact_target.rb", "lib/exact_target/builder_ext.rb", "lib/exact_target/configuration.rb", "lib/exact_target/error.rb", "lib/exact_target/net_https_hack.rb", "lib/exact_target/request_builder.rb", "lib/exact_target/response_class.erb", "lib/exact_target/response_classes.rb", "lib/exact_target/response_handler.rb", "lib/exact_target/string_ext.rb", "lib/exacttarget.rb", "spec/exact_target/net_https_hack_spec.rb", "spec/exact_target/response_handler_spec.rb", "spec/exact_target/string_ext_spec.rb", "spec/exact_target_data.yml", "spec/exact_target_spec.rb", "spec/spec.opts", "spec/spec_helper.rb" | 
| 13 | 
            +
              s.files = ["CHANGELOG", "Gemfile", "Gemfile.lock", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "exact-target.gemspec", "lib/exact-target.rb", "lib/exact_target.rb", "lib/exact_target/builder_ext.rb", "lib/exact_target/configuration.rb", "lib/exact_target/error.rb", "lib/exact_target/net_https_hack.rb", "lib/exact_target/request_builder.rb", "lib/exact_target/response_class.erb", "lib/exact_target/response_classes.rb", "lib/exact_target/response_handler.rb", "lib/exact_target/string_ext.rb", "lib/exacttarget.rb", "spec/exact_target/net_https_hack_spec.rb", "spec/exact_target/response_handler_spec.rb", "spec/exact_target/string_ext_spec.rb", "spec/exact_target_data.yml", "spec/exact_target_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
         | 
| 14 14 | 
             
              s.homepage = "http://github.com/ePublishing/exact_target"
         | 
| 15 15 | 
             
              s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Exact-target", "--main", "README.rdoc"]
         | 
| 16 16 | 
             
              s.require_paths = ["lib"]
         | 
    
        data/lib/exact_target.rb
    CHANGED
    
    | @@ -71,12 +71,21 @@ module ExactTarget | |
| 71 71 |  | 
| 72 72 | 
             
                def send_to_exact_target(request)
         | 
| 73 73 | 
             
                  verify_configure
         | 
| 74 | 
            -
             | 
| 74 | 
            +
             | 
| 75 | 
            +
                  data = "qf=xml&xml=#{URI.escape(URI.escape(request), "&")}"
         | 
| 76 | 
            +
                  uri = URI.parse(configuration.base_url)
         | 
| 77 | 
            +
             | 
| 75 78 | 
             
                  http = net_http_or_proxy.new(uri.host, uri.port)
         | 
| 76 79 | 
             
                  http.use_ssl = configuration.secure?
         | 
| 77 80 | 
             
                  http.open_timeout = configuration.http_open_timeout
         | 
| 78 81 | 
             
                  http.read_timeout = configuration.http_read_timeout
         | 
| 79 | 
            -
             | 
| 82 | 
            +
             | 
| 83 | 
            +
                  if configuration.http_method.to_s == "post"
         | 
| 84 | 
            +
                    resp = http.post(uri.request_uri, data)
         | 
| 85 | 
            +
                  else
         | 
| 86 | 
            +
                    resp = http.get(uri.request_uri + "?" + data)
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
             | 
| 80 89 | 
             
                  if resp.is_a?(Net::HTTPSuccess)
         | 
| 81 90 | 
             
                    resp.body
         | 
| 82 91 | 
             
                  else
         | 
| @@ -84,10 +93,11 @@ module ExactTarget | |
| 84 93 | 
             
                  end
         | 
| 85 94 | 
             
                end
         | 
| 86 95 |  | 
| 96 | 
            +
             | 
| 87 97 | 
             
                # Define ExactTarget methods
         | 
| 88 98 | 
             
                (RequestBuilder.instance_methods(false) & ResponseHandler.instance_methods(false)).each do |m|
         | 
| 89 | 
            -
                  define_method(m) do |*args | 
| 90 | 
            -
                    call(m, *args | 
| 99 | 
            +
                  define_method(m) do |*args|
         | 
| 100 | 
            +
                    call(m, *args)
         | 
| 91 101 | 
             
                  end
         | 
| 92 102 | 
             
                end
         | 
| 93 103 |  | 
| @@ -2,8 +2,11 @@ module ExactTarget | |
| 2 2 | 
             
              # Used to set up and modify settings for ExactTarget
         | 
| 3 3 | 
             
              class Configuration
         | 
| 4 4 |  | 
| 5 | 
            -
                OPTIONS = [:base_url, :username, :password,
         | 
| 6 | 
            -
                           :http_open_timeout, :http_read_timeout, :http_proxy].freeze
         | 
| 5 | 
            +
                OPTIONS = [:base_url, :username, :password, :readonly, :email_whitelist, :email_blacklist,
         | 
| 6 | 
            +
                           :http_method, :http_open_timeout, :http_read_timeout, :http_proxy].freeze
         | 
| 7 | 
            +
                STANDARD_READONLY_CALLS = [:list_add, :list_edit, :list_import, :list_delete,
         | 
| 8 | 
            +
                                           :subscriber_add, :subscriber_edit, :subscriber_delete, :subscriber_masterunsub,
         | 
| 9 | 
            +
                                           :email_add, :email_add_text, :job_send].freeze
         | 
| 7 10 |  | 
| 8 11 | 
             
                # The (optional) base URL for accessing ExactTarget (can be http or https).
         | 
| 9 12 | 
             
                # Defaults to 'https://api.dc1.exacttarget.com/integrate.aspx'
         | 
| @@ -27,10 +30,31 @@ module ExactTarget | |
| 27 30 | 
             
                # The (optional) HTTP proxy url
         | 
| 28 31 | 
             
                attr_accessor :http_proxy
         | 
| 29 32 |  | 
| 33 | 
            +
                # The HTTP method to make the request with
         | 
| 34 | 
            +
                attr_accessor :http_method
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                # The (optional) readonly flag (defaults to false)
         | 
| 37 | 
            +
                attr_accessor :readonly
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                # (optional) limiting triggeredsend email addresses
         | 
| 40 | 
            +
                attr_accessor :email_whitelist
         | 
| 41 | 
            +
                attr_accessor :email_blacklist
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                # optional params for batch
         | 
| 44 | 
            +
                attr_accessor :ftp_base_url
         | 
| 45 | 
            +
                attr_accessor :ftp_username
         | 
| 46 | 
            +
                attr_accessor :ftp_password
         | 
| 47 | 
            +
                attr_accessor :export_folder
         | 
| 48 | 
            +
                attr_accessor :import_folder
         | 
| 49 | 
            +
             | 
| 30 50 | 
             
                def initialize
         | 
| 31 51 | 
             
                  @base_url                 = 'https://api.dc1.exacttarget.com/integrate.aspx'
         | 
| 32 52 | 
             
                  @http_open_timeout        = 2
         | 
| 33 53 | 
             
                  @http_read_timeout        = 5
         | 
| 54 | 
            +
                  @http_method              = "get"
         | 
| 55 | 
            +
                  @readonly                 = []
         | 
| 56 | 
            +
                  @export_folder            = 'Export'
         | 
| 57 | 
            +
                  @import_folder            = 'Import'
         | 
| 34 58 | 
             
                end
         | 
| 35 59 |  | 
| 36 60 | 
             
                def valid?
         | 
    
        data/lib/exact_target/error.rb
    CHANGED
    
    | @@ -13,4 +13,34 @@ module ExactTarget | |
| 13 13 | 
             
                end
         | 
| 14 14 |  | 
| 15 15 | 
             
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              class EmailAddressError < Error
         | 
| 18 | 
            +
                def initialize(email)
         | 
| 19 | 
            +
                  @email = email
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              class BlacklistError < EmailAddressError
         | 
| 24 | 
            +
                def to_s
         | 
| 25 | 
            +
                  "#{@email} is on the email address blacklist"
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              class WhitelistError < EmailAddressError
         | 
| 30 | 
            +
                def to_s
         | 
| 31 | 
            +
                  "#{@email} is not on the email address whitelist"
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              class ReadonlyError < Error
         | 
| 36 | 
            +
                def initialize(name)
         | 
| 37 | 
            +
                  @name = name
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def to_s
         | 
| 41 | 
            +
                  "#{@name} is not allowed when the client is set to readonly"
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 16 46 | 
             
            end
         | 
| @@ -8,10 +8,12 @@ module ExactTarget | |
| 8 8 | 
             
                end
         | 
| 9 9 |  | 
| 10 10 | 
             
                def accountinfo_retrieve_attrbs
         | 
| 11 | 
            +
                  ensure_executable!("accountinfo_retrieve_attrbs")
         | 
| 11 12 | 
             
                  build(:accountinfo, :retrieve_attrbs)
         | 
| 12 13 | 
             
                end
         | 
| 13 14 |  | 
| 14 15 | 
             
                def list_add(list_name, list_type=nil)
         | 
| 16 | 
            +
                  ensure_executable!("list_add")
         | 
| 15 17 | 
             
                  list_type = :public unless %w(public private salesforce).include?(list_type.to_s)
         | 
| 16 18 | 
             
                  build(:list, :add) do |li|
         | 
| 17 19 | 
             
                    li.list_type list_type.to_s
         | 
| @@ -20,12 +22,14 @@ module ExactTarget | |
| 20 22 | 
             
                end
         | 
| 21 23 |  | 
| 22 24 | 
             
                def list_edit(list_id, new_list_name)
         | 
| 25 | 
            +
                  ensure_executable!("list_edit")
         | 
| 23 26 | 
             
                  build(:list, :edit, :listid, list_id) do |li|
         | 
| 24 27 | 
             
                    li.list_name new_list_name.to_s
         | 
| 25 28 | 
             
                  end
         | 
| 26 29 | 
             
                end
         | 
| 27 30 |  | 
| 28 31 | 
             
                def list_retrieve(id_or_name=nil)
         | 
| 32 | 
            +
                  ensure_executable!("list_retrieve")
         | 
| 29 33 | 
             
                  if id_or_name.is_a?(Fixnum) or id_or_name =~ /^\d+$/
         | 
| 30 34 | 
             
                    build(:list, :retrieve, :listid, id_or_name.to_i)
         | 
| 31 35 | 
             
                  else
         | 
| @@ -34,6 +38,7 @@ module ExactTarget | |
| 34 38 | 
             
                end
         | 
| 35 39 |  | 
| 36 40 | 
             
                def list_import(list_id, file_name, file_mapping, options={})
         | 
| 41 | 
            +
                  ensure_executable!("list_import")
         | 
| 37 42 | 
             
                  options = list_import_default_options(options, file_name)
         | 
| 38 43 | 
             
                  build(:list, :import, :listid, list_id) do |li|
         | 
| 39 44 | 
             
                    li.tags_from_options! options, :file_name, :email_address, :file_type, :column_headings
         | 
| @@ -45,6 +50,7 @@ module ExactTarget | |
| 45 50 | 
             
                end
         | 
| 46 51 |  | 
| 47 52 | 
             
                def list_importstatus(import_id)
         | 
| 53 | 
            +
                  ensure_executable!("list_importstatus")
         | 
| 48 54 | 
             
                  build(
         | 
| 49 55 | 
             
                    :list, :import,
         | 
| 50 56 | 
             
                    :sub_action => :importstatus,
         | 
| @@ -54,6 +60,7 @@ module ExactTarget | |
| 54 60 | 
             
                end
         | 
| 55 61 |  | 
| 56 62 | 
             
                def list_retrieve_sub(list_id, status=nil)
         | 
| 63 | 
            +
                  ensure_executable!("list_retrieve_sub")
         | 
| 57 64 | 
             
                  unless status.nil? or %w(Active Unsubscribed Returned Undeliverable Deleted).include?(status)
         | 
| 58 65 | 
             
                    raise "Invalid status: #{status}"
         | 
| 59 66 | 
             
                  end
         | 
| @@ -63,14 +70,17 @@ module ExactTarget | |
| 63 70 | 
             
                end
         | 
| 64 71 |  | 
| 65 72 | 
             
                def list_delete(id)
         | 
| 73 | 
            +
                  ensure_executable!("list_delete")
         | 
| 66 74 | 
             
                  build(:list, :delete, :listid, id)
         | 
| 67 75 | 
             
                end
         | 
| 68 76 |  | 
| 69 77 | 
             
                def list_retrievegroups
         | 
| 78 | 
            +
                  ensure_executable!("list_retrievegroups")
         | 
| 70 79 | 
             
                  build(:list, :retrievegroups, :groups)
         | 
| 71 80 | 
             
                end
         | 
| 72 81 |  | 
| 73 82 | 
             
                def list_refresh_group(group_id)
         | 
| 83 | 
            +
                  ensure_executable!("list_refresh_group")
         | 
| 74 84 | 
             
                  build(
         | 
| 75 85 | 
             
                    :list, :refresh_group,
         | 
| 76 86 | 
             
                    :sub_action => nil,
         | 
| @@ -81,6 +91,7 @@ module ExactTarget | |
| 81 91 | 
             
                end
         | 
| 82 92 |  | 
| 83 93 | 
             
                def batch_inquire(batch_id)
         | 
| 94 | 
            +
                  ensure_executable!("batch_inquire")
         | 
| 84 95 | 
             
                  build(
         | 
| 85 96 | 
             
                    :batch, :inquire, :batchid, batch_id,
         | 
| 86 97 | 
             
                    :sub_action => nil,
         | 
| @@ -90,11 +101,31 @@ module ExactTarget | |
| 90 101 |  | 
| 91 102 | 
             
                ###################################################################
         | 
| 92 103 |  | 
| 104 | 
            +
                def triggered_send_add(external_key, channel_member_id, email_addresses, options={})
         | 
| 105 | 
            +
                  build(:triggeredsend, :add, :search_type => :omit, :search_value => :omit) do |operation|
         | 
| 106 | 
            +
                    operation.TriggeredSend('xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
         | 
| 107 | 
            +
                                            'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
         | 
| 108 | 
            +
                                            'xmlns' => 'http://exacttarget.com/wsdl/partnerAPI') do |ts|
         | 
| 109 | 
            +
                      ts.TriggeredSendDefinition do |tsd|
         | 
| 110 | 
            +
                        tsd.CustomerKey external_key
         | 
| 111 | 
            +
                        tsd.Priority 'High'
         | 
| 112 | 
            +
                      end
         | 
| 113 | 
            +
                      email_addresses.each do |addr|
         | 
| 114 | 
            +
                        build_ts_subscriber(ts, channel_member_id, addr, options)
         | 
| 115 | 
            +
                      end
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
                  end
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                ###################################################################
         | 
| 121 | 
            +
             | 
| 93 122 | 
             
                def subscriber_add(list_id, subscriber, options={})
         | 
| 123 | 
            +
                  ensure_executable!("subscriber_add")
         | 
| 94 124 | 
             
                  subscriber_edit(list_id, nil, subscriber, options)
         | 
| 95 125 | 
             
                end
         | 
| 96 126 |  | 
| 97 127 | 
             
                def subscriber_edit(list_id, orig_email, subscriber, options={})
         | 
| 128 | 
            +
                  ensure_executable!("subscriber_edit")
         | 
| 98 129 | 
             
                  options = subscriber_edit_default_options(options)
         | 
| 99 130 | 
             
                  subscriber = subscriber.to_et_hash if subscriber.is_a?(Subscriber)
         | 
| 100 131 | 
             
                  action = orig_email.nil? ? :add : :edit
         | 
| @@ -112,16 +143,19 @@ module ExactTarget | |
| 112 143 | 
             
                end
         | 
| 113 144 |  | 
| 114 145 | 
             
                def subscriber_retrieve(id, email=nil)
         | 
| 146 | 
            +
                  ensure_executable!("subscriber_retrieve")
         | 
| 115 147 | 
             
                  type = email.blank? ? :subid : :listid
         | 
| 116 148 | 
             
                  build(:subscriber, :retrieve, type, id, :search_value2 => email)
         | 
| 117 149 | 
             
                end
         | 
| 118 150 |  | 
| 119 151 | 
             
                def subscriber_delete(id, email=nil)
         | 
| 152 | 
            +
                  ensure_executable!("subscriber_delete")
         | 
| 120 153 | 
             
                  type = email.blank? ? :subid : :listid
         | 
| 121 154 | 
             
                  build(:subscriber, :delete, type, id, :search_value2 => email)
         | 
| 122 155 | 
             
                end
         | 
| 123 156 |  | 
| 124 157 | 
             
                def subscriber_masterunsub(*email_addresses)
         | 
| 158 | 
            +
                  ensure_executable!("subscriber_masterunsub")
         | 
| 125 159 | 
             
                  build(:subscriber, :masterunsub, :emailaddress, :search_value => :omit) do |sub|
         | 
| 126 160 | 
             
                    sub.search_value do |sv|
         | 
| 127 161 | 
             
                      email_addresses.flatten.each { |a| sv.emailaddress(a) }
         | 
| @@ -132,6 +166,7 @@ module ExactTarget | |
| 132 166 | 
             
                ###################################################################
         | 
| 133 167 |  | 
| 134 168 | 
             
                def email_retrieve(name=nil, options={})
         | 
| 169 | 
            +
                  ensure_executable!("email_retrieve")
         | 
| 135 170 | 
             
                  name, options = nil, name if name.is_a?(Hash)
         | 
| 136 171 | 
             
                  start_date, end_date = %w(start_date end_date).map do |n|
         | 
| 137 172 | 
             
                    et_date options[n.to_sym]
         | 
| @@ -150,6 +185,7 @@ module ExactTarget | |
| 150 185 | 
             
                end
         | 
| 151 186 |  | 
| 152 187 | 
             
                def email_add(name, subject, options)
         | 
| 188 | 
            +
                  ensure_executable!("email_add")
         | 
| 153 189 | 
             
                  build(:email, :add, :search_type => :omit, :search_value => :omit, :sub_action => 'HTMLPaste') do |em|
         | 
| 154 190 | 
             
                    em.category
         | 
| 155 191 | 
             
                    em.email_name name
         | 
| @@ -163,6 +199,7 @@ module ExactTarget | |
| 163 199 | 
             
                end
         | 
| 164 200 |  | 
| 165 201 | 
             
                def email_add_text(email_id, options)
         | 
| 202 | 
            +
                  ensure_executable!("email_add_text")
         | 
| 166 203 | 
             
                  build(:email, :add, :search_type => :emailid,
         | 
| 167 204 | 
             
                              :search_value => email_id, :sub_action => :text) do |em|
         | 
| 168 205 | 
             
                    if options.has_key? :body
         | 
| @@ -174,6 +211,7 @@ module ExactTarget | |
| 174 211 | 
             
                end
         | 
| 175 212 |  | 
| 176 213 | 
             
                def email_retrieve_body(email_id)
         | 
| 214 | 
            +
                  ensure_executable!("email_retrieve_body")
         | 
| 177 215 | 
             
                  build(:email, :retrieve, :emailid, email_id, :sub_action => :htmlemail) do |em|
         | 
| 178 216 | 
             
                    em.search_value2
         | 
| 179 217 | 
             
                    em.search_value3
         | 
| @@ -182,7 +220,33 @@ module ExactTarget | |
| 182 220 |  | 
| 183 221 | 
             
                ###################################################################
         | 
| 184 222 |  | 
| 223 | 
            +
                def triggeredsend_add(email, customer_key, attributes = {})
         | 
| 224 | 
            +
                  ensure_executable!("triggeredsend_add", email)
         | 
| 225 | 
            +
                  build(:triggeredsend, :add) do |xml|
         | 
| 226 | 
            +
                    xml.TriggeredSend :"xmlns:xsi" => "http://www.w3.org/2001/XMLSchemainstance",
         | 
| 227 | 
            +
                                      :"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
         | 
| 228 | 
            +
                                      :"xmlns"     => "http://exacttarget.com/wsdl/partnerAPI" do
         | 
| 229 | 
            +
                      xml.TriggeredSendDefinition do
         | 
| 230 | 
            +
                        xml.CustomerKey customer_key
         | 
| 231 | 
            +
                      end
         | 
| 232 | 
            +
                      xml.Subscribers do
         | 
| 233 | 
            +
                        xml.EmailAddress email
         | 
| 234 | 
            +
                        xml.SubscriberKey email
         | 
| 235 | 
            +
                      end
         | 
| 236 | 
            +
                      attributes.each do |key, value|
         | 
| 237 | 
            +
                        xml.Attributes do
         | 
| 238 | 
            +
                          xml.Name key.to_s
         | 
| 239 | 
            +
                          xml.Value {|v| v.cdata! value.to_s }
         | 
| 240 | 
            +
                        end
         | 
| 241 | 
            +
                      end
         | 
| 242 | 
            +
                    end
         | 
| 243 | 
            +
                  end
         | 
| 244 | 
            +
                end
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                ###################################################################
         | 
| 247 | 
            +
             | 
| 185 248 | 
             
                def job_send(email_id, list_ids, options={})
         | 
| 249 | 
            +
                  ensure_executable!("job_send")
         | 
| 186 250 | 
             
                  options = job_send_default_options(options)
         | 
| 187 251 |  | 
| 188 252 | 
             
                  build(:job, :send, :emailid, email_id) do |job|
         | 
| @@ -195,6 +259,82 @@ module ExactTarget | |
| 195 259 | 
             
                  end
         | 
| 196 260 | 
             
                end
         | 
| 197 261 |  | 
| 262 | 
            +
                ###################################################################
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                def list_bulkasync(list_id, list_status = nil)
         | 
| 265 | 
            +
                  build(
         | 
| 266 | 
            +
                    :list, :bulkasync,
         | 
| 267 | 
            +
                    :sub_action => 'Subs_ToFTP',
         | 
| 268 | 
            +
                    :search_type => :listid,
         | 
| 269 | 
            +
                    :search_value => list_id
         | 
| 270 | 
            +
                  ) do |xml|
         | 
| 271 | 
            +
                    xml.search_status list_status if list_status
         | 
| 272 | 
            +
                  end
         | 
| 273 | 
            +
                end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                def subscriber_bulkasync(list_id)
         | 
| 276 | 
            +
                  build(:subscriber, :BulkAsync,
         | 
| 277 | 
            +
                    :sub_action => "SubsStatus_ToFTP",
         | 
| 278 | 
            +
                    :search_type => "lid",
         | 
| 279 | 
            +
                    :search_value => list_id)
         | 
| 280 | 
            +
                end
         | 
| 281 | 
            +
             | 
| 282 | 
            +
                # "retrieves complete tracking data for an email send"
         | 
| 283 | 
            +
                def tracking_bulkasync_all(job_id, start_date = nil, end_date = nil)
         | 
| 284 | 
            +
                  build(:tracking, :BulkAsync,
         | 
| 285 | 
            +
                    :sub_action => "all_ToFTP",
         | 
| 286 | 
            +
                    :search_type => "jobID",
         | 
| 287 | 
            +
                    :search_value => job_id) do |xml|
         | 
| 288 | 
            +
                    if start_date || end_date
         | 
| 289 | 
            +
                      start_date = start_date.strftime("%m/%d/%Y") if start_date.respond_to?(:strftime)
         | 
| 290 | 
            +
                      end_date = end_date.strftime("%m/%d/%Y") if end_date.respond_to?(:strftime)
         | 
| 291 | 
            +
                      xml.daterange do
         | 
| 292 | 
            +
                        xml.startdate start_date
         | 
| 293 | 
            +
                        xml.enddate end_date
         | 
| 294 | 
            +
                      end
         | 
| 295 | 
            +
                    end
         | 
| 296 | 
            +
                  end
         | 
| 297 | 
            +
                end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                def tracking_bulkasync_all_attributes(job_id, start_date = nil, end_date = nil)
         | 
| 300 | 
            +
                  build(:tracking, :BulkAsync,
         | 
| 301 | 
            +
                    :sub_action => "all_attributes_ToFTP",
         | 
| 302 | 
            +
                    :search_type => "jobID",
         | 
| 303 | 
            +
                    :search_value => job_id) do |xml|
         | 
| 304 | 
            +
                    if start_date || end_date
         | 
| 305 | 
            +
                      start_date = start_date.strftime("%m/%d/%Y") if start_date.respond_to?(:strftime)
         | 
| 306 | 
            +
                      end_date = end_date.strftime("%m/%d/%Y") if end_date.respond_to?(:strftime)
         | 
| 307 | 
            +
                      xml.daterange do
         | 
| 308 | 
            +
                        xml.startdate start_date
         | 
| 309 | 
            +
                        xml.enddate end_date
         | 
| 310 | 
            +
                      end
         | 
| 311 | 
            +
                    end
         | 
| 312 | 
            +
                  end
         | 
| 313 | 
            +
                end
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                def tracking_sent_bulkasync_all(job_id)
         | 
| 316 | 
            +
                  build(:tracking, :Sent_BulkAsync,
         | 
| 317 | 
            +
                    :sub_action => "all_ToFTP",
         | 
| 318 | 
            +
                    :search_type => "jobID",
         | 
| 319 | 
            +
                    :search_value => job_id)
         | 
| 320 | 
            +
                end
         | 
| 321 | 
            +
             | 
| 322 | 
            +
                def tracking_sent_bulkasync_all_attributes(job_id, start_date = nil, end_date = nil)
         | 
| 323 | 
            +
                    build(:tracking, :Sent_BulkAsync,
         | 
| 324 | 
            +
                      :sub_action => "all_attributes_ToFTP",
         | 
| 325 | 
            +
                      :search_type => "jobID",
         | 
| 326 | 
            +
                      :search_value => job_id) do |xml|
         | 
| 327 | 
            +
                      if start_date || end_date
         | 
| 328 | 
            +
                        start_date = start_date.strftime("%m/%d/%Y") if start_date.respond_to?(:strftime)
         | 
| 329 | 
            +
                        end_date = end_date.strftime("%m/%d/%Y") if end_date.respond_to?(:strftime)
         | 
| 330 | 
            +
                        xml.daterange do
         | 
| 331 | 
            +
                          xml.startdate start_date
         | 
| 332 | 
            +
                          xml.enddate end_date
         | 
| 333 | 
            +
                        end
         | 
| 334 | 
            +
                      end
         | 
| 335 | 
            +
                    end
         | 
| 336 | 
            +
                  end
         | 
| 337 | 
            +
             | 
| 198 338 | 
             
                ###################################################################
         | 
| 199 339 | 
             
                private
         | 
| 200 340 | 
             
                ###################################################################
         | 
| @@ -279,5 +419,40 @@ module ExactTarget | |
| 279 419 | 
             
                  end
         | 
| 280 420 | 
             
                end
         | 
| 281 421 |  | 
| 422 | 
            +
                def build_ts_subscriber(triggered_send, channel_member_id, email_address, options ={})
         | 
| 423 | 
            +
                  triggered_send.Subscribers('xmlns' => 'http://exacttarget.com/wsdl/partnerAPI') do |sub|
         | 
| 424 | 
            +
                    sub.Owner do |owner|
         | 
| 425 | 
            +
                      owner.Client do |client|
         | 
| 426 | 
            +
                        client.ID channel_member_id
         | 
| 427 | 
            +
                      end
         | 
| 428 | 
            +
                    end
         | 
| 429 | 
            +
                    sub.SubscriberKey email_address
         | 
| 430 | 
            +
                    sub.EmailAddress email_address
         | 
| 431 | 
            +
                    options.each do |key, value|
         | 
| 432 | 
            +
                      sub.Attributes do |atts|
         | 
| 433 | 
            +
                        atts.Name key.to_s
         | 
| 434 | 
            +
                        atts.Value value
         | 
| 435 | 
            +
                      end
         | 
| 436 | 
            +
                    end if options.present?
         | 
| 437 | 
            +
                  end
         | 
| 438 | 
            +
                end
         | 
| 439 | 
            +
             | 
| 440 | 
            +
                def ensure_executable!(method, email = nil)
         | 
| 441 | 
            +
                  # stop if the method is readonly
         | 
| 442 | 
            +
                  raise ReadonlyError.new(method) if @config.readonly && @config.readonly.include?(method.to_sym)
         | 
| 443 | 
            +
             | 
| 444 | 
            +
                  ensure_sendable!(email) if email
         | 
| 445 | 
            +
                end
         | 
| 446 | 
            +
             | 
| 447 | 
            +
                def ensure_sendable!(email)
         | 
| 448 | 
            +
                  if @config.email_whitelist && !@config.email_whitelist.match(email)
         | 
| 449 | 
            +
                    raise WhitelistError.new(email)
         | 
| 450 | 
            +
                  end
         | 
| 451 | 
            +
             | 
| 452 | 
            +
                  if @config.email_blacklist && @config.email_blacklist.match(email)
         | 
| 453 | 
            +
                    raise BlacklistError.new(email)
         | 
| 454 | 
            +
                  end
         | 
| 455 | 
            +
                end
         | 
| 456 | 
            +
             | 
| 282 457 | 
             
              end
         | 
| 283 458 | 
             
            end
         | 
| @@ -28,6 +28,9 @@ module ExactTarget | |
| 28 28 | 
             
                    class_from_et_attributes base, :EmailInformation,
         | 
| 29 29 | 
             
                      :emailname, :emailid, :emailsubject, :emailcreateddate, :categoryid
         | 
| 30 30 |  | 
| 31 | 
            +
                    class_from_et_attributes base, :BatchStatus,
         | 
| 32 | 
            +
                      :status, :batchid, :filename
         | 
| 33 | 
            +
             | 
| 31 34 | 
             
                    def base.subscriber_class
         | 
| 32 35 | 
             
                      @subscriber_class ||= ResponseClasses.class_from_et_attributes(
         | 
| 33 36 | 
             
                        self, :Subscriber, accountinfo_retrieve_attrbs.map(&:name), :Status
         | 
| @@ -15,9 +15,9 @@ module ExactTarget | |
| 15 15 | 
             
                  handle_id_result resp, :import_info, :importid, /is being imported/i
         | 
| 16 16 | 
             
                end
         | 
| 17 17 |  | 
| 18 | 
            -
                %w(email job list subscriber).each do |t|
         | 
| 18 | 
            +
                %w(email job list subscriber triggered_send).each do |t|
         | 
| 19 19 | 
             
                  define_method "handle_#{t}_id_result", lambda { |resp|
         | 
| 20 | 
            -
                    handle_id_result resp, "#{t}_info", "#{t}_description", /success/i
         | 
| 20 | 
            +
                    handle_id_result resp, "#{t}_info", "#{t}_description", /success|sucess/i
         | 
| 21 21 | 
             
                  }
         | 
| 22 22 | 
             
                end
         | 
| 23 23 |  | 
| @@ -29,6 +29,8 @@ module ExactTarget | |
| 29 29 | 
             
                  end
         | 
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 | 
            +
                alias :triggered_send_add :handle_triggered_send_id_result
         | 
| 33 | 
            +
             | 
| 32 34 | 
             
                alias :list_add :handle_list_id_result
         | 
| 33 35 |  | 
| 34 36 | 
             
                alias :list_edit :handle_list_id_result
         | 
| @@ -71,7 +73,7 @@ module ExactTarget | |
| 71 73 | 
             
                end
         | 
| 72 74 |  | 
| 73 75 | 
             
                def batch_inquire(resp)
         | 
| 74 | 
            -
                  resp.xpath('//Batch | 
| 76 | 
            +
                  create_result(BatchStatus, resp.xpath('//Batch').first)
         | 
| 75 77 | 
             
                end
         | 
| 76 78 |  | 
| 77 79 | 
             
                ###################################################################
         | 
| @@ -118,8 +120,33 @@ module ExactTarget | |
| 118 120 |  | 
| 119 121 | 
             
                ###################################################################
         | 
| 120 122 |  | 
| 123 | 
            +
                def triggeredsend_add(resp)
         | 
| 124 | 
            +
                  resp.xpath('//triggered_send_description[1]').first.text.to_i
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                ###################################################################
         | 
| 128 | 
            +
             | 
| 121 129 | 
             
                alias :job_send :handle_job_id_result
         | 
| 122 130 |  | 
| 131 | 
            +
                ###################################################################
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                def list_bulkasync(resp)
         | 
| 134 | 
            +
                  resp.xpath('//batchID').first.text.to_i
         | 
| 135 | 
            +
                end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                def subscriber_bulkasync(resp)
         | 
| 138 | 
            +
                  resp.xpath('//batchID').first.text.to_i
         | 
| 139 | 
            +
                end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                def tracking_sent_bulkasync_all(resp)
         | 
| 142 | 
            +
                  resp.xpath('//batchID').first.text.to_i
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                def tracking_sent_bulkasync_all_attributes(resp)
         | 
| 146 | 
            +
                  resp.xpath('//batchID').first.text.to_i
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
             | 
| 123 150 | 
             
                ###################################################################
         | 
| 124 151 | 
             
                private
         | 
| 125 152 | 
             
                ###################################################################
         | 
    
        data/spec/exact_target_data.yml
    CHANGED
    
    | @@ -122,6 +122,12 @@ email_retrieve_body: | |
| 122 122 |  | 
| 123 123 | 
             
            ####################################################################################
         | 
| 124 124 |  | 
| 125 | 
            +
            triggeredsend_add:
         | 
| 126 | 
            +
              request: <system_name>triggeredsend</system_name><action>add</action><search_type></search_type><search_value></search_value><TriggeredSend xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://exacttarget.com/wsdl/partnerAPI"><TriggeredSendDefinition><CustomerKey>email_name</CustomerKey></TriggeredSendDefinition><Subscribers><EmailAddress>recipient@foo.com</EmailAddress><SubscriberKey>recipient@foo.com</SubscriberKey></Subscribers><Attributes><Name>attr_1</Name><Value><![CDATA[val_1]]></Value></Attributes><Attributes><Name>attr_2</Name><Value><![CDATA[val_2]]></Value></Attributes></TriggeredSend>
         | 
| 127 | 
            +
              response: <triggeredsend><triggered_send_info>Triggered Send was added successfully</triggered_send_info><triggered_send_description>0</triggered_send_description></triggeredsend>
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            ####################################################################################
         | 
| 130 | 
            +
             | 
| 125 131 | 
             
            job_send:
         | 
| 126 132 | 
             
              request:  <system_name>job</system_name><action>send</action><search_type>emailid</search_type><search_value>112233</search_value><from_name>FrName</from_name><from_email>fr.email@nowhere.com</from_email><additional>addit</additional><multipart_mime>true</multipart_mime><track_links>false</track_links><send_date>5/3/2011</send_date><send_time>17:35</send_time><lists><list>12345</list><list>12346</list></lists><suppress><list>35612</list></suppress><test_send>true</test_send>
         | 
| 127 133 | 
             
              response: <job><job_info>Job was successfully created.</job_info><job_description>2030602</job_description></job>
         | 
    
        data/spec/exact_target_spec.rb
    CHANGED
    
    | @@ -154,7 +154,7 @@ describe ExactTarget do | |
| 154 154 | 
             
              end
         | 
| 155 155 |  | 
| 156 156 | 
             
              test_et :batch_inquire, 8912 do
         | 
| 157 | 
            -
                @res.should == 'Completed'
         | 
| 157 | 
            +
                @res.status.should == 'Completed'
         | 
| 158 158 | 
             
              end
         | 
| 159 159 |  | 
| 160 160 | 
             
              #################################################################
         | 
| @@ -283,6 +283,12 @@ describe ExactTarget do | |
| 283 283 |  | 
| 284 284 | 
             
              #################################################################
         | 
| 285 285 |  | 
| 286 | 
            +
              test_et :triggeredsend_add, 'recipient@foo.com', 'email_name', {:attr_1 => 'val_1', :attr_2 => 'val_2'} do
         | 
| 287 | 
            +
                @res.should == 0
         | 
| 288 | 
            +
              end
         | 
| 289 | 
            +
             | 
| 290 | 
            +
              #################################################################
         | 
| 291 | 
            +
             | 
| 286 292 | 
             
              test_et :job_send, 112233, [12345, 12346],
         | 
| 287 293 | 
             
                      :suppress_ids => 35612,
         | 
| 288 294 | 
             
                      :from_name => 'FrName',
         | 
| @@ -309,7 +315,8 @@ describe ExactTarget do | |
| 309 315 |  | 
| 310 316 | 
             
              context :send_to_exact_target do
         | 
| 311 317 | 
             
                before(:each) do
         | 
| 312 | 
            -
                  @path = '/foo | 
| 318 | 
            +
                  @path = '/foo'
         | 
| 319 | 
            +
                  @data = 'qf=xml&xml=%3Csomexml/%3E'
         | 
| 313 320 | 
             
                  @http = mock('Net::HTTP')
         | 
| 314 321 | 
             
                  @http.should_receive(:use_ssl=).with(true)
         | 
| 315 322 | 
             
                  @http.should_receive(:open_timeout=).with(2)
         | 
| @@ -317,15 +324,18 @@ describe ExactTarget do | |
| 317 324 | 
             
                  Net::HTTP.should_receive(:new).with('base.url.com', 443).and_return(@http)
         | 
| 318 325 | 
             
                end
         | 
| 319 326 |  | 
| 327 | 
            +
                after { ExactTarget.configuration.http_method = nil }
         | 
| 328 | 
            +
             | 
| 320 329 | 
             
                specify :success do
         | 
| 321 330 | 
             
                  resp = stub('Net::HTTPSuccess', :is_a? => true, :body => 'xyz')
         | 
| 322 | 
            -
                  @http.should_receive(:get).with(@path).and_return(resp)
         | 
| 331 | 
            +
                  @http.should_receive(:get).with("#{@path}?#{@data}").and_return(resp)
         | 
| 323 332 | 
             
                  ExactTarget.send_to_exact_target('<somexml/>').should == 'xyz'
         | 
| 324 333 | 
             
                end
         | 
| 325 334 |  | 
| 326 335 | 
             
                specify :error do
         | 
| 336 | 
            +
                  ExactTarget.configuration.http_method = :post
         | 
| 327 337 | 
             
                  resp = stub('Net::HTTPFailure', :error! => 'err')
         | 
| 328 | 
            -
                  @http.should_receive(: | 
| 338 | 
            +
                  @http.should_receive(:post).with(@path, @data).and_return(resp)
         | 
| 329 339 | 
             
                  ExactTarget.send_to_exact_target('<somexml/>').should == 'err'
         | 
| 330 340 | 
             
                end
         | 
| 331 341 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -2,22 +2,24 @@ | |
| 2 2 | 
             
            name: exact-target
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 4 | 
             
              prerelease: 
         | 
| 5 | 
            -
              version: 0. | 
| 5 | 
            +
              version: 0.1.8
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors: 
         | 
| 8 | 
            -
            - David McCullars
         | 
| 8 | 
            +
            - David McCullars, Paul Nock, Jeff Ching
         | 
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 12 |  | 
| 13 | 
            -
            date:  | 
| 13 | 
            +
            date: 2012-02-09 00:00:00 Z
         | 
| 14 14 | 
             
            dependencies: []
         | 
| 15 15 |  | 
| 16 16 | 
             
            description: |
         | 
| 17 17 | 
             
              This is a pure-ruby implementation of the ExactTarget api.
         | 
| 18 18 | 
             
              For more information consule http://www.exacttarget.com/.
         | 
| 19 19 |  | 
| 20 | 
            -
            email:  | 
| 20 | 
            +
            email: 
         | 
| 21 | 
            +
            - dmccullars@ePublishing.com
         | 
| 22 | 
            +
            - nocksf@gmail.com
         | 
| 21 23 | 
             
            executables: []
         | 
| 22 24 |  | 
| 23 25 | 
             
            extensions: []
         | 
| @@ -35,6 +37,7 @@ files: | |
| 35 37 | 
             
            - Manifest
         | 
| 36 38 | 
             
            - README.rdoc
         | 
| 37 39 | 
             
            - Rakefile
         | 
| 40 | 
            +
            - exact-target.gemspec
         | 
| 38 41 | 
             
            - lib/exact-target.rb
         | 
| 39 42 | 
             
            - lib/exact_target.rb
         | 
| 40 43 | 
             
            - lib/exact_target/builder_ext.rb
         | 
| @@ -54,7 +57,6 @@ files: | |
| 54 57 | 
             
            - spec/exact_target_spec.rb
         | 
| 55 58 | 
             
            - spec/spec.opts
         | 
| 56 59 | 
             
            - spec/spec_helper.rb
         | 
| 57 | 
            -
            - exact-target.gemspec
         | 
| 58 60 | 
             
            homepage: http://github.com/ePublishing/exact_target
         | 
| 59 61 | 
             
            licenses: []
         | 
| 60 62 |  |