mailjet 1.5.4 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +1,28 @@
1
- # encoding: utf-8
2
- require 'active_support'
1
+ require "json"
3
2
 
4
3
  module Mailjet
5
4
  class ApiError < StandardError
5
+ attr_reader :code, :reason
6
6
 
7
- attr_accessor :code, :reason
7
+ # @param code [Integer] HTTP response status code
8
+ # @param body [String] JSON response body
9
+ # @param request [Object] any request object
10
+ # @param url [String] request URL
11
+ # @param params [Hash] request headers and parameters
12
+ def initialize(code, body, request, url, params)
13
+ @code = code
14
+ @reason = begin
15
+ resdec = JSON.parse(body)
16
+ resdec['ErrorMessage']
17
+ rescue JSON::ParserError
18
+ body
19
+ end
8
20
 
21
+ message = "error #{code} while sending #{request.inspect} to #{url} with #{params.inspect}"
22
+ error_details = body.inspect
23
+ hint = "Please see https://dev.mailjet.com/guides/#status-codes for more informations on error numbers."
9
24
 
10
- def initialize(code, res, request, request_path, params)
11
- self.code = code
12
- self.reason = ""
13
- unless res.blank?
14
- resdec = ActiveSupport::JSON.decode(res)
15
- self.reason = resdec['ErrorMessage']
16
- end
17
- # code is ugly, output is pretty
18
- super("error #{code} while sending #{request.inspect} to #{request_path} with #{params.inspect}\n\n" +
19
- if res['errors'].present?
20
- [(res['errors'] || [])].flatten.map do |param, text|
21
- [param, text].map(&:to_s).reject(&:blank?).join(': ')
22
- end.join("\n")
23
- else
24
- res.inspect
25
- end + "\n\nPlease see https://dev.mailjet.com/guides/#status-codes for more informations on error numbers.\n\n"
26
- )
25
+ super("#{message}\n\n#{error_details}\n\n#{hint}\n\n")
27
26
  end
28
27
  end
29
28
  end
@@ -1,17 +1,69 @@
1
- require 'active_support/core_ext/module/attribute_accessors'
2
-
3
1
  module Mailjet
4
2
  module Configuration
5
- mattr_accessor :api_key, :secret_key, :default_from
3
+ def self.api_key
4
+ @api_key
5
+ end
6
+
7
+ def self.api_key=(api_key)
8
+ @api_key = api_key
9
+ end
10
+
11
+ def self.secret_key
12
+ @secret_key
13
+ end
14
+
15
+ def self.secret_key=(secret_key)
16
+ @secret_key = secret_key
17
+ end
18
+
19
+ def self.default_from
20
+ @default_from
21
+ end
22
+
23
+ def self.default_from=(default_from)
24
+ @default_from = default_from
25
+ end
26
+
27
+ def self.api_version
28
+ @api_version
29
+ end
30
+
31
+ def self.api_version=(api_version)
32
+ @api_version = api_version
33
+ end
34
+
35
+ def self.sandbox_mode
36
+ @sandbox_mode
37
+ end
38
+
39
+ def self.sandbox_mode=(sandbox_mode)
40
+ @sandbox_mode = sandbox_mode
41
+ end
42
+
43
+ def self.end_point
44
+ @end_point
45
+ end
46
+
47
+ def self.end_point=(end_point)
48
+ @end_point = end_point
49
+ end
50
+
51
+ def self.perform_api_call
52
+ @perform_api_call
53
+ end
54
+
55
+ def self.perform_api_call=(perform_api_call)
56
+ @perform_api_call = perform_api_call
57
+ end
6
58
 
7
59
  DEFAULT = {
8
60
  api_version: 'v3',
61
+ sandbox_mode: false,
9
62
  end_point: 'https://api.mailjet.com',
10
63
  perform_api_call: true,
11
64
  }
12
65
 
13
66
  DEFAULT.each do |param, default_value|
14
- mattr_accessor param
15
67
  self.send("#{param}=", default_value)
16
68
  end
17
69
  end
@@ -1,16 +1,13 @@
1
1
  require 'rest_client'
2
2
  require 'mailjet/gem_extensions/rest_client'
3
- require 'active_support/core_ext/module/delegation'
4
3
  require 'json'
5
4
 
6
5
  module Mailjet
7
6
  class Connection
8
7
 
9
- attr_accessor :adapter, :public_operations, :read_only, :perform_api_call
8
+ attr_accessor :adapter, :public_operations, :read_only, :perform_api_call, :read_timeout, :open_timeout
10
9
  alias :read_only? :read_only
11
10
 
12
- delegate :options, :concat_urls, :url, to: :adapter
13
-
14
11
  def [](suburl, &new_block)
15
12
  broken_url = url.split("/")
16
13
  if broken_url.include?("contactslist") && broken_url.include?("managemanycontacts") && broken_url.last.to_i > 0
@@ -35,8 +32,10 @@ module Mailjet
35
32
  adapter_class = options[:adapter_class] || RestClient::Resource
36
33
  self.public_operations = options[:public_operations] || []
37
34
  self.read_only = options[:read_only]
35
+ self.read_timeout = options[:read_timeout]
36
+ self.open_timeout = options[:open_timeout]
38
37
  # self.adapter = adapter_class.new(end_point, options.merge(user: api_key, password: secret_key, :verify_ssl => false, content_type: 'application/json'))
39
- self.adapter = adapter_class.new(end_point, options.merge(user: api_key, password: secret_key, content_type: 'application/json'))
38
+ self.adapter = adapter_class.new(end_point, options.merge(user: api_key, password: secret_key, content_type: 'application/json', read_timeout: self.read_timeout, open_timeout: self.open_timeout))
40
39
  self.perform_api_call = options.key?(:perform_api_call) ? options[:perform_api_call] : true
41
40
  end
42
41
 
@@ -56,6 +55,18 @@ module Mailjet
56
55
  handle_api_call(:delete, additional_headers, &block)
57
56
  end
58
57
 
58
+ def options
59
+ self.adapter.options
60
+ end
61
+
62
+ def concat_urls(*options)
63
+ self.adapter.concat_urls(*options)
64
+ end
65
+
66
+ def url
67
+ self.adapter.url
68
+ end
69
+
59
70
  private
60
71
 
61
72
  def handle_api_call(method, additional_headers = {}, payload = {}, &block)
@@ -85,7 +96,26 @@ module Mailjet
85
96
  formatted_payload = (additional_headers[:content_type] == :json) ? JSON.parse(payload) : payload
86
97
  params = params.merge(formatted_payload)
87
98
 
88
- raise Mailjet::ApiError.new(e.http_code, e.http_body, @adapter, @adapter.url, params)
99
+ http_body = if e.http_headers[:content_type].include?("application/json")
100
+ e.http_body
101
+ else
102
+ "{}"
103
+ end
104
+
105
+ if sent_invalid_email?(e.http_body, @adapter.url)
106
+ return e.http_body
107
+ else
108
+ raise Mailjet::ApiError.new(e.http_code, http_body, @adapter, @adapter.url, params)
109
+ end
110
+ end
111
+
112
+ def sent_invalid_email?(error_http_body, url)
113
+ return false unless url.include?('v3.1/send')
114
+ return unless error_http_body
115
+
116
+ parsed_body = JSON.parse(error_http_body)
117
+ error_message = parsed_body['Messages']&.first&.dig('Errors')&.first&.dig('ErrorMessage')
118
+ error_message.include?('is an invalid email address.')
89
119
  end
90
120
 
91
121
  end
@@ -42,6 +42,13 @@ class Mailjet::APIMailer
42
42
 
43
43
  CONNECTION_PERMITTED_OPTIONS = [:api_key, :secret_key]
44
44
 
45
+ HEADER_BLACKLIST = [
46
+ 'from', 'sender', 'subject', 'to', 'cc', 'bcc', 'return-path', 'delivered-to', 'dkim-signature',
47
+ 'domainkey-status', 'received-spf', 'authentication-results', 'received', 'user-agent', 'x-mailer',
48
+ 'x-feedback-id', 'list-id', 'date', 'x-csa-complaints', 'message-id', 'reply-to', 'content-type',
49
+ 'mime-version', 'content-transfer-encoding'
50
+ ]
51
+
45
52
  def initialize(opts = {})
46
53
  options = HashWithIndifferentAccess.new(opts)
47
54
 
@@ -67,7 +74,7 @@ class Mailjet::APIMailer
67
74
  version = options[:version] || Mailjet.config.api_version
68
75
 
69
76
  if (version == 'v3.1')
70
- Mailjet::Send.create({ :Messages => [setContentV3_1(mail)] }, options)
77
+ Mailjet::Send.create({ :Messages => [setContentV3_1(mail)], SandboxMode: Mailjet.config.sandbox_mode }, options)
71
78
  else
72
79
  Mailjet::Send.create(setContentV3_0(mail), options)
73
80
  end
@@ -110,7 +117,7 @@ class Mailjet::APIMailer
110
117
  if mail.header && mail.header.fields.any?
111
118
  content[:Headers] = {}
112
119
  mail.header.fields.each do |header|
113
- if header.name.start_with?('X-') && !header.name.start_with?('X-MJ') && !header.name.start_with?('X-Mailjet')
120
+ if !header.name.start_with?('X-MJ') && !header.name.start_with?('X-Mailjet') && !HEADER_BLACKLIST.include?(header.name.downcase)
114
121
  content[:Headers][header.name] = header.value
115
122
  end
116
123
  end
@@ -119,8 +126,8 @@ class Mailjet::APIMailer
119
126
  # ReplyTo property was added in v3.1
120
127
  # Passing it as an header if mail.reply_to
121
128
 
122
- if mail.reply_to
123
- if mail.reply_to.respond_to?(:display_names) && mail.reply_to.display_names.first
129
+ if mail[:reply_to]
130
+ if mail[:reply_to].respond_to?(:display_names) && mail[:reply_to].display_names.first
124
131
  content[:ReplyTo] = {:Email=> mail[:reply_to].addresses.first, :Name=> mail[:reply_to].display_names.first}
125
132
  else
126
133
  content[:ReplyTo] = {:Email=> mail[:reply_to].addresses.first}
@@ -163,8 +170,13 @@ class Mailjet::APIMailer
163
170
  ccs =[{:Email=>mail[:cc].address.first}]
164
171
  end
165
172
  else
173
+ ccs = []
166
174
  mail[:cc].each do |cc|
167
- ccs << {:Email=> cc.address, :Name=>cc.display_name}
175
+ if cc.display_name
176
+ ccs << {:Email=> cc.address, :Name=>cc.display_name}
177
+ else
178
+ ccs << {:Email=> cc.address}
179
+ end
168
180
  end
169
181
  end
170
182
  end
@@ -177,7 +189,8 @@ class Mailjet::APIMailer
177
189
  payload[:Bcc] = [{:Email=>mail[:bcc].address.first}]
178
190
  end
179
191
  else
180
- mail[:bcc].formatted.each do |bcc|
192
+ bccs = []
193
+ mail[:bcc].each do |bcc|
181
194
  if bcc.display_name
182
195
  bccs << {:Email=> bcc.address, :Name=>bcc.display_name}
183
196
  else
@@ -198,7 +211,26 @@ class Mailjet::APIMailer
198
211
  payload[:Cc] = ccs if mail[:cc]
199
212
  payload[:Bcc] = bccs if mail[:bcc]
200
213
 
201
- payload
214
+ decode_emails_V3_1!(payload)
215
+ end
216
+
217
+ def decode_emails_V3_1!(payload)
218
+ # ActionMailer may have handed us encoded email
219
+ # addresses, mailjet will reject. Therefore we
220
+ # walk through the payload to decode them back.
221
+ payload.each do |key, value|
222
+ if key == :Email
223
+ payload[key] = Mail::Encodings.value_decode(value)
224
+ elsif value.is_a?(Hash)
225
+ decode_emails_V3_1! value
226
+ elsif value.is_a?(Array)
227
+ value.each do |item|
228
+ if item.is_a?(Hash)
229
+ decode_emails_V3_1! item
230
+ end
231
+ end
232
+ end
233
+ end
202
234
  end
203
235
 
204
236
  def setContentV3_0(mail)
@@ -265,7 +297,7 @@ class Mailjet::APIMailer
265
297
  payload.merge(content)
266
298
  .merge(base_from)
267
299
  .merge(@delivery_method_options_v3_0)
268
- end
300
+ end
269
301
  end
270
302
 
271
303
  ActionMailer::Base.add_delivery_method :mailjet_api, Mailjet::APIMailer
@@ -1,6 +1,5 @@
1
- require 'active_support'
2
1
  require 'rack/request'
3
-
2
+ require 'json'
4
3
 
5
4
  module Mailjet
6
5
  module Rack
@@ -13,7 +12,7 @@ module Mailjet
13
12
 
14
13
  def call(env)
15
14
  if env['PATH_INFO'] == @path && (content = env['rack.input'].read)
16
- @block.call(ActiveSupport::JSON.decode(content))
15
+ @block.call(JSON.parse(content))
17
16
  [200, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []]
18
17
  else
19
18
  @app.call(env)
@@ -1,12 +1,10 @@
1
1
  require 'mailjet/connection'
2
- require 'active_support/hash_with_indifferent_access'
3
- require 'active_support/core_ext/class'
4
- require 'active_support/core_ext/hash'
5
2
  require 'active_support/core_ext/string'
6
3
  require 'active_support/core_ext/module/delegation'
7
- require 'active_support/concern'
8
- require 'active_support/json/decoding'
9
4
  #require 'mail'
5
+ require 'active_support/hash_with_indifferent_access'
6
+ require 'active_support/core_ext/hash'
7
+ require 'active_support/json/decoding'
10
8
  require 'json'
11
9
 
12
10
 
@@ -18,38 +16,42 @@ require 'json'
18
16
 
19
17
  module Mailjet
20
18
  module Resource
21
- extend ActiveSupport::Concern
22
19
 
23
20
  # define here available options for filtering
24
- OPTIONS = [:version, :url, :perform_api_call, :api_key, :secret_key]
21
+ OPTIONS = [:version, :url, :perform_api_call, :api_key, :secret_key, :read_timeout, :open_timeout]
25
22
 
26
23
  NON_JSON_URLS = ['v3/send/message'] # urls that don't accept JSON input
27
24
 
28
- included do
29
- cattr_accessor :resource_path, :public_operations, :read_only, :filters, :resourceprop, :action, :non_json_urls, :version
30
- cattr_writer :connection
25
+ def self.included(base)
26
+ base.extend ClassMethods
27
+ base.class_eval do
28
+ cattr_accessor :resource_path, :public_operations, :read_only, :filters, :resourceprop, :read_only_attributes, :action, :non_json_urls, :version
29
+ cattr_writer :connection
31
30
 
32
- def self.connection(options = {})
33
- class_variable_get(:@@connection) || default_connection(options)
34
- end
31
+ def self.connection(options = {})
32
+ class_variable_get(:@@connection) || default_connection(options)
33
+ end
35
34
 
36
- def self.default_connection(options = {})
37
- Mailjet::Connection.new(
38
- "#{options[:url]}/#{options[:version]}/#{resource_path}",
39
- options[:api_key] || Mailjet.config.api_key,
40
- options[:secret_key] || Mailjet.config.secret_key,
41
- public_operations: public_operations,
42
- read_only: read_only,
43
- perform_api_call: options[:perform_api_call])
44
- end
35
+ def self.default_connection(options = {})
36
+ Mailjet::Connection.new(
37
+ "#{options[:url]}/#{options[:version]}/#{resource_path}",
38
+ options[:api_key] || Mailjet.config.api_key,
39
+ options[:secret_key] || Mailjet.config.secret_key,
40
+ public_operations: public_operations,
41
+ read_only: read_only,
42
+ perform_api_call: options[:perform_api_call],
43
+ open_timeout: options[:open_timeout],
44
+ read_timeout: options[:read_timeout])
45
+ end
45
46
 
46
- def self.default_headers
47
- if NON_JSON_URLS.include?(self.resource_path) # don't use JSON if Send API
48
- default_headers = { accept: :json, accept_encoding: :deflate }
49
- else
50
- default_headers = { accept: :json, accept_encoding: :deflate, content_type: :json } #use JSON if *not* Send API
47
+ def self.default_headers
48
+ if NON_JSON_URLS.include?(self.resource_path) # don't use JSON if Send API
49
+ default_headers = { accept: :json, accept_encoding: :deflate }
50
+ else
51
+ default_headers = { accept: :json, accept_encoding: :deflate, content_type: :json } #use JSON if *not* Send API
52
+ end
53
+ return default_headers.merge(user_agent: "mailjet-api-v3-ruby/#{Gem.loaded_specs["mailjet"].version}")
51
54
  end
52
- return default_headers.merge(user_agent: "mailjet-api-v3-ruby/#{Gem.loaded_specs["mailjet"].version}")
53
55
  end
54
56
  end
55
57
 
@@ -69,16 +71,22 @@ module Mailjet
69
71
  def count(options = {})
70
72
  opts = define_options(options)
71
73
  response_json = connection(opts).get(default_headers.merge(params: {limit: 1, countrecords: 1}))
72
- response_hash = ActiveSupport::JSON.decode(response_json)
74
+ response_hash = JSON.parse(response_json)
73
75
  response_hash['Total']
74
76
  end
75
77
 
76
78
  def find(id, job_id = nil, options = {})
79
+ normalized_id = if id.is_a? String
80
+ URI.encode_www_form_component(id)
81
+ else
82
+ id
83
+ end
84
+
77
85
  # if action method, ammend url to appropriate id
78
86
  opts = define_options(options)
79
- self.resource_path = create_action_resource_path(id, job_id) if self.action
87
+ self.resource_path = create_action_resource_path(normalized_id, job_id) if self.action
80
88
  #
81
- attributes = parse_api_json(connection(opts)[id].get(default_headers)).first
89
+ attributes = parse_api_json(connection(opts)[normalized_id].get(default_headers)).first
82
90
  instanciate_from_api(attributes)
83
91
 
84
92
  rescue Mailjet::ApiError => e
@@ -92,7 +100,7 @@ module Mailjet
92
100
  def create(attributes = {}, options = {})
93
101
  # if action method, ammend url to appropriate id
94
102
  opts = define_options(options)
95
- self.resource_path = create_action_resource_path(attributes[:id]) if self.action
103
+ self.resource_path = create_action_resource_path(attributes[:id]) if (self.action and attributes[:id])
96
104
  attributes.tap { |hs| hs.delete(:id) }
97
105
 
98
106
  if Mailjet.config.default_from and self.resource_path == 'send/'
@@ -106,7 +114,7 @@ module Mailjet
106
114
 
107
115
  self.new(attributes).tap do |resource|
108
116
  resource.save!(opts)
109
- resource.persisted = true
117
+ resource.attributes[:persisted] = true
110
118
  end
111
119
 
112
120
  end
@@ -123,7 +131,7 @@ module Mailjet
123
131
  end
124
132
 
125
133
  def parse_api_json(response_json)
126
- response_hash = ActiveSupport::JSON.decode(response_json)
134
+ response_hash = JSON.parse(response_json)
127
135
 
128
136
  #Take the response from the API and put it through a method -- taken from the ActiveSupport library -- which converts
129
137
  #the date-time from "2014-05-19T15:31:09Z" to "Mon, 19 May 2014 15:31:09 +0000" format.
@@ -138,17 +146,17 @@ module Mailjet
138
146
  end
139
147
 
140
148
  def create_action_resource_path(id, job_id = nil)
141
- url_elements = self.resource_path.split("/")
142
- url_elements.delete_at(url_elements.length-1) if url_elements.last.to_i > 0 #if there is a trailing number for the job id from last call, delete it
149
+ url_elements = self.resource_path.split("/")
150
+ url_elements.delete_at(url_elements.length-1) if url_elements.last.to_i > 0 #if there is a trailing number for the job id from last call, delete it
143
151
 
144
- if !(url_elements[1] == "contacts" && self.action == "managemanycontacts")
145
- url_elements[2] = id.to_s
146
- end
152
+ if !(url_elements[1] == "contacts" && self.action == "managemanycontacts")
153
+ url_elements[2] = id.to_s
154
+ end
147
155
 
148
- url_elements << job_id.to_s if job_id #if job_id exists, amend it to end of the URI
149
- url = url_elements.join("/")
156
+ url_elements << job_id.to_s if job_id #if job_id exists, amend it to end of the URI
157
+ url = url_elements.join("/")
150
158
 
151
- return url
159
+ return url
152
160
  end
153
161
 
154
162
 
@@ -250,7 +258,7 @@ module Mailjet
250
258
  if opts[:perform_api_call] && !persisted?
251
259
  # get attributes only for entity creation
252
260
  self.attributes = if self.resource_path == 'send'
253
- ActiveSupport::JSON.decode(response)
261
+ JSON.parse(response)
254
262
  else
255
263
  parse_api_json(response).first
256
264
  end
@@ -292,7 +300,7 @@ module Mailjet
292
300
  save(opts)
293
301
  end
294
302
 
295
- def delete(call)
303
+ def delete
296
304
  self.class.delete(id)
297
305
  end
298
306
 
@@ -309,12 +317,15 @@ module Mailjet
309
317
  def formatted_payload
310
318
  payload = attributes.reject { |k,v| v.blank? }
311
319
  if persisted?
312
- payload = payload.slice(*resourceprop)
320
+ payload = payload.slice(*resourceprop.map(&:to_s))
321
+ .except(*read_only_attributes.map(&:to_s))
313
322
  end
314
323
  payload = camelcase_keys(payload)
315
324
  payload.tap { |hs| hs.delete("Persisted") }
316
325
  payload.inject({}) do |h, (k, v)|
317
- v = v.utc.as_json if v.respond_to? :utc
326
+ if v.respond_to? :utc
327
+ v = v.utc.to_s
328
+ end
318
329
  h.merge!({k => v})
319
330
  end
320
331
  end
@@ -337,20 +348,16 @@ module Mailjet
337
348
 
338
349
  def method_missing(method_symbol, *arguments) #:nodoc:
339
350
  method_name = method_symbol.to_s
340
- if method_name =~ /(=|\?)$/
341
- case $1
342
- when "="
343
- attributes[$`] = arguments.first
344
- when "?"
345
- attributes[$`]
346
- end
347
- else
348
- return attributes[method_name] if attributes.include?(method_name)
349
- # not set right now but we know about it
350
- # return nil if known_attributes.include?(method_name)
351
- super
351
+ if method_name.end_with?("=")
352
+ attributes[method_name.chop] = arguments.first
353
+ return
352
354
  end
353
- end
354
355
 
356
+ if attributes.include?(method_name)
357
+ return attributes[method_name]
358
+ end
359
+
360
+ super
361
+ end
355
362
  end
356
363
  end
@@ -1,7 +1,7 @@
1
1
  module Mailjet
2
2
  class Campaigndraft
3
3
  include Mailjet::Resource
4
- self.resource_path = 'v3/REST/campaigndraft'
4
+ self.resource_path = 'REST/campaigndraft'
5
5
  self.public_operations = [:get, :put, :post]
6
6
  self.filters = [:campaign, :contacts_list, :delivered_at, :edit_mode, :is_archived, :is_campaign, :is_deleted, :is_handled, :is_starred, :modified, :news_letter_template, :segmentation, :status, :subject, :template]
7
7
  self.resourceprop = [:campaign, :contacts_list, :created_at, :delivered_at, :edit_mode, :id, :is_starred, :is_text_part_included, :locale, :modified_at, :preset, :reply_email, :segmentation, :sender, :sender_email, :sender_name, :status, :subject, :template_id, :title, :url, :used, 'CampaignID', 'CampaignALT', 'ContactsListID', 'ContactsListALT', 'SegmentationID', 'SegmentationALT', :contacts_list_id,'TemplateID']
@@ -2,10 +2,26 @@ module Mailjet
2
2
  class Campaigndraft_detailcontent
3
3
  include Mailjet::Resource
4
4
  self.action = "detailcontent"
5
- self.resource_path = "v3/REST/campaigndraft/id/#{self.action}"
5
+ self.resource_path = "REST/campaigndraft/id/#{self.action}"
6
6
  self.public_operations = [:get, :post]
7
7
  self.filters = []
8
8
  self.resourceprop = [:text_part, :html_part, :headers, :mjml_content]
9
9
 
10
+ def self.find(id, job_id = nil, options = {})
11
+ opts = define_options(options)
12
+ self.resource_path = create_action_resource_path(id, job_id) if self.action
13
+
14
+ raw_data = parse_api_json(connection(opts)[id].get(default_headers))
15
+
16
+ raw_data.map do |entity|
17
+ instanciate_from_api(entity)
18
+ end
19
+ rescue Mailjet::ApiError => e
20
+ if e.code == 404
21
+ nil
22
+ else
23
+ raise e
24
+ end
25
+ end
10
26
  end
11
27
  end
@@ -2,7 +2,7 @@ module Mailjet
2
2
  class Campaigndraft_schedule
3
3
  include Mailjet::Resource
4
4
  self.action = "schedule"
5
- self.resource_path = "v3/REST/campaigndraft/id/#{self.action}"
5
+ self.resource_path = "REST/campaigndraft/id/#{self.action}"
6
6
  self.public_operations = [:post, :delete , :get]
7
7
  self.filters = []
8
8
  self.resourceprop = [:date]
@@ -2,7 +2,7 @@ module Mailjet
2
2
  class Campaigndraft_send
3
3
  include Mailjet::Resource
4
4
  self.action = "send"
5
- self.resource_path = "v3/REST/campaigndraft/id/#{self.action}"
5
+ self.resource_path = "REST/campaigndraft/id/#{self.action}"
6
6
  self.public_operations = [:post]
7
7
  self.filters = []
8
8
  self.resourceprop = []
@@ -2,7 +2,7 @@ module Mailjet
2
2
  class Campaigndraft_status
3
3
  include Mailjet::Resource
4
4
  self.action = 'status'
5
- self.resource_path = "v3/REST/campaigndraft/id/#{self.action}"
5
+ self.resource_path = "REST/campaigndraft/id/#{self.action}"
6
6
  self.public_operations = [:get]
7
7
  self.filters = []
8
8
  self.resourceprop = []
@@ -2,7 +2,7 @@ module Mailjet
2
2
  class Campaigndraft_test
3
3
  include Mailjet::Resource
4
4
  self.action = "test"
5
- self.resource_path = "v3/REST/campaigndraft/id/#{self.action}"
5
+ self.resource_path = "REST/campaigndraft/id/#{self.action}"
6
6
  self.public_operations = [:post]
7
7
  self.filters = []
8
8
  self.resourceprop = [:email, :name]
@@ -4,7 +4,21 @@ module Mailjet
4
4
  self.resource_path = 'REST/contact'
5
5
  self.public_operations = [:get, :put, :post]
6
6
  self.filters = [:campaign, :contacts_list, :is_unsubscribed, :last_activity_at, :recipient, :status]
7
- self.resourceprop = [:created_at, :delivered_count, :email, :id, :is_opt_in_pending, :is_spam_complaining, :last_activity_at, :last_update_at, :name, :unsubscribed_at, :unsubscribed_by]
7
+ self.resourceprop = [
8
+ :created_at,
9
+ :delivered_count,
10
+ :email,
11
+ :id,
12
+ :is_opt_in_pending,
13
+ :is_spam_complaining,
14
+ :last_activity_at,
15
+ :last_update_at,
16
+ :name,
17
+ :unsubscribed_at,
18
+ :unsubscribed_by,
19
+ :is_excluded_from_campaigns
20
+ ]
21
+ self.read_only_attributes = [:created_at, :last_activity_at, :last_update_at, :unsubscribed_at]
8
22
 
9
23
  end
10
24
  end
@@ -6,5 +6,22 @@ module Mailjet
6
6
  self.public_operations = [:get]
7
7
  self.filters = []
8
8
  self.resourceprop = []
9
+
10
+ def self.find(id, job_id = nil, options = {})
11
+ opts = define_options(options)
12
+ self.resource_path = create_action_resource_path(id, job_id) if self.action
13
+
14
+ raw_data = parse_api_json(connection(opts).get(default_headers))
15
+
16
+ raw_data.map do |entity|
17
+ instanciate_from_api(entity)
18
+ end
19
+ rescue Mailjet::ApiError => e
20
+ if e.code == 404
21
+ nil
22
+ else
23
+ raise e
24
+ end
25
+ end
9
26
  end
10
27
  end