mailgun-ruby 1.2.15 → 1.3.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 +4 -4
- data/CHANGELOG.md +7 -2
- data/Gemfile +1 -0
- data/README.md +2 -1
- data/docs/Metrics.md +108 -0
- data/docs/Webhooks.md +4 -2
- data/lib/mailgun/client.rb +38 -30
- data/lib/mailgun/exceptions/exceptions.rb +7 -7
- data/lib/mailgun/metrics/metrics.rb +61 -0
- data/lib/mailgun/response.rb +11 -10
- data/lib/mailgun/version.rb +1 -1
- data/lib/mailgun.rb +2 -1
- data/mailgun.gemspec +2 -1
- data/spec/integration/mailgun_spec.rb +5 -5
- data/spec/integration/metrics_spec.rb +218 -0
- data/spec/unit/connection/test_client.rb +1 -1
- data/spec/unit/exceptions/exceptions_spec.rb +3 -3
- data/vcr_cassettes/metrics.yml +116 -0
- metadata +28 -9
- /data/docs/{railgun/Templates.md → Templates.md} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f18ece3e95078672f58a188ff310d572559ac05aa442080a8a76ec357fa563b9
|
4
|
+
data.tar.gz: 30a957419c41fa13342db90ca3ee386d1c312da20daa41c06229801e6c07ec95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0309b13c1dda7a95224776c9bb1e0a04a3bfef7945f9a92c24ea566742f183ff544294d9a8dd6af006856fa7c97d2175cf01fe84c72e85712c1da34ec08bc723'
|
7
|
+
data.tar.gz: 90db979ec789797886fa5210ea3b2ec9bac048dbb440facd9f356324093cc98ce657ecc589f719efe4b4c2b51251153071b936db0cd34877370debe02912b66b
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
|
+
## [1.2.16] - 2024-11-29
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Metrics API support (https://github.com/mailgun/mailgun-ruby/pull/326)
|
12
|
+
|
7
13
|
## [1.2.15] - 2024-02-13
|
8
14
|
|
9
15
|
### Fixed
|
@@ -19,7 +25,6 @@ All notable changes to this project will be documented in this file.
|
|
19
25
|
- Additional Domain Endpoints (https://github.com/mailgun/mailgun-ruby/pull/314)
|
20
26
|
- Webhooks Update Method (https://github.com/mailgun/mailgun-ruby/pull/305)
|
21
27
|
- Add support for AMP HTML (https://github.com/mailgun/mailgun-ruby/pull/304)
|
22
|
-
- Add support for AMP HTML (https://github.com/mailgun/mailgun-ruby/pull/304)
|
23
28
|
|
24
29
|
### Fixed
|
25
30
|
|
@@ -40,4 +45,4 @@ All notable changes to this project will be documented in this file.
|
|
40
45
|
### Fixed
|
41
46
|
|
42
47
|
- transform_for_mailgun block iteration issue (https://github.com/mailgun/mailgun-ruby/pull/298).
|
43
|
-
- Typos in several files (https://github.com/mailgun/mailgun-ruby/pull/297).
|
48
|
+
- Typos in several files (https://github.com/mailgun/mailgun-ruby/pull/297).
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -19,7 +19,7 @@ gem install mailgun-ruby
|
|
19
19
|
Gemfile:
|
20
20
|
|
21
21
|
```ruby
|
22
|
-
gem 'mailgun-ruby', '~>1.2.
|
22
|
+
gem 'mailgun-ruby', '~>1.2.16'
|
23
23
|
```
|
24
24
|
|
25
25
|
Usage
|
@@ -193,6 +193,7 @@ This SDK includes the following components:
|
|
193
193
|
- [Suppressions](docs/Suppressions.md)
|
194
194
|
- [Templates](docs/Templates.md)
|
195
195
|
- [EmailValidation](docs/EmailValidation.md)
|
196
|
+
- [Metrics](docs/Metrics.md)
|
196
197
|
|
197
198
|
Message Builder allows you to quickly create the array of parameters, required
|
198
199
|
to send a message, by calling a methods for each parameter.
|
data/docs/Metrics.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
Mailgun - Metrics
|
2
|
+
====================
|
3
|
+
|
4
|
+
This is the Mailgun Ruby *Metrics* utilities.
|
5
|
+
|
6
|
+
The below assumes you've already installed the Mailgun Ruby SDK in to your
|
7
|
+
project. If not, go back to the master README for instructions. It currently supports
|
8
|
+
all calls except credentials.
|
9
|
+
|
10
|
+
---
|
11
|
+
|
12
|
+
Mailgun collects many different events and generates event metrics which are available
|
13
|
+
in your Control Panel. This data is also available via our analytics metrics API endpoint.
|
14
|
+
|
15
|
+
You can view additional samples in the [metrics_spec.rb](/spec/integration/metrics_spec.rb)
|
16
|
+
or the Metrics client API in [metrics.rb](/lib/metrics/metrics.rb).
|
17
|
+
|
18
|
+
Usage
|
19
|
+
-----
|
20
|
+
|
21
|
+
To get an instance of the Metrics client:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'mailgun'
|
25
|
+
|
26
|
+
mg_client = Mailgun::Client.new('your-api-key', 'mailgun-api-host', 'v1')
|
27
|
+
metrics = Mailgun::Metrics.new(mg_client)
|
28
|
+
````
|
29
|
+
---
|
30
|
+
Get filtered metrics for an account:
|
31
|
+
```ruby
|
32
|
+
options = {
|
33
|
+
{
|
34
|
+
resolution: 'hour',
|
35
|
+
metrics: [
|
36
|
+
'accepted_count',
|
37
|
+
'delivered_count',
|
38
|
+
'clicked_rate',
|
39
|
+
'opened_rate'
|
40
|
+
],
|
41
|
+
include_aggregates: true,
|
42
|
+
start: 'Tue, 26 Nov 2024 20:56:50 -0500',
|
43
|
+
duration: '1m',
|
44
|
+
filter: {
|
45
|
+
AND: [
|
46
|
+
{
|
47
|
+
attribute: 'domain',
|
48
|
+
comparator: '!=',
|
49
|
+
values: [
|
50
|
+
{
|
51
|
+
label: 'example.com',
|
52
|
+
value: 'example.com'
|
53
|
+
}
|
54
|
+
]
|
55
|
+
}
|
56
|
+
]
|
57
|
+
},
|
58
|
+
dimensions: ['time'],
|
59
|
+
end: 'Tue, 30 Nov 2024 20:56:50 -0500',
|
60
|
+
include_subaccounts: true
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
metrics.account_metrics(options)
|
65
|
+
```
|
66
|
+
---
|
67
|
+
|
68
|
+
Get filtered usage metrics for an account:
|
69
|
+
```ruby
|
70
|
+
options = {
|
71
|
+
resolution: 'hour',
|
72
|
+
metrics: [
|
73
|
+
'accepted_count',
|
74
|
+
'delivered_count',
|
75
|
+
'clicked_rate',
|
76
|
+
'opened_rate'
|
77
|
+
],
|
78
|
+
include_aggregates: true,
|
79
|
+
start: 'Tue, 26 Nov 2024 20:56:50 -0500',
|
80
|
+
duration: '1m',
|
81
|
+
filter: {
|
82
|
+
AND: [
|
83
|
+
{
|
84
|
+
attribute: 'domain',
|
85
|
+
comparator: '!=',
|
86
|
+
values: [
|
87
|
+
{
|
88
|
+
label: 'example.com',
|
89
|
+
value: 'example.com'
|
90
|
+
}
|
91
|
+
]
|
92
|
+
}
|
93
|
+
]
|
94
|
+
},
|
95
|
+
dimensions: ['time'],
|
96
|
+
end: 'Tue, 30 Nov 2024 20:56:50 -0500',
|
97
|
+
include_subaccounts: true
|
98
|
+
}
|
99
|
+
|
100
|
+
metrics.account_usage_metrics(options)
|
101
|
+
```
|
102
|
+
|
103
|
+
---
|
104
|
+
|
105
|
+
More Documentation
|
106
|
+
------------------
|
107
|
+
See the official [Mailgun Domain Docs](https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/)
|
108
|
+
for more information
|
data/docs/Webhooks.md
CHANGED
@@ -4,8 +4,7 @@ Mailgun - Webhooks
|
|
4
4
|
This is the Mailgun Ruby *Webhook* utilities.
|
5
5
|
|
6
6
|
The below assumes you've already installed the Mailgun Ruby SDK in to your
|
7
|
-
project. If not, go back to the master README for instructions.
|
8
|
-
all calls except updating webhooks.
|
7
|
+
project. If not, go back to the master README for instructions.
|
9
8
|
|
10
9
|
Usage - Webhooks
|
11
10
|
-----------------------
|
@@ -27,6 +26,9 @@ hook.create_all 'my.perfect.domain', 'https://the.webhook.url/'
|
|
27
26
|
# Add a url for a specific webhook
|
28
27
|
hook.create 'my.perfect.domain', 'deliver', 'https://the.webhook.url/'
|
29
28
|
|
29
|
+
# Update the url for a specific webhook
|
30
|
+
hook.update 'my.perfect.domain', 'deliver', 'https://the.webhook.url/'
|
31
|
+
|
30
32
|
# Remove a url for a specific webhook
|
31
33
|
hook.remove 'my.perfect.domain', 'deliver'
|
32
34
|
|
data/lib/mailgun/client.rb
CHANGED
@@ -19,16 +19,26 @@ module Mailgun
|
|
19
19
|
timeout = nil,
|
20
20
|
proxy_url = Mailgun.proxy_url)
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
endpoint = endpoint_generator(api_host, api_version, ssl)
|
23
|
+
|
24
|
+
request_options = {
|
25
|
+
url: endpoint,
|
26
|
+
proxy: Mailgun.proxy_url,
|
27
|
+
ssl: {verify: ssl},
|
28
|
+
headers: {
|
29
|
+
'User-Agent' => "mailgun-sdk-ruby/#{Mailgun::VERSION}",
|
30
|
+
'Accept' =>'*/*'
|
31
|
+
}
|
26
32
|
}
|
27
|
-
|
33
|
+
request_options.merge!(request: {timeout: timeout}) if timeout
|
34
|
+
|
35
|
+
@http_client = Faraday.new(request_options) do |conn|
|
36
|
+
conn.request :authorization, :basic, 'api', api_key
|
37
|
+
conn.request :url_encoded
|
38
|
+
conn.response :raise_error, include_request: true
|
39
|
+
conn.adapter Faraday.default_adapter
|
40
|
+
end
|
28
41
|
|
29
|
-
endpoint = endpoint_generator(api_host, api_version, ssl)
|
30
|
-
RestClient.proxy = proxy_url
|
31
|
-
@http_client = RestClient::Resource.new(endpoint, rest_client_params)
|
32
42
|
@test_mode = test_mode
|
33
43
|
@api_version = api_version
|
34
44
|
end
|
@@ -49,17 +59,17 @@ module Mailgun
|
|
49
59
|
|
50
60
|
# Change API key
|
51
61
|
def set_api_key(api_key)
|
52
|
-
@http_client.
|
62
|
+
@http_client.set_basic_auth('api', api_key)
|
53
63
|
end
|
54
64
|
|
55
65
|
# Add subaccount id to headers
|
56
66
|
def set_subaccount(subaccount_id)
|
57
|
-
@http_client.
|
67
|
+
@http_client.headers = @http_client.headers.merge!({ SUBACCOUNT_HEADER => subaccount_id })
|
58
68
|
end
|
59
69
|
|
60
70
|
# Reset subaccount for primary usage
|
61
71
|
def reset_subaccount
|
62
|
-
@http_client.
|
72
|
+
@http_client.headers.delete(SUBACCOUNT_HEADER)
|
63
73
|
end
|
64
74
|
|
65
75
|
# Client is in test mode?
|
@@ -95,7 +105,7 @@ module Mailgun
|
|
95
105
|
return Response.from_hash(
|
96
106
|
{
|
97
107
|
:body => "{\"id\": \"test-mode-mail-#{SecureRandom.uuid}@localhost\", \"message\": \"Queued. Thank you.\"}",
|
98
|
-
:
|
108
|
+
:status => 200,
|
99
109
|
}
|
100
110
|
)
|
101
111
|
end
|
@@ -130,7 +140,7 @@ module Mailgun
|
|
130
140
|
# @param [Hash] headers Additional headers to pass to the resource.
|
131
141
|
# @return [Mailgun::Response] A Mailgun::Response object.
|
132
142
|
def post(resource_path, data, headers = {})
|
133
|
-
response = @http_client
|
143
|
+
response = @http_client.post(resource_path, data, headers)
|
134
144
|
Response.new(response)
|
135
145
|
rescue => err
|
136
146
|
raise communication_error err
|
@@ -138,21 +148,19 @@ module Mailgun
|
|
138
148
|
|
139
149
|
# Generic Mailgun GET Handler
|
140
150
|
#
|
141
|
-
# @param [String] resource_path
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
# @
|
146
|
-
# @
|
147
|
-
def get(resource_path, params =
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
response = @http_client[resource_path].get(accept: accept)
|
152
|
-
end
|
151
|
+
# @param [String] resource_path The API resource path to request, including the domain if required.
|
152
|
+
# @param [Hash] params Optional request parameters, including query parameters and headers.
|
153
|
+
# - `:headers` [Hash] (optional) Custom headers for the request.
|
154
|
+
# @param [String] accept The expected Content-Type of the response. Defaults to '*/*'.
|
155
|
+
# @return [Mailgun::Response] A response object containing the API response data.
|
156
|
+
# @raise [CommunicationError] If the request fails, raises a communication error.
|
157
|
+
def get(resource_path, params = {}, accept = '*/*')
|
158
|
+
headers = (params[:headers] || {}).merge(accept: accept)
|
159
|
+
response = @http_client.get(resource_path, params, headers)
|
160
|
+
|
153
161
|
Response.new(response)
|
154
162
|
rescue => err
|
155
|
-
raise communication_error
|
163
|
+
raise communication_error(err)
|
156
164
|
end
|
157
165
|
|
158
166
|
# Generic Mailgun PUT Handler
|
@@ -163,7 +171,7 @@ module Mailgun
|
|
163
171
|
# containing required parameters for the requested resource.
|
164
172
|
# @return [Mailgun::Response] A Mailgun::Response object.
|
165
173
|
def put(resource_path, data)
|
166
|
-
response = @http_client
|
174
|
+
response = @http_client.put(resource_path, data)
|
167
175
|
Response.new(response)
|
168
176
|
rescue => err
|
169
177
|
raise communication_error err
|
@@ -176,9 +184,9 @@ module Mailgun
|
|
176
184
|
# @return [Mailgun::Response] A Mailgun::Response object.
|
177
185
|
def delete(resource_path, params = nil)
|
178
186
|
if params
|
179
|
-
response = @http_client
|
187
|
+
response = @http_client.delete(resource_path, params: params)
|
180
188
|
else
|
181
|
-
response = @http_client
|
189
|
+
response = @http_client.delete(resource_path)
|
182
190
|
end
|
183
191
|
Response.new(response)
|
184
192
|
rescue => err
|
@@ -227,7 +235,7 @@ module Mailgun
|
|
227
235
|
# @param [StandardException] e upstream exception object
|
228
236
|
def communication_error(e)
|
229
237
|
if e.respond_to?(:response) && e.response
|
230
|
-
return case e.
|
238
|
+
return case e.response_status
|
231
239
|
when Unauthorized::CODE
|
232
240
|
Unauthorized.new(e.message, e.response)
|
233
241
|
when BadRequest::CODE
|
@@ -29,10 +29,10 @@ module Mailgun
|
|
29
29
|
# Public: Class for managing communications (eg http) response errors
|
30
30
|
# Inherits from Mailgun::Error
|
31
31
|
class CommunicationError < Error
|
32
|
-
# Public: gets HTTP status
|
33
|
-
attr_reader :
|
32
|
+
# Public: gets HTTP status status
|
33
|
+
attr_reader :status
|
34
34
|
|
35
|
-
# Public: fallback if there is no response
|
35
|
+
# Public: fallback if there is no response status on the object
|
36
36
|
NOCODE = 000
|
37
37
|
FORBIDDEN = 'Forbidden'
|
38
38
|
|
@@ -43,17 +43,17 @@ module Mailgun
|
|
43
43
|
#
|
44
44
|
def initialize(message = nil, response = nil)
|
45
45
|
@response = response
|
46
|
-
@
|
46
|
+
@status = if response.nil?
|
47
47
|
NOCODE
|
48
48
|
else
|
49
|
-
response.
|
49
|
+
response.status
|
50
50
|
end
|
51
51
|
|
52
52
|
begin
|
53
53
|
json = JSON.parse(response.body)
|
54
54
|
api_message = json['message'] || json['Error'] || json['error']
|
55
55
|
rescue JSON::ParserError
|
56
|
-
api_message = response.
|
56
|
+
api_message = response.response_body
|
57
57
|
rescue NoMethodError
|
58
58
|
api_message = "Unknown API error"
|
59
59
|
rescue
|
@@ -65,7 +65,7 @@ module Mailgun
|
|
65
65
|
|
66
66
|
super(message, response)
|
67
67
|
rescue NoMethodError, JSON::ParserError
|
68
|
-
@
|
68
|
+
@status = NOCODE
|
69
69
|
super(message, response)
|
70
70
|
end
|
71
71
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'mailgun/exceptions/exceptions'
|
2
|
+
|
3
|
+
module Mailgun
|
4
|
+
# A Mailgun::Metrics object is a simple interface to Mailgun Metrics.
|
5
|
+
# Uses Mailgun
|
6
|
+
class Metrics
|
7
|
+
# Public: creates a new Mailgun::Metrics instance.
|
8
|
+
# Defaults to Mailgun::Client
|
9
|
+
def initialize(client = Mailgun::Client.new(Mailgun.api_key, Mailgun.api_host || 'api.mailgun.net', 'v1'))
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: Post query to get account metrics
|
14
|
+
#
|
15
|
+
# options - [Hash] of
|
16
|
+
# start - [String] A start date (default: 7 days before current time). Must be in RFC 2822 format.
|
17
|
+
# end - [String] An end date (default: current time). Must be in RFC 2822 format.
|
18
|
+
# resolution - [String] A resolution in the format of 'day' 'hour' 'month'. Default is day.
|
19
|
+
# duration - [String] A duration in the format of '1d' '2h' '2m'. If duration is provided then it is calculated from the end date and overwrites the start date.
|
20
|
+
# dimensions - [Array] Attributes of the metric data such as 'subaccount'.
|
21
|
+
# metrics - [Array] Name of the metrics to receive the stats for such as 'processed_count'
|
22
|
+
# filter - [Object]
|
23
|
+
# AND: - [Array] of objects
|
24
|
+
# attribute - [String]
|
25
|
+
# comparator - [String]
|
26
|
+
# values - [Array] of objects
|
27
|
+
# label - [String]
|
28
|
+
# value - [String]
|
29
|
+
# include_subaccounts - [Boolean] Include stats from all subaccounts.
|
30
|
+
# include_aggregates - [Boolean] Include top-level aggregate metrics.
|
31
|
+
#
|
32
|
+
# Returns [Hash] Metrics
|
33
|
+
def account_metrics(options={})
|
34
|
+
@client.post('analytics/metrics', options.to_json, { "Content-Type" => "application/json" }).to_h!
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: Post query to get account usage metrics
|
38
|
+
#
|
39
|
+
# options - [Hash] of
|
40
|
+
# start - [String] A start date (default: 7 days before current time). Must be in RFC 2822 format.
|
41
|
+
# end - [String] An end date (default: current time). Must be in RFC 2822 format.
|
42
|
+
# resolution - [String] A resolution in the format of 'day' 'hour' 'month'. Default is day.
|
43
|
+
# duration - [String] A duration in the format of '1d' '2h' '2m'. If duration is provided then it is calculated from the end date and overwrites the start date.
|
44
|
+
# dimensions - [Array] Attributes of the metric data such as 'subaccount'.
|
45
|
+
# metrics - [Array] Name of the metrics to receive the stats for such as 'processed_count'
|
46
|
+
# filter - [Object]
|
47
|
+
# AND: - [Array] of objects
|
48
|
+
# attribute - [String]
|
49
|
+
# comparator - [String]
|
50
|
+
# values - [Array] of objects
|
51
|
+
# label - [String]
|
52
|
+
# value - [String]
|
53
|
+
# include_subaccounts - [Boolean] Include stats from all subaccounts.
|
54
|
+
# include_aggregates - [Boolean] Include top-level aggregate metrics.
|
55
|
+
#
|
56
|
+
# Returns [Hash] Metrics
|
57
|
+
def account_usage_metrics(options={})
|
58
|
+
@client.post('analytics/usage/metrics', options.to_json, { "Content-Type" => "application/json" }).to_h!
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/mailgun/response.rb
CHANGED
@@ -6,19 +6,20 @@ module Mailgun
|
|
6
6
|
#
|
7
7
|
# See the Github documentation for full examples.
|
8
8
|
class Response
|
9
|
-
# All responses have a payload and a
|
9
|
+
# All responses have a payload and a status corresponding to http, though
|
10
10
|
# slightly different
|
11
|
-
attr_accessor :body, :code
|
11
|
+
attr_accessor :body, :status, :code
|
12
12
|
|
13
|
-
ResponseHash = Struct.new(:body, :
|
13
|
+
ResponseHash = Struct.new(:body, :status)
|
14
14
|
def self.from_hash(h)
|
15
15
|
# Create a "fake" response object with the data passed from h
|
16
|
-
self.new ResponseHash.new(h[:body], h[:
|
16
|
+
self.new ResponseHash.new(h[:body], h[:status])
|
17
17
|
end
|
18
18
|
|
19
19
|
def initialize(response)
|
20
20
|
@body = response.body
|
21
|
-
@
|
21
|
+
@status = response.status
|
22
|
+
@code = response.status
|
22
23
|
end
|
23
24
|
|
24
25
|
# Return response as Ruby Hash
|
@@ -57,12 +58,12 @@ module Mailgun
|
|
57
58
|
rescue => err
|
58
59
|
raise ParseError.new(err), err
|
59
60
|
end
|
60
|
-
|
61
|
-
# Returns true if response
|
62
|
-
#
|
63
|
-
# @return [Boolean] A boolean that binarizes the response
|
61
|
+
|
62
|
+
# Returns true if response status is 2xx
|
63
|
+
#
|
64
|
+
# @return [Boolean] A boolean that binarizes the response status result.
|
64
65
|
def success?
|
65
|
-
(200..299).include?(
|
66
|
+
(200..299).include?(status)
|
66
67
|
end
|
67
68
|
end
|
68
69
|
end
|
data/lib/mailgun/version.rb
CHANGED
data/lib/mailgun.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'tempfile'
|
2
|
-
require '
|
2
|
+
require 'faraday'
|
3
3
|
require 'yaml'
|
4
4
|
require 'json'
|
5
5
|
|
@@ -18,6 +18,7 @@ require 'mailgun/webhooks/webhooks'
|
|
18
18
|
require 'mailgun/templates/templates'
|
19
19
|
require 'mailgun/subaccounts/subaccounts'
|
20
20
|
require 'mailgun/tags/tags'
|
21
|
+
require 'mailgun/metrics/metrics'
|
21
22
|
|
22
23
|
# Module for interacting with the sweet Mailgun API.
|
23
24
|
#
|
data/mailgun.gemspec
CHANGED
@@ -30,11 +30,12 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency 'bundler', '>= 1.16.2'
|
31
31
|
spec.add_development_dependency 'rspec', '~> 3.8.0'
|
32
32
|
spec.add_development_dependency 'rake', '~> 12.3.2'
|
33
|
+
spec.add_development_dependency 'mime-types'
|
33
34
|
spec.add_development_dependency 'webmock', '~> 3.7'
|
34
35
|
spec.add_development_dependency 'pry', '~> 0.11.3'
|
35
36
|
spec.add_development_dependency 'vcr', '~> 3.0.3'
|
36
37
|
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
37
38
|
spec.add_development_dependency 'rails'
|
38
|
-
spec.add_dependency '
|
39
|
+
spec.add_dependency 'faraday', "~> 2.1"
|
39
40
|
|
40
41
|
end
|
@@ -51,7 +51,7 @@ describe 'Client exceptions', vcr: vcr_opts do
|
|
51
51
|
:text => 'INTEGRATION TESTING'
|
52
52
|
})
|
53
53
|
rescue Mailgun::Unauthorized => err
|
54
|
-
expect(err.message).to eq('401
|
54
|
+
expect(err.message).to eq('the server responded with status 401 - Invalid Domain or API key')
|
55
55
|
else
|
56
56
|
fail
|
57
57
|
end
|
@@ -75,7 +75,7 @@ describe 'Client exceptions', vcr: vcr_opts do
|
|
75
75
|
:text => 'INTEGRATION TESTING'
|
76
76
|
})
|
77
77
|
rescue Mailgun::BadRequest => err
|
78
|
-
expect(err.message).to eq('
|
78
|
+
expect(err.message).to eq('the server responded with status 400')
|
79
79
|
else
|
80
80
|
fail
|
81
81
|
end
|
@@ -99,7 +99,7 @@ describe 'Client exceptions', vcr: vcr_opts do
|
|
99
99
|
:text => 'INTEGRATION TESTING'
|
100
100
|
})
|
101
101
|
rescue Mailgun::CommunicationError => err
|
102
|
-
expect(err.message).to include('403
|
102
|
+
expect(err.message).to include('403')
|
103
103
|
else
|
104
104
|
fail
|
105
105
|
end
|
@@ -192,7 +192,7 @@ Testing some Mailgun awesomness!'
|
|
192
192
|
expect(result.body).to include("message")
|
193
193
|
expect(result.body).to include("id")
|
194
194
|
end
|
195
|
-
|
195
|
+
|
196
196
|
it 'receives success response code' do
|
197
197
|
@mg_obj.enable_test_mode!
|
198
198
|
|
@@ -205,7 +205,7 @@ Testing some Mailgun awesomness!'
|
|
205
205
|
|
206
206
|
result = @mg_obj.send_message(@domain, data)
|
207
207
|
result.to_h!
|
208
|
-
|
208
|
+
|
209
209
|
expect(result.success?).to be(true)
|
210
210
|
end
|
211
211
|
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mailgun'
|
3
|
+
|
4
|
+
vcr_opts = { cassette_name: 'metrics' }
|
5
|
+
|
6
|
+
describe Mailgun::Metrics, vcr: vcr_opts do
|
7
|
+
let(:metrics) { Mailgun::Metrics.new(Mailgun::Client.new(APIKEY, APIHOST, 'v1')) }
|
8
|
+
|
9
|
+
describe '#account_metrics' do
|
10
|
+
let(:options) do
|
11
|
+
{
|
12
|
+
resolution: 'hour',
|
13
|
+
metrics: [
|
14
|
+
'accepted_count',
|
15
|
+
'delivered_count',
|
16
|
+
'clicked_rate',
|
17
|
+
'opened_rate'
|
18
|
+
],
|
19
|
+
include_aggregates: true,
|
20
|
+
start: 'Tue, 26 Nov 2024 20:56:50 -0500',
|
21
|
+
duration: '1m',
|
22
|
+
filter: {
|
23
|
+
AND: [
|
24
|
+
{
|
25
|
+
attribute: 'domain',
|
26
|
+
comparator: '!=',
|
27
|
+
values: [
|
28
|
+
{
|
29
|
+
label: 'example.com',
|
30
|
+
value: 'example.com'
|
31
|
+
}
|
32
|
+
]
|
33
|
+
}
|
34
|
+
]
|
35
|
+
},
|
36
|
+
dimensions: ['time'],
|
37
|
+
end: 'Tue, 30 Nov 2024 20:56:50 -0500',
|
38
|
+
include_subaccounts: true
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'responds with account metrics' do
|
43
|
+
expect(metrics.account_metrics(options)).to eq(
|
44
|
+
{
|
45
|
+
"start" => "Fri, 01 Nov 2024 01:00:00 +0000",
|
46
|
+
"end" => "Sun, 01 Dec 2024 01:00:00 +0000",
|
47
|
+
"resolution" => "hour",
|
48
|
+
"duration" => "1m",
|
49
|
+
"dimensions" => ["time"],
|
50
|
+
"pagination" => {
|
51
|
+
"sort" => "", "skip" => 0, "limit" => 1500, "total" => 3
|
52
|
+
},
|
53
|
+
"items" => [{
|
54
|
+
"dimensions" => [{
|
55
|
+
"dimension" => "time",
|
56
|
+
"value" => "Wed, 27 Nov 2024 12:00:00 +0000",
|
57
|
+
"display_value" => "Wed, 27 Nov 2024 12:00:00 +0000"
|
58
|
+
}],
|
59
|
+
"metrics" => {
|
60
|
+
"accepted_count" => 1, "delivered_count" => 1, "opened_rate" => "0.0000", "clicked_rate" => "0.0000"
|
61
|
+
}
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"dimensions" => [{
|
65
|
+
"dimension" => "time",
|
66
|
+
"value" => "Wed, 27 Nov 2024 13:00:00 +0000",
|
67
|
+
"display_value" => "Wed, 27 Nov 2024 13:00:00 +0000"
|
68
|
+
}],
|
69
|
+
"metrics" => {
|
70
|
+
"accepted_count" => 1, "delivered_count" => 1, "opened_rate" => "0.0000", "clicked_rate" => "0.0000"
|
71
|
+
}
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"dimensions" => [{
|
75
|
+
"dimension" => "time",
|
76
|
+
"value" => "Thu, 28 Nov 2024 15:00:00 +0000",
|
77
|
+
"display_value" => "Thu, 28 Nov 2024 15:00:00 +0000"
|
78
|
+
}],
|
79
|
+
"metrics" => {
|
80
|
+
"accepted_count" => 1, "delivered_count" => 1, "opened_rate" => "0.0000", "clicked_rate" => "0.0000"
|
81
|
+
}
|
82
|
+
}
|
83
|
+
],
|
84
|
+
"aggregates" => {
|
85
|
+
"metrics" => {
|
86
|
+
"accepted_count" => 3, "delivered_count" => 3, "opened_rate" => "0.0000", "clicked_rate" => "0.0000"
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#account_usage_metrics' do
|
95
|
+
let(:options) do
|
96
|
+
{
|
97
|
+
resolution: 'hour',
|
98
|
+
metrics: [
|
99
|
+
'email_preview_count',
|
100
|
+
'email_preview_failed_count',
|
101
|
+
'email_validation_bulk_count',
|
102
|
+
'email_validation_count',
|
103
|
+
'email_validation_list_count',
|
104
|
+
'email_validation_mailgun_count',
|
105
|
+
'email_validation_mailjet_count',
|
106
|
+
'email_validation_public_count',
|
107
|
+
'email_validation_single_count',
|
108
|
+
'email_validation_valid_count',
|
109
|
+
'link_validation_count',
|
110
|
+
'link_validation_failed_count',
|
111
|
+
'processed_count',
|
112
|
+
'seed_test_count'
|
113
|
+
],
|
114
|
+
include_aggregates: true,
|
115
|
+
start: 'Tue, 26 Nov 2024 20:56:50 -0500',
|
116
|
+
duration: '1m',
|
117
|
+
filter: {
|
118
|
+
AND: [
|
119
|
+
{
|
120
|
+
attribute: 'subaccount',
|
121
|
+
comparator: '!=',
|
122
|
+
values: [
|
123
|
+
{
|
124
|
+
label: '12345',
|
125
|
+
value: '12345'
|
126
|
+
}
|
127
|
+
]
|
128
|
+
}
|
129
|
+
]
|
130
|
+
},
|
131
|
+
dimensions: ['time'],
|
132
|
+
end: 'Tue, 28 Nov 2024 20:56:50 -0500',
|
133
|
+
include_subaccounts: true
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'responds with account usage metrics' do
|
138
|
+
expect(metrics.account_usage_metrics(options)).to eq(
|
139
|
+
{
|
140
|
+
"start" => "Tue, 29 Oct 2024 01:00:00 +0000",
|
141
|
+
"end" => "Fri, 29 Nov 2024 01:00:00 +0000",
|
142
|
+
"resolution" => "hour",
|
143
|
+
"duration" => "1m",
|
144
|
+
"dimensions" => ["time"],
|
145
|
+
"pagination" => {
|
146
|
+
"sort" => "", "skip" => 0, "limit" => 1500, "total" => 2
|
147
|
+
},
|
148
|
+
"items" => [{
|
149
|
+
"dimensions" => [{
|
150
|
+
"dimension" => "time",
|
151
|
+
"value" => "Wed, 27 Nov 2024 00:00:00 +0000",
|
152
|
+
"display_value" => "Wed, 27 Nov 2024 00:00:00 +0000"
|
153
|
+
}],
|
154
|
+
"metrics" => {
|
155
|
+
"processed_count" => 2,
|
156
|
+
"email_validation_count" => 0,
|
157
|
+
"email_validation_public_count" => 0,
|
158
|
+
"email_validation_valid_count" => 0,
|
159
|
+
"email_validation_single_count" => 0,
|
160
|
+
"email_validation_bulk_count" => 0,
|
161
|
+
"email_validation_list_count" => 0,
|
162
|
+
"email_validation_mailgun_count" => 0,
|
163
|
+
"email_validation_mailjet_count" => 0,
|
164
|
+
"email_preview_count" => 0,
|
165
|
+
"email_preview_failed_count" => 0,
|
166
|
+
"link_validation_count" => 0,
|
167
|
+
"link_validation_failed_count" => 0,
|
168
|
+
"seed_test_count" => 0
|
169
|
+
}
|
170
|
+
},
|
171
|
+
{
|
172
|
+
"dimensions" => [{
|
173
|
+
"dimension" => "time",
|
174
|
+
"value" => "Thu, 28 Nov 2024 00:00:00 +0000",
|
175
|
+
"display_value" => "Thu, 28 Nov 2024 00:00:00 +0000"
|
176
|
+
}],
|
177
|
+
"metrics" => {
|
178
|
+
"processed_count" => 1,
|
179
|
+
"email_validation_count" => 0,
|
180
|
+
"email_validation_public_count" => 0,
|
181
|
+
"email_validation_valid_count" => 0,
|
182
|
+
"email_validation_single_count" => 0,
|
183
|
+
"email_validation_bulk_count" => 0,
|
184
|
+
"email_validation_list_count" => 0,
|
185
|
+
"email_validation_mailgun_count" => 0,
|
186
|
+
"email_validation_mailjet_count" => 0,
|
187
|
+
"email_preview_count" => 0,
|
188
|
+
"email_preview_failed_count" => 0,
|
189
|
+
"link_validation_count" => 0,
|
190
|
+
"link_validation_failed_count" => 0,
|
191
|
+
"seed_test_count" => 0
|
192
|
+
}
|
193
|
+
}
|
194
|
+
],
|
195
|
+
"aggregates" => {
|
196
|
+
"metrics" => {
|
197
|
+
"permanent_failed_count" => 0,
|
198
|
+
"processed_count" => 3,
|
199
|
+
"email_validation_count" => 0,
|
200
|
+
"email_validation_public_count" => 0,
|
201
|
+
"email_validation_valid_count" => 0,
|
202
|
+
"email_validation_single_count" => 0,
|
203
|
+
"email_validation_bulk_count" => 0,
|
204
|
+
"email_validation_list_count" => 0,
|
205
|
+
"email_validation_mailgun_count" => 0,
|
206
|
+
"email_validation_mailjet_count" => 0,
|
207
|
+
"email_preview_count" => 0,
|
208
|
+
"email_preview_failed_count" => 0,
|
209
|
+
"link_validation_count" => 0,
|
210
|
+
"link_validation_failed_count" => 0,
|
211
|
+
"seed_test_count" => 0
|
212
|
+
}
|
213
|
+
}
|
214
|
+
}
|
215
|
+
)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -99,7 +99,7 @@ module Mailgun
|
|
99
99
|
return Response.from_hash({ body: JSON.generate({"message" => "Queued. Thank you.", "id" => id}) })
|
100
100
|
end
|
101
101
|
if resource_endpoint == "bounces"
|
102
|
-
return Response.from_hash({ body: JSON.generate({"total_count" => 1, "items" => {"created_at" => "Fri, 21 Oct 2011 11:02:55 GMT", "
|
102
|
+
return Response.from_hash({ body: JSON.generate({"total_count" => 1, "items" => {"created_at" => "Fri, 21 Oct 2011 11:02:55 GMT", "status" => 550, "address" => "baz@example.com", "error" => "Message was not accepted -- invalid mailbox. Local mailbox baz@example.com is unavailable: user not found"}}) })
|
103
103
|
end
|
104
104
|
if resource_endpoint == "lists"
|
105
105
|
return Response.from_hash({ body: JSON.generate({"member" => {"vars" => {"age" => 26}, "name" => "Foo Bar", "subscribed" => false, "address" => "bar@example.com"}, "message" => "Mailing list member has been updated"}) })
|
@@ -5,13 +5,13 @@ RSpec.describe Mailgun::CommunicationError do
|
|
5
5
|
context "when the Response body doesn't have a `message` property" do
|
6
6
|
it "doesn't raise an error" do
|
7
7
|
expect do
|
8
|
-
described_class.new('Boom!', Mailgun::Response.from_hash({
|
8
|
+
described_class.new('Boom!', Mailgun::Response.from_hash({ status: 401, body: '{}' }))
|
9
9
|
end.not_to raise_error
|
10
10
|
end
|
11
11
|
|
12
12
|
context "when the Response body has an `Error` property" do
|
13
13
|
it "uses the `Error` property as the API message" do
|
14
|
-
subject = described_class.new('Boom!', Mailgun::Response.from_hash({
|
14
|
+
subject = described_class.new('Boom!', Mailgun::Response.from_hash({ status: 401, body: '{"Error":"unauthorized"}' }))
|
15
15
|
|
16
16
|
expect(subject.message).to eq("Boom!: unauthorized")
|
17
17
|
end
|
@@ -19,7 +19,7 @@ RSpec.describe Mailgun::CommunicationError do
|
|
19
19
|
|
20
20
|
context "when the Response body has an `error` property" do
|
21
21
|
it "uses the `Error` property as the API message" do
|
22
|
-
subject = described_class.new('Boom!', Mailgun::Response.from_hash({
|
22
|
+
subject = described_class.new('Boom!', Mailgun::Response.from_hash({ status: 401, body: '{"error":"not found"}' }))
|
23
23
|
|
24
24
|
expect(subject.message).to eq("Boom!: not found")
|
25
25
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.mailgun.net/v1/analytics/metrics
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"resolution":"hour","metrics":["accepted_count","delivered_count","clicked_rate","opened_rate"],"include_aggregates":true,"start":"Tue,
|
9
|
+
26 Nov 2024 20:56:50 -0500","duration":"1m","filter":{"AND":[{"attribute":"domain","comparator":"!=","values":[{"label":"example.com","value":"example.com"}]}]},"dimensions":["time"],"end":"Tue,
|
10
|
+
30 Nov 2024 20:56:50 -0500","include_subaccounts":true}'
|
11
|
+
headers:
|
12
|
+
Accept:
|
13
|
+
- "*/*"
|
14
|
+
User-Agent:
|
15
|
+
- rest-client/2.1.0 (darwin23 x86_64) ruby/3.1.4p223
|
16
|
+
Content-Type:
|
17
|
+
- application/json
|
18
|
+
Content-Length:
|
19
|
+
- '387'
|
20
|
+
Accept-Encoding:
|
21
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
22
|
+
Host:
|
23
|
+
- api.mailgun.net
|
24
|
+
Authorization:
|
25
|
+
- Basic xxx
|
26
|
+
response:
|
27
|
+
status:
|
28
|
+
code: 200
|
29
|
+
message: OK
|
30
|
+
headers:
|
31
|
+
Access-Control-Allow-Credentials:
|
32
|
+
- 'true'
|
33
|
+
Access-Control-Allow-Origin:
|
34
|
+
- "*"
|
35
|
+
Cache-Control:
|
36
|
+
- no-store
|
37
|
+
Content-Length:
|
38
|
+
- '1006'
|
39
|
+
Content-Type:
|
40
|
+
- application/json; charset=utf-8
|
41
|
+
Date:
|
42
|
+
- Thu, 28 Nov 2024 18:20:22 GMT
|
43
|
+
Strict-Transport-Security:
|
44
|
+
- max-age=63072000; includeSubDomains
|
45
|
+
X-Mailgun-Key-Id:
|
46
|
+
- c02fd0ba-d8dbad66
|
47
|
+
X-Xss-Protection:
|
48
|
+
- 1; mode=block
|
49
|
+
body:
|
50
|
+
encoding: UTF-8
|
51
|
+
string: '{"start":"Fri, 01 Nov 2024 01:00:00 +0000","end":"Sun, 01 Dec 2024
|
52
|
+
01:00:00 +0000","resolution":"hour","duration":"1m","dimensions":["time"],"pagination":{"sort":"","skip":0,"limit":1500,"total":3},"items":[{"dimensions":[{"dimension":"time","value":"Wed,
|
53
|
+
27 Nov 2024 12:00:00 +0000","display_value":"Wed, 27 Nov 2024 12:00:00 +0000"}],"metrics":{"accepted_count":1,"delivered_count":1,"opened_rate":"0.0000","clicked_rate":"0.0000"}},{"dimensions":[{"dimension":"time","value":"Wed,
|
54
|
+
27 Nov 2024 13:00:00 +0000","display_value":"Wed, 27 Nov 2024 13:00:00 +0000"}],"metrics":{"accepted_count":1,"delivered_count":1,"opened_rate":"0.0000","clicked_rate":"0.0000"}},{"dimensions":[{"dimension":"time","value":"Thu,
|
55
|
+
28 Nov 2024 15:00:00 +0000","display_value":"Thu, 28 Nov 2024 15:00:00 +0000"}],"metrics":{"accepted_count":1,"delivered_count":1,"opened_rate":"0.0000","clicked_rate":"0.0000"}}],"aggregates":{"metrics":{"accepted_count":3,"delivered_count":3,"opened_rate":"0.0000","clicked_rate":"0.0000"}}}
|
56
|
+
|
57
|
+
'
|
58
|
+
http_version:
|
59
|
+
recorded_at: Thu, 28 Nov 2024 18:20:22 GMT
|
60
|
+
- request:
|
61
|
+
method: post
|
62
|
+
uri: https://api.mailgun.net/v1/analytics/usage/metrics
|
63
|
+
body:
|
64
|
+
encoding: UTF-8
|
65
|
+
string: '{"resolution":"hour","metrics":["email_preview_count","email_preview_failed_count","email_validation_bulk_count","email_validation_count","email_validation_list_count","email_validation_mailgun_count","email_validation_mailjet_count","email_validation_public_count","email_validation_single_count","email_validation_valid_count","link_validation_count","link_validation_failed_count","processed_count","seed_test_count"],"include_aggregates":true,"start":"Tue,
|
66
|
+
26 Nov 2024 20:56:50 -0500","duration":"1m","filter":{"AND":[{"attribute":"subaccount","comparator":"!=","values":[{"label":"12345","value":"12345"}]}]},"dimensions":["time"],"end":"Tue,
|
67
|
+
28 Nov 2024 20:56:50 -0500","include_subaccounts":true}'
|
68
|
+
headers:
|
69
|
+
Accept:
|
70
|
+
- "*/*"
|
71
|
+
User-Agent:
|
72
|
+
- rest-client/2.1.0 (darwin23 x86_64) ruby/3.1.4p223
|
73
|
+
Content-Type:
|
74
|
+
- application/json
|
75
|
+
Content-Length:
|
76
|
+
- '703'
|
77
|
+
Accept-Encoding:
|
78
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
79
|
+
Host:
|
80
|
+
- api.mailgun.net
|
81
|
+
Authorization:
|
82
|
+
- Basic xxx
|
83
|
+
response:
|
84
|
+
status:
|
85
|
+
code: 200
|
86
|
+
message: OK
|
87
|
+
headers:
|
88
|
+
Access-Control-Allow-Credentials:
|
89
|
+
- 'true'
|
90
|
+
Access-Control-Allow-Origin:
|
91
|
+
- "*"
|
92
|
+
Cache-Control:
|
93
|
+
- no-store
|
94
|
+
Content-Length:
|
95
|
+
- '1795'
|
96
|
+
Content-Type:
|
97
|
+
- application/json; charset=utf-8
|
98
|
+
Date:
|
99
|
+
- Thu, 28 Nov 2024 18:20:23 GMT
|
100
|
+
Strict-Transport-Security:
|
101
|
+
- max-age=63072000; includeSubDomains
|
102
|
+
X-Mailgun-Key-Id:
|
103
|
+
- c02fd0ba-d8dbad66
|
104
|
+
X-Xss-Protection:
|
105
|
+
- 1; mode=block
|
106
|
+
body:
|
107
|
+
encoding: UTF-8
|
108
|
+
string: '{"start":"Tue, 29 Oct 2024 01:00:00 +0000","end":"Fri, 29 Nov 2024
|
109
|
+
01:00:00 +0000","resolution":"hour","duration":"1m","dimensions":["time"],"pagination":{"sort":"","skip":0,"limit":1500,"total":2},"items":[{"dimensions":[{"dimension":"time","value":"Wed,
|
110
|
+
27 Nov 2024 00:00:00 +0000","display_value":"Wed, 27 Nov 2024 00:00:00 +0000"}],"metrics":{"processed_count":2,"email_validation_count":0,"email_validation_public_count":0,"email_validation_valid_count":0,"email_validation_single_count":0,"email_validation_bulk_count":0,"email_validation_list_count":0,"email_validation_mailgun_count":0,"email_validation_mailjet_count":0,"email_preview_count":0,"email_preview_failed_count":0,"link_validation_count":0,"link_validation_failed_count":0,"seed_test_count":0}},{"dimensions":[{"dimension":"time","value":"Thu,
|
111
|
+
28 Nov 2024 00:00:00 +0000","display_value":"Thu, 28 Nov 2024 00:00:00 +0000"}],"metrics":{"processed_count":1,"email_validation_count":0,"email_validation_public_count":0,"email_validation_valid_count":0,"email_validation_single_count":0,"email_validation_bulk_count":0,"email_validation_list_count":0,"email_validation_mailgun_count":0,"email_validation_mailjet_count":0,"email_preview_count":0,"email_preview_failed_count":0,"link_validation_count":0,"link_validation_failed_count":0,"seed_test_count":0}}],"aggregates":{"metrics":{"permanent_failed_count":0,"processed_count":3,"email_validation_count":0,"email_validation_public_count":0,"email_validation_valid_count":0,"email_validation_single_count":0,"email_validation_bulk_count":0,"email_validation_list_count":0,"email_validation_mailgun_count":0,"email_validation_mailjet_count":0,"email_preview_count":0,"email_preview_failed_count":0,"link_validation_count":0,"link_validation_failed_count":0,"seed_test_count":0}}}
|
112
|
+
|
113
|
+
'
|
114
|
+
http_version:
|
115
|
+
recorded_at: Thu, 28 Nov 2024 18:20:23 GMT
|
116
|
+
recorded_with: VCR 3.0.3
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mailgun-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mailgun
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-01-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: 12.3.2
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: mime-types
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
56
70
|
- !ruby/object:Gem::Dependency
|
57
71
|
name: webmock
|
58
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,19 +138,19 @@ dependencies:
|
|
124
138
|
- !ruby/object:Gem::Version
|
125
139
|
version: '0'
|
126
140
|
- !ruby/object:Gem::Dependency
|
127
|
-
name:
|
141
|
+
name: faraday
|
128
142
|
requirement: !ruby/object:Gem::Requirement
|
129
143
|
requirements:
|
130
|
-
- - "
|
144
|
+
- - "~>"
|
131
145
|
- !ruby/object:Gem::Version
|
132
|
-
version: 2.
|
146
|
+
version: '2.1'
|
133
147
|
type: :runtime
|
134
148
|
prerelease: false
|
135
149
|
version_requirements: !ruby/object:Gem::Requirement
|
136
150
|
requirements:
|
137
|
-
- - "
|
151
|
+
- - "~>"
|
138
152
|
- !ruby/object:Gem::Version
|
139
|
-
version: 2.
|
153
|
+
version: '2.1'
|
140
154
|
description: Mailgun's Official Ruby SDK for interacting with the Mailgun API.
|
141
155
|
email: support@mailgunhq.com
|
142
156
|
executables: []
|
@@ -158,15 +172,16 @@ files:
|
|
158
172
|
- docs/Events.md
|
159
173
|
- docs/MessageBuilder.md
|
160
174
|
- docs/Messages.md
|
175
|
+
- docs/Metrics.md
|
161
176
|
- docs/OptInHandler.md
|
162
177
|
- docs/Snippets.md
|
163
178
|
- docs/Subaccounts.md
|
164
179
|
- docs/Suppressions.md
|
180
|
+
- docs/Templates.md
|
165
181
|
- docs/Webhooks.md
|
166
182
|
- docs/railgun/EmailValidation.md
|
167
183
|
- docs/railgun/Overview.md
|
168
184
|
- docs/railgun/Parameters.md
|
169
|
-
- docs/railgun/Templates.md
|
170
185
|
- lib/mailgun-ruby.rb
|
171
186
|
- lib/mailgun.rb
|
172
187
|
- lib/mailgun/address.rb
|
@@ -178,6 +193,7 @@ files:
|
|
178
193
|
- lib/mailgun/lists/opt_in_handler.rb
|
179
194
|
- lib/mailgun/messages/batch_message.rb
|
180
195
|
- lib/mailgun/messages/message_builder.rb
|
196
|
+
- lib/mailgun/metrics/metrics.rb
|
181
197
|
- lib/mailgun/response.rb
|
182
198
|
- lib/mailgun/subaccounts/subaccounts.rb
|
183
199
|
- lib/mailgun/suppressions.rb
|
@@ -203,6 +219,7 @@ files:
|
|
203
219
|
- spec/integration/mailer_spec.rb
|
204
220
|
- spec/integration/mailgun_spec.rb
|
205
221
|
- spec/integration/messages/sample_data/mime.txt
|
222
|
+
- spec/integration/metrics_spec.rb
|
206
223
|
- spec/integration/routes_spec.rb
|
207
224
|
- spec/integration/stats_spec.rb
|
208
225
|
- spec/integration/subaccounts_spec.rb
|
@@ -240,6 +257,7 @@ files:
|
|
240
257
|
- vcr_cassettes/mailing_list.todo.yml
|
241
258
|
- vcr_cassettes/mailing_list.yml
|
242
259
|
- vcr_cassettes/message_deliver.yml
|
260
|
+
- vcr_cassettes/metrics.yml
|
243
261
|
- vcr_cassettes/routes.yml
|
244
262
|
- vcr_cassettes/send_message.yml
|
245
263
|
- vcr_cassettes/stats.yml
|
@@ -270,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
270
288
|
- !ruby/object:Gem::Version
|
271
289
|
version: '0'
|
272
290
|
requirements: []
|
273
|
-
rubygems_version: 3.
|
291
|
+
rubygems_version: 3.3.27
|
274
292
|
signing_key:
|
275
293
|
specification_version: 4
|
276
294
|
summary: Mailgun's Official Ruby SDK
|
@@ -286,6 +304,7 @@ test_files:
|
|
286
304
|
- spec/integration/mailer_spec.rb
|
287
305
|
- spec/integration/mailgun_spec.rb
|
288
306
|
- spec/integration/messages/sample_data/mime.txt
|
307
|
+
- spec/integration/metrics_spec.rb
|
289
308
|
- spec/integration/routes_spec.rb
|
290
309
|
- spec/integration/stats_spec.rb
|
291
310
|
- spec/integration/subaccounts_spec.rb
|
File without changes
|