mailjet 1.7.3 → 1.8.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8196f5f49e3b7aa6766ad97b0e8a2346c4591f56f30a37e124a346ba46e06f3b
4
- data.tar.gz: b7264d284ac5267785d26c0d8a14810f714ea74893f52eb8d82dc049347b1883
3
+ metadata.gz: c9c74309f3d5e557d27fe01548e0998a987c90a9bd1e5e52c187c23d33fb5475
4
+ data.tar.gz: 3c44b00a89c535c6143d0011fa6e11ca1d6bcdbc82ed984eea4b5f23b0483b89
5
5
  SHA512:
6
- metadata.gz: e2c289c1757e6cbc7980296b2de8b9bf7052dbea80265e93d4131a8b8de720c11daa07e83d1ca0d42f4acbc8e637ed387130ca6cf12efbf896e089fb460cc4f8
7
- data.tar.gz: 7502fade84d6f8690394c3a911dfdb48786d21a3414a79416436a04da69aba2f0450b35ea1912b586c69126d6b3052573c3b29a8f3929c969b3d97c3bb0d76ad
6
+ metadata.gz: a35a75e7a661f72c28fda90a8403f363252f36cf9573786e512f1721b807b6f450d51dafdc6d8ae8c816b4bd0f32b4abe008f67b6189647a0caa70f0ebbc929d
7
+ data.tar.gz: 513f1178e1f7e625b177faa7220d60fbb4208a5d38f91642d173ee7a63d39fa3758d189f04e9a4a3e928d84e8d4921a17c22d281bb9fca2b8cf47c7f9f7348ca
data/README.md CHANGED
@@ -76,7 +76,7 @@ Check out all the resources and Ruby code examples in the [Offical Documentation
76
76
 
77
77
  This library requires **Ruby v2.2.X**.
78
78
 
79
- The Rails ActionMailer integration is designed for Rails 3.X and 4.X.
79
+ The Rails ActionMailer integration is designed for Rails >= 5.
80
80
 
81
81
  ## Installation
82
82
 
@@ -139,7 +139,7 @@ Here's an example on how to send an email:
139
139
  require 'mailjet'
140
140
  Mailjet.configure do |config|
141
141
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
142
- config.secret_key = ENV['MJ_APIKEY_PRIVATE']
142
+ config.secret_key = ENV['MJ_APIKEY_PRIVATE']
143
143
  config.api_version = "v3.1"
144
144
  end
145
145
  variable = Mailjet::Send.create(messages: [{
@@ -177,7 +177,7 @@ Since most Email API endpoints are located under `v3`, it is set as the default
177
177
  require 'mailjet'
178
178
  Mailjet.configure do |config|
179
179
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
180
- config.secret_key = ENV['MJ_APIKEY_PRIVATE']
180
+ config.secret_key = ENV['MJ_APIKEY_PRIVATE']
181
181
  config.api_version = "v3.1"
182
182
  end
183
183
  ```
@@ -189,7 +189,7 @@ The default base domain name for the Mailjet API is `https://api.mailjet.com`. Y
189
189
  ```ruby
190
190
  Mailjet.configure do |config|
191
191
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
192
- config.secret_key = ENV['MJ_APIKEY_PRIVATE']
192
+ config.secret_key = ENV['MJ_APIKEY_PRIVATE']
193
193
  config.api_version = "v3.1"
194
194
  config.end_point = "https://api.us.mailjet.com"
195
195
  end
@@ -221,7 +221,7 @@ Use the `create` method of the Mailjet CLient (i.e. `variable = Mailjet::$resour
221
221
  require 'mailjet'
222
222
  Mailjet.configure do |config|
223
223
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
224
- config.secret_key = ENV['MJ_APIKEY_PRIVATE']
224
+ config.secret_key = ENV['MJ_APIKEY_PRIVATE']
225
225
  end
226
226
  variable = Mailjet::Contact.create(email: "Mister@mailjet.com"
227
227
  )
@@ -239,7 +239,7 @@ Use `id` to specify the ID you want to apply a POST request to (used in case of
239
239
  require 'mailjet'
240
240
  Mailjet.configure do |config|
241
241
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
242
- config.secret_key = ENV['MJ_APIKEY_PRIVATE']
242
+ config.secret_key = ENV['MJ_APIKEY_PRIVATE']
243
243
  end
244
244
  variable = Mailjet::Contact_managecontactslists.create(id: $ID, contacts_lists: [{
245
245
  'ListID'=> '$ListID_1',
@@ -285,7 +285,7 @@ Use the `.find` method to retrieve a specific object. Specify the ID of the obje
285
285
  require 'mailjet'
286
286
  Mailjet.configure do |config|
287
287
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
288
- config.secret_key = ENV['MJ_APIKEY_PRIVATE']
288
+ config.secret_key = ENV['MJ_APIKEY_PRIVATE']
289
289
  end
290
290
  variable = Mailjet::Contact.find($CONTACT_EMAIL)
291
291
  p variable.attributes['Data']
@@ -483,6 +483,17 @@ UserMailer.welcome_email.deliver_now!
483
483
 
484
484
  For more information on `ActionMailer::MessageDelivery`, see the documentation [HERE](http://edgeapi.rubyonrails.org/classes/ActionMailer/MessageDelivery.html)
485
485
 
486
+ #### Manage contacts via CSV Upload
487
+ Create the CSV content in a format compatible with the Mailjet API, see the documentation [HERE](https://dev.mailjet.com/email/guides/contact-management/#manage-contacts-via-csv-upload)
488
+ ```ruby
489
+ Mailjet::ContactslistCsv.send_data(ID_CONTACTLIST, File.open('some_csvdata.csv', 'r'))
490
+ ```
491
+
492
+ #### [Delete the Contact](https://dev.mailjet.com/email/guides/contact-management/#gdpr-delete-contacts)
493
+ ```ruby
494
+ Mailjet::ContactPii.delete(contact_ID)
495
+ ```
496
+
486
497
  ## Track email delivery
487
498
 
488
499
  You can setup your Rack application in order to receive feedback on emails you sent (clicks, etc.)
@@ -1,41 +1,32 @@
1
- require 'rest_client'
2
- require 'mailjet/gem_extensions/rest_client'
3
- require 'json'
1
+ require 'faraday'
2
+ require 'yajl'
4
3
 
5
4
  module Mailjet
6
5
  class Connection
7
6
 
8
- attr_accessor :adapter, :public_operations, :read_only, :perform_api_call, :read_timeout, :open_timeout
7
+ attr_accessor :adapter, :public_operations, :read_only, :perform_api_call, :api_key, :secret_key, :options
9
8
  alias :read_only? :read_only
10
9
 
11
10
  def [](suburl, &new_block)
12
- broken_url = url.split("/")
11
+ broken_url = uri.path.split("/")
13
12
  if broken_url.include?("contactslist") && broken_url.include?("managemanycontacts") && broken_url.last.to_i > 0
14
- self.class.new(url, options[:user], options[:password], options)
13
+ self.class.new(uri, api_key, secret_key, options)
15
14
  else
16
- self.class.new(concat_urls(url, suburl), options[:user], options[:password], options)
15
+ self.class.new(concat_urls(suburl), api_key, secret_key, options)
17
16
  end
18
17
  end
19
18
 
20
19
  def initialize(end_point, api_key, secret_key, options = {})
21
- # #charles proxy
22
- # RestClient.proxy = "http://127.0.0.1:8888"
23
- # #
24
- # #Output for debugging
25
- # RestClient.log =
26
- # Object.new.tap do |proxy|
27
- # def proxy.<<(message)
28
- # Rails.logger.info message
29
- # end
30
- # end
31
- # #
32
- adapter_class = options[:adapter_class] || RestClient::Resource
20
+ self.options = options
21
+ self.api_key = api_key
22
+ self.secret_key = secret_key
33
23
  self.public_operations = options[:public_operations] || []
34
24
  self.read_only = options[:read_only]
35
- self.read_timeout = options[:read_timeout]
36
- self.open_timeout = options[:open_timeout]
37
- # self.adapter = adapter_class.new(end_point, options.merge(user: api_key, password: secret_key, :verify_ssl => false, 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))
25
+ self.adapter = Faraday.new(end_point, ssl: { verify: false }) do |conn|
26
+ conn.response :raise_error, include_request: true
27
+ conn.request :authorization, :basic, api_key, secret_key
28
+ conn.headers['Content-Type'] = 'application/json'
29
+ end
39
30
  self.perform_api_call = options.key?(:perform_api_call) ? options[:perform_api_call] : true
40
31
  end
41
32
 
@@ -55,34 +46,31 @@ module Mailjet
55
46
  handle_api_call(:delete, additional_headers, &block)
56
47
  end
57
48
 
58
- def options
59
- self.adapter.options
60
- end
61
-
62
- def concat_urls(*options)
63
- self.adapter.concat_urls(*options)
49
+ def concat_urls(suburl)
50
+ self.adapter.build_url(suburl.to_s)
64
51
  end
65
52
 
66
- def url
67
- self.adapter.url
53
+ def uri
54
+ self.adapter.build_url
68
55
  end
69
56
 
70
57
  private
71
58
 
72
59
  def handle_api_call(method, additional_headers = {}, payload = {}, &block)
73
- formatted_payload = (additional_headers[:content_type] == :json) ? payload.to_json : payload
60
+ formatted_payload = (additional_headers["Content-Type"] == 'application/json') ? Yajl::Encoder.encode(payload) : payload
74
61
  raise Mailjet::MethodNotAllowed unless method_allowed(method)
75
62
 
76
63
  if self.perform_api_call
77
64
  if [:get, :delete].include?(method)
78
- @adapter.send(method, additional_headers, &block)
65
+ @adapter.send(method, nil, additional_headers[:params], &block)
79
66
  else
80
- @adapter.send(method, formatted_payload, additional_headers, &block)
67
+ @adapter.send(method, nil, formatted_payload, additional_headers, &block)
81
68
  end
82
69
  else
83
- return {'Count' => 0, 'Data' => [mock_api_call: true], 'Total' => 0}.to_json
70
+ return Yajl::Encoder.encode({'Count' => 0, 'Data' => [mock_api_call: true], 'Total' => 0})
84
71
  end
85
- rescue RestClient::Exception => e
72
+
73
+ rescue Faraday::Error => e
86
74
  handle_exception(e, additional_headers, formatted_payload)
87
75
  end
88
76
 
@@ -92,28 +80,44 @@ module Mailjet
92
80
  end
93
81
 
94
82
  def handle_exception(e, additional_headers, payload = {})
83
+ return e.response_body if e.response_headers[:content_type].include?("text/plain")
84
+
95
85
  params = additional_headers[:params] || {}
96
- formatted_payload = (additional_headers[:content_type] == :json) ? JSON.parse(payload) : payload
97
- params = params.merge(formatted_payload)
86
+ formatted_payload = (additional_headers[:content_type] == :json) ? Yajl::Parser.parse(payload) : payload
87
+ params = params.merge!(formatted_payload) if formatted_payload.is_a?(Hash)
98
88
 
99
- http_body = if e.http_headers[:content_type].include?("application/json")
100
- e.http_body
89
+ response_body = if e.response_headers[:content_type].include?("application/json")
90
+ e.response_body
101
91
  else
102
92
  "{}"
103
93
  end
104
94
 
105
- if sent_invalid_email?(e.http_body, @adapter.url)
106
- return e.http_body
95
+ if sent_invalid_email?(e.response_body, @adapter.build_url)
96
+ return e.response_body
107
97
  else
108
- raise Mailjet::ApiError.new(e.http_code, http_body, @adapter, @adapter.url, params)
98
+ raise communication_error(e)
109
99
  end
110
100
  end
111
101
 
112
- def sent_invalid_email?(error_http_body, url)
113
- return false unless url.include?('v3.1/send')
102
+ def communication_error(e)
103
+ if e.respond_to?(:response) && e.response
104
+ return case e.response_status
105
+ when Unauthorized::CODE
106
+ Unauthorized.new(e.message, e)
107
+ when BadRequest::CODE
108
+ BadRequest.new(e.message, e)
109
+ else
110
+ CommunicationError.new(e.message, e)
111
+ end
112
+ end
113
+ CommunicationError.new(e.message)
114
+ end
115
+
116
+ def sent_invalid_email?(error_http_body, uri)
117
+ return false unless uri.path.include?('v3.1/send')
114
118
  return unless error_http_body
115
119
 
116
- parsed_body = JSON.parse(error_http_body)
120
+ parsed_body = Yajl::Parser.parse(error_http_body)
117
121
  error_message = parsed_body.dig('Messages')&.first&.dig('Errors')&.first&.dig('ErrorMessage') || []
118
122
  error_message.include?('is an invalid email address.')
119
123
  rescue
@@ -123,6 +127,5 @@ module Mailjet
123
127
  end
124
128
 
125
129
  class MethodNotAllowed < StandardError
126
-
127
130
  end
128
131
  end
@@ -0,0 +1,94 @@
1
+ require 'yajl'
2
+ require 'json'
3
+
4
+ module Mailjet
5
+ class Error < StandardError
6
+ attr_reader :object
7
+
8
+ def initialize(message = nil, object = nil)
9
+ super(message)
10
+ @object = object
11
+ end
12
+ end
13
+
14
+ class ApiError < StandardError
15
+ attr_reader :code, :reason
16
+
17
+ # @param code [Integer] HTTP response status code
18
+ # @param body [String] JSON response body
19
+ # @param request [Object] any request object
20
+ # @param url [String] request URL
21
+ # @param params [Hash] request headers and parameters
22
+ def initialize(code, body, request, url, params)
23
+ @code = code
24
+ @reason = begin
25
+ resdec = JSON.parse(body)
26
+ resdec['ErrorMessage']
27
+ rescue JSON::ParserError
28
+ body
29
+ end
30
+
31
+ if request.respond_to?(:options)
32
+ request.options[:user] = '***'
33
+ request.options[:password] = '***'
34
+ end
35
+
36
+ message = "error #{code} while sending #{request.inspect} to #{url} with #{params.inspect}"
37
+ error_details = body.inspect
38
+ hint = "Please see https://dev.mailjet.com/email/reference/overview/errors/ for more informations on error numbers."
39
+
40
+ super("#{message}\n\n#{error_details}\n\n#{hint}\n\n")
41
+ end
42
+ end
43
+
44
+ class CommunicationError < Error
45
+ attr_reader :code
46
+
47
+ NOCODE = 000
48
+
49
+ def initialize(message = nil, response = nil)
50
+ @response = response
51
+ @code = if response.nil?
52
+ NOCODE
53
+ else
54
+ response.response_status
55
+ end
56
+
57
+ api_message = begin
58
+ Yajl::Parser.parse(response.response_body)['ErrorMessage']
59
+ rescue Yajl::ParseError
60
+ response.response_body
61
+ rescue NoMethodError
62
+ "Unknown API error"
63
+ rescue
64
+ 'Unknown API error'
65
+ end
66
+
67
+ message ||= ''
68
+ api_message ||= ''
69
+ message = message + ': ' + api_message
70
+
71
+ super(message, response)
72
+ rescue NoMethodError, JSON::ParserError
73
+ @code = NOCODE
74
+ super(message, response)
75
+ end
76
+ end
77
+
78
+ class Unauthorized < CommunicationError
79
+ CODE = 401
80
+
81
+ def initialize(error_message, response)
82
+ error_message = error_message + ' - Invalid Domain or API key'
83
+ super(error_message, response)
84
+ end
85
+ end
86
+
87
+ class BadRequest < CommunicationError
88
+ CODE = 400
89
+
90
+ def initialize(error_message, response)
91
+ super(error_message, response)
92
+ end
93
+ end
94
+ end
@@ -1,7 +1,8 @@
1
1
  require 'action_mailer'
2
2
  require 'mail'
3
3
  require 'base64'
4
- require 'json'
4
+ require 'yajl'
5
+
5
6
 
6
7
  # Mailjet::Mailer enables to send a Mail::Message via Mailjet SMTP relay servers
7
8
  # User is the API key, and password the API secret
@@ -15,7 +16,7 @@ class Mailjet::Mailer < ::Mail::SMTP
15
16
  user_name: options.delete(:api_key) || Mailjet.config.api_key,
16
17
  password: options.delete(:secret_key) || Mailjet.config.secret_key,
17
18
  enable_starttls_auto: true
18
- }.merge(options))
19
+ }.merge!(options))
19
20
  end
20
21
  end
21
22
 
@@ -202,9 +203,7 @@ class Mailjet::APIMailer
202
203
 
203
204
  payload = {
204
205
  :To=> to,
205
- }.merge(content)
206
- .merge(base_from)
207
- .merge(@delivery_method_options_v3_1)
206
+ }.merge!(content, base_from, @delivery_method_options_v3_1)
208
207
 
209
208
  payload[:Subject] = mail.subject if !mail.subject.blank?
210
209
  payload[:Sender] = mail[:sender] if !mail[:sender].blank?
@@ -294,9 +293,7 @@ class Mailjet::APIMailer
294
293
  payload[:bcc] = mail[:bcc].formatted.join(', ') if mail[:bcc]
295
294
 
296
295
  # Send the final payload to Mailjet Send API
297
- payload.merge(content)
298
- .merge(base_from)
299
- .merge(@delivery_method_options_v3_0)
296
+ payload.merge!(content, base_from, @delivery_method_options_v3_0)
300
297
  end
301
298
  end
302
299
 
@@ -1,5 +1,5 @@
1
1
  require 'rack/request'
2
- require 'json'
2
+ require 'yajl'
3
3
 
4
4
  module Mailjet
5
5
  module Rack
@@ -12,7 +12,7 @@ module Mailjet
12
12
 
13
13
  def call(env)
14
14
  if env['PATH_INFO'] == @path && (content = env['rack.input'].read)
15
- @block.call(JSON.parse(content))
15
+ @block.call(Yajl::Parser.parse(content))
16
16
  [200, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []]
17
17
  else
18
18
  @app.call(env)
@@ -1,11 +1,9 @@
1
1
  require 'mailjet/connection'
2
+ require 'yajl'
3
+ require 'active_support'
2
4
  require 'active_support/core_ext/string'
3
- require 'active_support/core_ext/module/delegation'
4
- #require 'mail'
5
- require 'active_support/hash_with_indifferent_access'
6
- require 'active_support/core_ext/hash'
7
- require 'active_support/json/decoding'
8
- require 'json'
5
+ require 'active_support/core_ext/hash/indifferent_access'
6
+
9
7
 
10
8
 
11
9
  # This option automatically transforms the date output by the API into something a bit more readable.
@@ -16,11 +14,11 @@ require 'json'
16
14
 
17
15
  module Mailjet
18
16
  module Resource
19
-
20
17
  # define here available options for filtering
21
- OPTIONS = [:version, :url, :perform_api_call, :api_key, :secret_key, :read_timeout, :open_timeout]
18
+ OPTIONS = [:version, :url, :perform_api_call, :api_key, :secret_key]
22
19
 
23
20
  NON_JSON_URLS = ['v3/send/message'] # urls that don't accept JSON input
21
+ DATA_URLS = ['plain', 'csv'] # url for send binary data , 'CSVError/text:csv'
24
22
 
25
23
  def self.included(base)
26
24
  base.extend ClassMethods
@@ -41,18 +39,20 @@ module Mailjet
41
39
  options[:secret_key] || Mailjet.config.secret_key,
42
40
  public_operations: public_operations,
43
41
  read_only: read_only,
44
- perform_api_call: options[:perform_api_call],
45
- open_timeout: options[:open_timeout],
46
- read_timeout: options[:read_timeout])
42
+ perform_api_call: options[:perform_api_call])
47
43
  end
48
44
 
49
45
  def self.default_headers
50
46
  if NON_JSON_URLS.include?(self.resource_path) # don't use JSON if Send API
51
- default_headers = { accept: :json, accept_encoding: :deflate }
47
+ default_headers = { 'Accept' =>'application/json', 'Accept-Encoding' => 'deflate' }
48
+ elsif DATA_URLS.any? do |data_type|
49
+ default_headers = { 'Content-Type' => "text/#{data_type}" } if self.resource_path.include?(data_type)
50
+ end
52
51
  else
53
- default_headers = { accept: :json, accept_encoding: :deflate, content_type: :json } #use JSON if *not* Send API
52
+ # use JSON if *not* Send API
53
+ default_headers = {'Content-Type' =>'application/json', 'Accept' =>'application/json', 'Accept-Encoding' => 'deflate'}
54
54
  end
55
- return default_headers.merge(user_agent: "mailjet-api-v3-ruby/#{Gem.loaded_specs["mailjet"].version}")
55
+ return default_headers.merge!('User-Agent' => "mailjet-api-v3-ruby/#{Gem.loaded_specs["mailjet"].version}")
56
56
  end
57
57
  end
58
58
  end
@@ -60,21 +60,27 @@ module Mailjet
60
60
  module ClassMethods
61
61
  def first(params = {}, options = {})
62
62
  all(params.merge!(limit: 1), options).first
63
+ rescue Mailjet::ApiError => error
64
+ raise error
63
65
  end
64
66
 
65
67
  def all(params = {}, options = {})
66
68
  opts = define_options(options)
67
69
  params = format_params(params)
68
- response = connection(opts).get(default_headers.merge(params: params))
69
- attribute_array = parse_api_json(response)
70
+ response = connection(opts).get(default_headers.merge!(params: params))
71
+ attribute_array = parse_api_json(response.body)
70
72
  attribute_array.map{ |attributes| instanciate_from_api(attributes) }
73
+ rescue Mailjet::ApiError => error
74
+ raise error
71
75
  end
72
76
 
73
77
  def count(options = {})
74
78
  opts = define_options(options)
75
- response_json = connection(opts).get(default_headers.merge(params: {limit: 1, countrecords: 1}))
76
- response_hash = JSON.parse(response_json)
79
+ response_json = connection(opts).get(default_headers.merge!(params: {limit: 1, countrecords: 1}))
80
+ response_hash = Yajl::Parser.parse(response_json.body)
77
81
  response_hash['Total']
82
+ rescue Mailjet::ApiError => error
83
+ raise error
78
84
  end
79
85
 
80
86
  def find(id, job_id = nil, options = {})
@@ -87,11 +93,11 @@ module Mailjet
87
93
  # if action method, ammend url to appropriate id
88
94
  opts = define_options(options)
89
95
  self.resource_path = create_action_resource_path(normalized_id, job_id) if self.action
90
- #
91
- attributes = parse_api_json(connection(opts)[normalized_id].get(default_headers)).first
96
+
97
+ attributes = parse_api_json(connection(opts)[normalized_id].get(default_headers).body).first
92
98
  instanciate_from_api(attributes)
93
99
 
94
- rescue Mailjet::ApiError => e
100
+ rescue Mailjet::CommunicationError => e
95
101
  if e.code == 404
96
102
  nil
97
103
  else
@@ -99,6 +105,14 @@ module Mailjet
99
105
  end
100
106
  end
101
107
 
108
+
109
+ def find_by_id(id, options = {})
110
+ # if action method, ammend url to appropriate id
111
+ opts = define_options(options)
112
+ self.resource_path = create_action_resource_path(id) if self.action
113
+ connection(opts).get(default_headers)
114
+ end
115
+
102
116
  def create(attributes = {}, options = {})
103
117
  # if action method, ammend url to appropriate id
104
118
  opts = define_options(options)
@@ -118,7 +132,6 @@ module Mailjet
118
132
  resource.save!(opts)
119
133
  resource.attributes[:persisted] = true
120
134
  end
121
-
122
135
  end
123
136
 
124
137
  def delete(id, options = {})
@@ -126,14 +139,25 @@ module Mailjet
126
139
  opts = define_options(options)
127
140
  self.resource_path = create_action_resource_path(id) if self.action
128
141
  connection(opts)[id].delete(default_headers)
142
+ rescue Mailjet::ApiError => error
143
+ raise error
144
+ end
145
+
146
+ def send_data(id, binary_data = nil, options = {})
147
+ opts = define_options(options)
148
+ self.resource_path = create_action_resource_path(id) if self.action
149
+ response = connection(opts).post(binary_data, default_headers.merge({'Content-Length' => "#{binary_data.size}", 'Transfer-Encoding' => 'chunked'}))
150
+
151
+ response_hash = response.respond_to?(:body) ? Yajl::Parser.parse(response.body) : Yajl::Parser.parse(response)
152
+ response_hash['ID'] ? response_hash['ID'] : response_hash
129
153
  end
130
154
 
131
155
  def instanciate_from_api(attributes = {})
132
- self.new(attributes.merge(persisted: true))
156
+ self.new(attributes.merge!(persisted: true))
133
157
  end
134
158
 
135
159
  def parse_api_json(response_json)
136
- response_hash = JSON.parse(response_json)
160
+ response_hash = Yajl::Parser.parse(response_json)
137
161
 
138
162
  #Take the response from the API and put it through a method -- taken from the ActiveSupport library -- which converts
139
163
  #the date-time from "2014-05-19T15:31:09Z" to "Mon, 19 May 2014 15:31:09 +0000" format.
@@ -169,9 +193,9 @@ module Mailjet
169
193
  case data
170
194
  when nil
171
195
  nil
172
- when /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
196
+ when /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
173
197
  begin
174
- DateTime.parse(data)
198
+ DateTime.iso8601(data)
175
199
  rescue ArgumentError
176
200
  data
177
201
  end
@@ -260,9 +284,9 @@ module Mailjet
260
284
  if opts[:perform_api_call] && !persisted?
261
285
  # get attributes only for entity creation
262
286
  self.attributes = if self.resource_path == 'send'
263
- JSON.parse(response)
287
+ Yajl::Parser.parse(response.body)
264
288
  else
265
- parse_api_json(response).first
289
+ parse_api_json(response.body).first
266
290
  end
267
291
  end
268
292
 
@@ -11,12 +11,12 @@ module Mailjet
11
11
  opts = define_options(options)
12
12
  self.resource_path = create_action_resource_path(id, job_id) if self.action
13
13
 
14
- raw_data = parse_api_json(connection(opts)[id].get(default_headers))
14
+ raw_data = parse_api_json(connection(opts)[id].get(default_headers).body)
15
15
 
16
16
  raw_data.map do |entity|
17
17
  instanciate_from_api(entity)
18
18
  end
19
- rescue Mailjet::ApiError => e
19
+ rescue Mailjet::CommunicationError => e
20
20
  if e.code == 404
21
21
  nil
22
22
  else
@@ -5,20 +5,15 @@ module Mailjet
5
5
  self.public_operations = [:get, :put, :post]
6
6
  self.filters = [:campaign, :contacts_list, :is_unsubscribed, :last_activity_at, :recipient, :status]
7
7
  self.resourceprop = [
8
- :created_at,
9
8
  :delivered_count,
10
9
  :email,
11
10
  :id,
12
11
  :is_opt_in_pending,
13
12
  :is_spam_complaining,
14
- :last_activity_at,
15
- :last_update_at,
16
13
  :name,
17
- :unsubscribed_at,
18
14
  :unsubscribed_by,
19
15
  :is_excluded_from_campaigns
20
16
  ]
21
17
  self.read_only_attributes = [:created_at, :last_activity_at, :last_update_at, :unsubscribed_at]
22
-
23
18
  end
24
19
  end
@@ -11,12 +11,12 @@ module Mailjet
11
11
  opts = define_options(options)
12
12
  self.resource_path = create_action_resource_path(id, job_id) if self.action
13
13
 
14
- raw_data = parse_api_json(connection(opts).get(default_headers))
14
+ raw_data = parse_api_json(connection(opts).get(default_headers).body)
15
15
 
16
16
  raw_data.map do |entity|
17
17
  instanciate_from_api(entity)
18
18
  end
19
- rescue Mailjet::ApiError => e
19
+ rescue Mailjet::CommunicationError => e
20
20
  if e.code == 404
21
21
  nil
22
22
  else
@@ -0,0 +1,8 @@
1
+ module Mailjet
2
+ class ContactPii
3
+ include Mailjet::Resource
4
+ self.version = 'v4'
5
+ self.resource_path = 'contacts'
6
+ self.public_operations = [:delete]
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Mailjet
2
+ class ContactslistCsv
3
+ include Mailjet::Resource
4
+ self.action = "DATA/contactslist"
5
+ self.resource_path = "#{self.action}/id/CSVData/text:plain"
6
+ self.public_operations = [:post]
7
+ end
8
+ end
@@ -5,6 +5,5 @@ module Mailjet
5
5
  self.public_operations = [:get, :put, :post]
6
6
  self.filters = []
7
7
  self.resourceprop = [:alive_at, :contacts_list, :count, :current, :data_id, :errcount, :err_treshold, :id, :import_options, :job_end, :job_start, :method, :request_at, :status]
8
-
9
8
  end
10
9
  end
@@ -4,7 +4,8 @@ module Mailjet
4
4
  self.resource_path = 'REST/listrecipient'
5
5
  self.public_operations = [:get, :put, :post, :delete]
6
6
  self.filters = [:active, :blocked, :contact, :contact_email, :contacts_list, :last_activity_at, :list_name, :opened, :status, :unsub]
7
- self.resourceprop = [:contact, :id, :is_active, :is_unsubscribed, :list, :unsubscribed_at, :contact_id, :list_id, 'ContactID', 'ListID', 'ContactALT', 'ListALT']
7
+ self.resourceprop = [:contact, :id, :is_active, :is_unsubscribed, :list, :contact_id, :list_id, 'ContactID', 'ListID', 'ContactALT', 'ListALT']
8
8
 
9
+ self.read_only_attributes = [:subscribed_at, :unsubscribed_at]
9
10
  end
10
11
  end
@@ -12,12 +12,12 @@ module Mailjet
12
12
  opts = define_options(options)
13
13
  self.resource_path = create_action_resource_path(id, job_id) if self.action
14
14
 
15
- raw_data = parse_api_json(connection(opts)[id].get(default_headers))
15
+ raw_data = parse_api_json(connection(opts)[id].get(default_headers).body)
16
16
 
17
17
  raw_data.map do |entity|
18
18
  instanciate_from_api(entity)
19
19
  end
20
- rescue Mailjet::ApiError => e
20
+ rescue Mailjet::CommunicationError => e
21
21
  if e.code == 404
22
22
  nil
23
23
  else
@@ -12,12 +12,12 @@ module Mailjet
12
12
  opts = define_options(options)
13
13
  self.resource_path = create_action_resource_path(id, job_id) if self.action
14
14
 
15
- raw_data = parse_api_json(connection(opts)[id].get(default_headers))
15
+ raw_data = parse_api_json(connection(opts)[id].get(default_headers).body)
16
16
 
17
17
  raw_data.map do |entity|
18
18
  instanciate_from_api(entity)
19
19
  end
20
- rescue Mailjet::ApiError => e
20
+ rescue Mailjet::CommunicationError => e
21
21
  if e.code == 404
22
22
  nil
23
23
  else
@@ -12,12 +12,12 @@ module Mailjet
12
12
  opts = define_options(options)
13
13
  self.resource_path = create_action_resource_path(id, job_id) if self.action
14
14
 
15
- raw_data = parse_api_json(connection(opts)[id].get(default_headers))
15
+ raw_data = parse_api_json(connection(opts)[id].get(default_headers).body)
16
16
 
17
17
  raw_data.map do |entity|
18
18
  instanciate_from_api(entity)
19
19
  end
20
- rescue Mailjet::ApiError => e
20
+ rescue Mailjet::CommunicationError => e
21
21
  if e.code == 404
22
22
  nil
23
23
  else
@@ -0,0 +1,8 @@
1
+ module Mailjet
2
+ class RetrieveErrosCsv
3
+ include Mailjet::Resource
4
+ self.action = "DATA/BatchJob"
5
+ self.resource_path = "#{self.action}/id/CSVError/text:csv"
6
+ self.public_operations = [:get]
7
+ end
8
+ end
@@ -12,10 +12,10 @@ module Mailjet
12
12
 
13
13
  opts = define_options(options)
14
14
  response = connection(opts).get(default_headers)
15
- attributes = parse_api_json(response).first
15
+ attributes = parse_api_json(response.body).first
16
16
 
17
17
  instanciate_from_api(attributes)
18
- rescue Mailjet::ApiError => e
18
+ rescue Mailjet::CommunicationError => e
19
19
  if e.code == 404
20
20
  nil
21
21
  else
@@ -1,3 +1,3 @@
1
1
  module Mailjet
2
- VERSION = "1.7.3"
2
+ VERSION = "1.8.0"
3
3
  end
data/lib/mailjet.rb CHANGED
@@ -1,13 +1,11 @@
1
1
  require 'json/ext'
2
- require 'ostruct'
3
- require 'mailjet/core_extensions/ostruct'
2
+ require 'yajl'
4
3
  require 'mailjet/configuration'
5
- require 'mailjet/api_error'
6
4
 
7
5
  require 'mailjet/resource'
8
6
  require 'mailjet/message_delivery'
9
7
 
10
- Dir[File.expand_path("../mailjet/resources/*.rb", __FILE__)].each do |file|
8
+ Dir[File.expand_path("../mailjet/{resources,exception}/*.rb", __FILE__)].each do |file|
11
9
  require file
12
10
  end
13
11
 
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailjet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.3
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Nappy
8
8
  - Jean-Baptiste Escoyez
9
9
  - Aurélien AMILIN
10
10
  - Benoit Bénézech
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2023-02-15 00:00:00.000000000 Z
14
+ date: 2024-08-30 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 3.1.0
22
+ version: 5.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 3.1.0
29
+ version: 5.0.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rack
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -42,33 +42,47 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.4.0
44
44
  - !ruby/object:Gem::Dependency
45
- name: rest-client
45
+ name: faraday
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '2.1'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '2.1'
58
+ - !ruby/object:Gem::Dependency
59
+ name: yajl-ruby
46
60
  requirement: !ruby/object:Gem::Requirement
47
61
  requirements:
48
62
  - - ">="
49
63
  - !ruby/object:Gem::Version
50
- version: 2.0.0
64
+ version: '0'
51
65
  type: :runtime
52
66
  prerelease: false
53
67
  version_requirements: !ruby/object:Gem::Requirement
54
68
  requirements:
55
69
  - - ">="
56
70
  - !ruby/object:Gem::Version
57
- version: 2.0.0
71
+ version: '0'
58
72
  - !ruby/object:Gem::Dependency
59
73
  name: actionmailer
60
74
  requirement: !ruby/object:Gem::Requirement
61
75
  requirements:
62
76
  - - ">="
63
77
  - !ruby/object:Gem::Version
64
- version: 3.0.9
78
+ version: 5.0.0
65
79
  type: :development
66
80
  prerelease: false
67
81
  version_requirements: !ruby/object:Gem::Requirement
68
82
  requirements:
69
83
  - - ">="
70
84
  - !ruby/object:Gem::Version
71
- version: 3.0.9
85
+ version: 5.0.0
72
86
  - !ruby/object:Gem::Dependency
73
87
  name: rake
74
88
  requirement: !ruby/object:Gem::Requirement
@@ -168,12 +182,10 @@ files:
168
182
  - lib/generators/mailjet/initializer_generator.rb
169
183
  - lib/generators/mailjet/templates/mailjet.rb.erb
170
184
  - lib/mailjet.rb
171
- - lib/mailjet/api_error.rb
172
185
  - lib/mailjet/collection_proxy.rb
173
186
  - lib/mailjet/configuration.rb
174
187
  - lib/mailjet/connection.rb
175
- - lib/mailjet/core_extensions/ostruct.rb
176
- - lib/mailjet/gem_extensions/rest_client.rb
188
+ - lib/mailjet/exception/errors.rb
177
189
  - lib/mailjet/mailer.rb
178
190
  - lib/mailjet/message_delivery.rb
179
191
  - lib/mailjet/rack/endpoint.rb
@@ -203,11 +215,13 @@ files:
203
215
  - lib/mailjet/resources/contact_getcontactslists.rb
204
216
  - lib/mailjet/resources/contact_managecontactslists.rb
205
217
  - lib/mailjet/resources/contact_managemanycontacts.rb
218
+ - lib/mailjet/resources/contact_pii.rb
206
219
  - lib/mailjet/resources/contactdata.rb
207
220
  - lib/mailjet/resources/contactfilter.rb
208
221
  - lib/mailjet/resources/contacthistorydata.rb
209
222
  - lib/mailjet/resources/contactmetadata.rb
210
223
  - lib/mailjet/resources/contactslist.rb
224
+ - lib/mailjet/resources/contactslist_csv.rb
211
225
  - lib/mailjet/resources/contactslist_managecontact.rb
212
226
  - lib/mailjet/resources/contactslist_managemanycontacts.rb
213
227
  - lib/mailjet/resources/contactslistsignup.rb
@@ -248,6 +262,7 @@ files:
248
262
  - lib/mailjet/resources/openstatistics.rb
249
263
  - lib/mailjet/resources/parseroute.rb
250
264
  - lib/mailjet/resources/preferences.rb
265
+ - lib/mailjet/resources/retrieve_errors_csv.rb
251
266
  - lib/mailjet/resources/send.rb
252
267
  - lib/mailjet/resources/sender.rb
253
268
  - lib/mailjet/resources/sender_validate.rb
@@ -291,11 +306,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
291
306
  - !ruby/object:Gem::Version
292
307
  version: '0'
293
308
  requirements: []
294
- rubygems_version: 3.0.3
295
- signing_key:
309
+ rubygems_version: 3.1.6
310
+ signing_key:
296
311
  specification_version: 4
297
312
  summary: Mailjet a powerful all-in-one email service provider clients can use to get
298
313
  maximum insight and deliverability results from both their marketing and transactional
299
314
  emails. Our analytics tools and intelligent APIs give senders the best understanding
300
315
  of how to maximize benefits for each individual contact, with each email sent.
301
316
  test_files: []
317
+ ...
@@ -1,28 +0,0 @@
1
- require "json"
2
-
3
- module Mailjet
4
- class ApiError < StandardError
5
- attr_reader :code, :reason
6
-
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
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."
24
-
25
- super("#{message}\n\n#{error_details}\n\n#{hint}\n\n")
26
- end
27
- end
28
- end
@@ -1,9 +0,0 @@
1
- class OpenStruct
2
-
3
- # when asked for id, ruby 1.8.7's implementation of OpenStruct returns object's inner id instead of table's value if present. Evilishish infamous Monkey-Patch.
4
- if RUBY_VERSION =~ /1\.8\./
5
- def id
6
- send(:eval, "@table[:id]")
7
- end
8
- end
9
- end
@@ -1,19 +0,0 @@
1
- module RestClient
2
- module Payload
3
- class Base
4
- def flatten_params_array value, calculated_key
5
- result = []
6
- value.each do |elem|
7
- if elem.is_a? Hash
8
- result += flatten_params(elem, calculated_key)
9
- elsif elem.is_a? Array
10
- result += flatten_params_array(elem, calculated_key)
11
- else
12
- result << ["#{calculated_key}", elem]
13
- end
14
- end
15
- result
16
- end
17
- end
18
- end
19
- end