mailgun-ruby 1.1.2 → 1.1.6
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/.ruby-env.yml.example +1 -1
- data/.travis.yml +6 -4
- data/README.md +46 -8
- data/{Domains.md → docs/Domains.md} +18 -0
- data/{Events.md → docs/Events.md} +0 -0
- data/{MessageBuilder.md → docs/MessageBuilder.md} +21 -5
- data/{Messages.md → docs/Messages.md} +3 -3
- data/{OptInHandler.md → docs/OptInHandler.md} +0 -0
- data/{Snippets.md → docs/Snippets.md} +21 -2
- data/docs/Suppressions.md +82 -0
- data/{Webhooks.md → docs/Webhooks.md} +0 -0
- data/lib/mailgun/client.rb +27 -3
- data/lib/mailgun/events/events.rb +23 -6
- data/lib/mailgun/messages/batch_message.rb +2 -2
- data/lib/mailgun/messages/message_builder.rb +79 -24
- data/lib/mailgun/suppressions.rb +270 -0
- data/lib/mailgun/version.rb +1 -1
- data/lib/mailgun-ruby.rb +2 -1
- data/lib/railgun/attachment.rb +56 -0
- data/lib/railgun/errors.rb +27 -0
- data/lib/railgun/mailer.rb +158 -0
- data/lib/railgun/message.rb +17 -0
- data/lib/railgun/railtie.rb +9 -0
- data/lib/railgun.rb +8 -0
- data/mailgun.gemspec +1 -1
- data/spec/integration/events_spec.rb +9 -1
- data/spec/integration/mailgun_spec.rb +0 -0
- data/spec/integration/suppressions_spec.rb +126 -0
- data/spec/unit/events/events_spec.rb +17 -2
- data/spec/unit/messages/message_builder_spec.rb +44 -7
- data/vcr_cassettes/events.yml +48 -1
- data/vcr_cassettes/suppressions.yml +676 -0
- metadata +21 -10
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'action_mailer'
|
2
|
+
require 'mailgun'
|
3
|
+
require 'rails'
|
4
|
+
require 'railgun/errors'
|
5
|
+
|
6
|
+
module Railgun
|
7
|
+
|
8
|
+
# Railgun::Mailer is an ActionMailer provider for sending mail through
|
9
|
+
# Mailgun.
|
10
|
+
class Mailer
|
11
|
+
|
12
|
+
# [Hash] config ->
|
13
|
+
# Requires *at least* `api_key` and `domain` keys.
|
14
|
+
attr_accessor :config, :domain
|
15
|
+
|
16
|
+
# Initialize the Railgun mailer.
|
17
|
+
#
|
18
|
+
# @param [Hash] config Hash of config values, typically from `app_config.action_mailer.mailgun_config`
|
19
|
+
def initialize(config)
|
20
|
+
@config = config
|
21
|
+
|
22
|
+
[:api_key, :domain].each do |k|
|
23
|
+
raise Railgun::ConfigurationError.new("Config requires `#{k}` key", @config) unless @config.has_key?(k)
|
24
|
+
end
|
25
|
+
|
26
|
+
@mg_client = Mailgun::Client.new(config[:api_key])
|
27
|
+
@domain = @config[:domain]
|
28
|
+
|
29
|
+
if (@config[:fake_message_send] || false)
|
30
|
+
Rails.logger.info "NOTE: fake message sending has been enabled for mailgun-ruby!"
|
31
|
+
@mg_client.enable_test_mode!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def deliver!(mail)
|
36
|
+
mg_message = Railgun.transform_for_mailgun(mail)
|
37
|
+
response = @mg_client.send_message(@domain, mg_message)
|
38
|
+
|
39
|
+
if response.code == 200 then
|
40
|
+
mg_id = response.body['id']
|
41
|
+
mail.message_id = mg_id
|
42
|
+
end
|
43
|
+
response
|
44
|
+
end
|
45
|
+
|
46
|
+
def mailgun_client
|
47
|
+
@mg_obj
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
module_function
|
53
|
+
|
54
|
+
# Performs a series of transformations on the `mailgun*` attributes.
|
55
|
+
# After prefixing them with the proper option type, they are added to
|
56
|
+
# the message hash where they will then be sent to the API as JSON.
|
57
|
+
#
|
58
|
+
# @param [Mail::Message] mail message to transform
|
59
|
+
#
|
60
|
+
# @return [Hash] transformed message hash
|
61
|
+
def transform_for_mailgun(mail)
|
62
|
+
message = build_message_object(mail)
|
63
|
+
|
64
|
+
# v:* attributes (variables)
|
65
|
+
mail.mailgun_variables.try(:each) do |k, v|
|
66
|
+
message["v:#{k}"] = v
|
67
|
+
end
|
68
|
+
|
69
|
+
# o:* attributes (options)
|
70
|
+
mail.mailgun_options.try(:each) do |k, v|
|
71
|
+
message["o:#{k}"] = v
|
72
|
+
end
|
73
|
+
|
74
|
+
# h:* attributes (headers)
|
75
|
+
mail.mailgun_headers.try(:each) do |k, v|
|
76
|
+
message["h:#{k}"] = v
|
77
|
+
end
|
78
|
+
|
79
|
+
# recipient variables
|
80
|
+
message['recipient-variables'] = mail.mailgun_recipient_variables.to_json if mail.mailgun_recipient_variables
|
81
|
+
|
82
|
+
# reject blank values
|
83
|
+
message.delete_if do |k, v|
|
84
|
+
v.nil? or (v.respond_to?(:empty) and v.empty?)
|
85
|
+
end
|
86
|
+
|
87
|
+
return message
|
88
|
+
end
|
89
|
+
|
90
|
+
# Acts on a Rails/ActionMailer message object and uses Mailgun::MessageBuilder
|
91
|
+
# to construct a new message.
|
92
|
+
#
|
93
|
+
# @param [Mail::Message] mail message to transform
|
94
|
+
#
|
95
|
+
# @returns [Hash] Message hash from Mailgun::MessageBuilder
|
96
|
+
def build_message_object(mail)
|
97
|
+
mb = Mailgun::MessageBuilder.new
|
98
|
+
|
99
|
+
mb.from mail[:from]
|
100
|
+
mb.reply_to(mail[:reply_to].to_s) if mail[:reply_to].present?
|
101
|
+
mb.subject mail.subject
|
102
|
+
mb.body_html extract_body_html(mail)
|
103
|
+
mb.body_text extract_body_text(mail)
|
104
|
+
|
105
|
+
[:to, :cc, :bcc].each do |rcpt_type|
|
106
|
+
addrs = mail[rcpt_type] || nil
|
107
|
+
case addrs
|
108
|
+
when String
|
109
|
+
# Likely a single recipient
|
110
|
+
mb.add_recipient rcpt_type.to_s, addrs
|
111
|
+
when Array
|
112
|
+
addrs.each do |addr|
|
113
|
+
mb.add_recipient rcpt_type.to_s, addr
|
114
|
+
end
|
115
|
+
when Mail::Field
|
116
|
+
mb.add_recipient rcpt_type.to_s, addrs.to_s
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
return mb.message if mail.attachments.empty?
|
121
|
+
|
122
|
+
mail.attachments.each do |attach|
|
123
|
+
attach = Attachment.new(attach, encoding: 'ascii-8bit', inline: attach.inline?)
|
124
|
+
attach.attach_to_message! mb
|
125
|
+
end
|
126
|
+
|
127
|
+
return mb.message
|
128
|
+
end
|
129
|
+
|
130
|
+
# Returns the decoded HTML body from the Mail::Message object if available,
|
131
|
+
# otherwise nil.
|
132
|
+
#
|
133
|
+
# @param [Mail::Message] mail message to transform
|
134
|
+
#
|
135
|
+
# @return [String]
|
136
|
+
def extract_body_html(mail)
|
137
|
+
begin
|
138
|
+
(mail.html_part || mail).body.decoded || nil
|
139
|
+
rescue
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Returns the decoded text body from the Mail::Message object if it is available,
|
145
|
+
# otherwise nil.
|
146
|
+
#
|
147
|
+
# @param [Mail::Message] mail message to transform
|
148
|
+
#
|
149
|
+
# @return [String]
|
150
|
+
def extract_body_text(mail)
|
151
|
+
begin
|
152
|
+
(mail.text_part || mail).body.decoded || nil
|
153
|
+
rescue
|
154
|
+
nil
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'mail'
|
2
|
+
require 'mailgun/messages/message_builder'
|
3
|
+
require 'railgun/attachment'
|
4
|
+
require 'railgun/errors'
|
5
|
+
|
6
|
+
module Mail
|
7
|
+
|
8
|
+
class Message
|
9
|
+
|
10
|
+
# Attributes to hold Mailgun-specific information
|
11
|
+
attr_accessor :mailgun_variables,
|
12
|
+
:mailgun_options,
|
13
|
+
:mailgun_recipient_variables,
|
14
|
+
:mailgun_headers
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/railgun.rb
ADDED
data/mailgun.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = Mailgun::VERSION
|
10
10
|
spec.homepage = 'http://www.mailgun.com'
|
11
11
|
spec.platform = Gem::Platform::RUBY
|
12
|
-
spec.license = 'Apache'
|
12
|
+
spec.license = 'Apache-2.0'
|
13
13
|
|
14
14
|
spec.summary = "Mailgun's Official Ruby SDK"
|
15
15
|
spec.description = "Mailgun's Official Ruby SDK for interacting with the Mailgun API."
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'mailgun'
|
3
|
+
require 'mailgun/events/events'
|
3
4
|
|
4
5
|
vcr_opts = { :cassette_name => "events" }
|
5
6
|
|
@@ -7,9 +8,10 @@ describe 'For the Events endpoint', vcr: vcr_opts do
|
|
7
8
|
before(:all) do
|
8
9
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
9
10
|
@domain = TESTDOMAIN
|
11
|
+
@events = Mailgun::Events.new(@mg_obj, @domain)
|
10
12
|
end
|
11
13
|
|
12
|
-
it 'get an event.' do
|
14
|
+
it 'can get an event.' do
|
13
15
|
result = @mg_obj.get("#{@domain}/events", {:limit => 1})
|
14
16
|
|
15
17
|
result.to_h!
|
@@ -17,4 +19,10 @@ describe 'For the Events endpoint', vcr: vcr_opts do
|
|
17
19
|
expect(result.body["paging"]).to include("next")
|
18
20
|
expect(result.body["paging"]).to include("previous")
|
19
21
|
end
|
22
|
+
|
23
|
+
it 'can iterate over all events with `each`' do
|
24
|
+
@events.each do |e|
|
25
|
+
expect(e.id).to eq("JAx9z641TuGGUyaJlD9sCQ")
|
26
|
+
end
|
27
|
+
end
|
20
28
|
end
|
File without changes
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'mailgun'
|
4
|
+
require 'mailgun/suppressions'
|
5
|
+
|
6
|
+
vcr_opts = { :cassette_name => 'suppressions' }
|
7
|
+
|
8
|
+
describe 'For the suppressions handling class', order: :defined, vcr: vcr_opts do
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
@mg_obj = Mailgun::Client.new(APIKEY)
|
12
|
+
@suppress = Mailgun::Suppressions.new(@mg_obj, TESTDOMAIN)
|
13
|
+
|
14
|
+
@addresses = ['test1@example.com', 'test2@example.org', 'test3@example.net', 'test4@example.info']
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'can batch-add bounces' do
|
18
|
+
bounces = []
|
19
|
+
@addresses.each do |addr|
|
20
|
+
bounces.push({
|
21
|
+
:address => addr,
|
22
|
+
:code => 500,
|
23
|
+
:error => 'integration testing',
|
24
|
+
})
|
25
|
+
end
|
26
|
+
|
27
|
+
response, nested = @suppress.create_bounces bounces
|
28
|
+
response.to_h!
|
29
|
+
|
30
|
+
expect(response.code).to eq(200)
|
31
|
+
expect(response.body['message']).to eq('4 addresses have been added to the bounces table')
|
32
|
+
expect(nested.length).to eq(0)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'raises ParameterError if no bounce[:address] is present' do
|
36
|
+
bounces = []
|
37
|
+
bounces.push({
|
38
|
+
:code => 500,
|
39
|
+
:error => 'integration testing',
|
40
|
+
})
|
41
|
+
|
42
|
+
expect { @suppress.create_bounces bounces }.to raise_error(Mailgun::ParameterError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'removes a single bounce address' do
|
46
|
+
@addresses.each do |addr|
|
47
|
+
response = @suppress.delete_bounce addr
|
48
|
+
response.to_h!
|
49
|
+
|
50
|
+
expect(response.code).to eq(200)
|
51
|
+
expect(response.body['message']).to eq('Bounced address has been removed')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can batch-add unsubscribes' do
|
56
|
+
unsubscribes = []
|
57
|
+
@addresses.each do |addr|
|
58
|
+
unsubscribes.push({
|
59
|
+
:address => addr,
|
60
|
+
:tag => 'integration',
|
61
|
+
})
|
62
|
+
end
|
63
|
+
|
64
|
+
response, nested = @suppress.create_unsubscribes unsubscribes
|
65
|
+
response.to_h!
|
66
|
+
|
67
|
+
expect(response.code).to eq(200)
|
68
|
+
expect(response.body['message']).to eq('4 addresses have been added to the unsubscribes table')
|
69
|
+
expect(nested.length).to eq(0)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'raises ParameterError if no unsubscribe[:address] is present' do
|
73
|
+
unsubscribes = []
|
74
|
+
unsubscribes.push({
|
75
|
+
:tag => 'integration',
|
76
|
+
})
|
77
|
+
|
78
|
+
expect { @suppress.create_unsubscribes unsubscribes }.to raise_error(Mailgun::ParameterError)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'removes a single unsubscribe address' do
|
82
|
+
@addresses.each do |addr|
|
83
|
+
response = @suppress.delete_unsubscribe addr
|
84
|
+
response.to_h!
|
85
|
+
|
86
|
+
expect(response.code).to eq(200)
|
87
|
+
expect(response.body['message']).to eq('Unsubscribe event has been removed')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'can batch-add complaints' do
|
92
|
+
complaints = []
|
93
|
+
@addresses.each do |addr|
|
94
|
+
complaints.push :address => addr
|
95
|
+
end
|
96
|
+
|
97
|
+
response, nested = @suppress.create_complaints complaints
|
98
|
+
response.to_h!
|
99
|
+
|
100
|
+
expect(response.code).to eq(200)
|
101
|
+
expect(response.body['message']).to eq('4 complaint addresses have been added to the complaints table')
|
102
|
+
expect(nested.length).to eq(0)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'raises ParameterError if no complaint[:address] is present' do
|
106
|
+
complaints = []
|
107
|
+
complaints.push({
|
108
|
+
:tag => 'integration',
|
109
|
+
})
|
110
|
+
|
111
|
+
expect { @suppress.create_complaints complaints }.to raise_error(Mailgun::ParameterError)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'removes a single complaint address' do
|
115
|
+
@addresses.each do |addr|
|
116
|
+
response = @suppress.delete_complaint addr
|
117
|
+
response.to_h!
|
118
|
+
|
119
|
+
expect(response.code).to eq(200)
|
120
|
+
expect(response.body['message']).to eq('Spam complaint has been removed')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# TODO: Add tests for pagination support.
|
125
|
+
end
|
126
|
+
|
@@ -5,7 +5,7 @@ describe 'The method get' do
|
|
5
5
|
@mg_obj = Mailgun::UnitClient.new('events')
|
6
6
|
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
7
7
|
result = events.get()
|
8
|
-
|
8
|
+
|
9
9
|
expect(result.body).to include("items")
|
10
10
|
expect(result.body).to include("paging")
|
11
11
|
end
|
@@ -17,7 +17,7 @@ describe 'The method next' do
|
|
17
17
|
@mg_obj = Mailgun::UnitClient.new('events')
|
18
18
|
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
19
19
|
result = events.next()
|
20
|
-
|
20
|
+
|
21
21
|
expect(result.body).to include("items")
|
22
22
|
expect(result.body).to include("paging")
|
23
23
|
end
|
@@ -33,3 +33,18 @@ describe 'The method previous' do
|
|
33
33
|
expect(result.body).to include("paging")
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
describe 'The method each' do
|
38
|
+
it 'should iterate over all event items.' do
|
39
|
+
@mg_obj = Mailgun::UnitClient.new('events')
|
40
|
+
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
41
|
+
# Events from the UnitClient are actually empty.
|
42
|
+
count = 0
|
43
|
+
events.each do |e|
|
44
|
+
count = count + 1
|
45
|
+
end
|
46
|
+
|
47
|
+
# Better than nothing..
|
48
|
+
expect(count).to eq(0)
|
49
|
+
end
|
50
|
+
end
|
@@ -70,7 +70,7 @@ describe 'The method add_recipient' do
|
|
70
70
|
recipient_type = 'h:reply-to'
|
71
71
|
@mb_obj.add_recipient(recipient_type, @address, @variables)
|
72
72
|
|
73
|
-
expect(@mb_obj.message[recipient_type]
|
73
|
+
expect(@mb_obj.message[recipient_type]).to eq("'#{@variables['first']} #{@variables['last']}' <#{@address}>")
|
74
74
|
@mb_obj.counters[:recipients].each_value{|value| expect(value).to eq(0)}
|
75
75
|
end
|
76
76
|
|
@@ -249,6 +249,31 @@ describe 'The method add_inline_image' do
|
|
249
249
|
end
|
250
250
|
end
|
251
251
|
|
252
|
+
describe 'The method list_unsubscribe' do
|
253
|
+
before(:each) do
|
254
|
+
@mb_obj = Mailgun::MessageBuilder.new
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'sets the message list_unsubscribe to blank if called and no parameters are provided' do
|
258
|
+
@mb_obj.list_unsubscribe
|
259
|
+
expect(@mb_obj.message['h:List-Unsubscribe']).to eq('')
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'sets the message list_unsubscribe if called with one list_unsubscribe parameter' do
|
263
|
+
unsubscribe_to = 'http://example.com/stop-hassle'
|
264
|
+
@mb_obj.list_unsubscribe(unsubscribe_to)
|
265
|
+
expect(@mb_obj.message['h:List-Unsubscribe']).to eq("<#{unsubscribe_to}>")
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'sets the message list_unsubscribe if called with many list_unsubscribe parameters' do
|
269
|
+
unsubscribe_to = %w(http://example.com/stop-hassle mailto:stop-hassle@example.com)
|
270
|
+
@mb_obj.list_unsubscribe(*unsubscribe_to)
|
271
|
+
expect(@mb_obj.message['h:List-Unsubscribe']).to eq(
|
272
|
+
unsubscribe_to.map { |var| "<#{var}>" }.join(',')
|
273
|
+
)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
252
277
|
describe 'The method set_test_mode' do
|
253
278
|
it 'warns of set_test_mode deprecation' do
|
254
279
|
@mb_obj = Mailgun::MessageBuilder.new
|
@@ -485,19 +510,31 @@ describe 'The method header' do
|
|
485
510
|
it 'accepts valid JSON and appends as data to the message.' do
|
486
511
|
@mb_obj.header('my-data', '{"key":"value"}')
|
487
512
|
|
488
|
-
expect(@mb_obj.message["
|
489
|
-
expect(@mb_obj.message["
|
513
|
+
expect(@mb_obj.message["h:my-data"]).to be_kind_of(String)
|
514
|
+
expect(@mb_obj.message["h:my-data"].to_s).to eq('{"key":"value"}')
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
describe 'The method variable' do
|
519
|
+
before(:each) do
|
520
|
+
@mb_obj = Mailgun::MessageBuilder.new
|
521
|
+
end
|
522
|
+
it 'accepts valid JSON and stores it as message[param].' do
|
523
|
+
@mb_obj.variable('my-data', '{"key":"value"}')
|
524
|
+
|
525
|
+
expect(@mb_obj.message["v:my-data"]).to be_kind_of(String)
|
526
|
+
expect(@mb_obj.message["v:my-data"].to_s).to eq('{"key":"value"}')
|
490
527
|
end
|
491
528
|
it 'accepts a hash and appends as data to the message.' do
|
492
529
|
data = {'key' => 'value'}
|
493
|
-
@mb_obj.
|
530
|
+
@mb_obj.variable('my-data', data)
|
494
531
|
|
495
|
-
expect(@mb_obj.message["v:my-data"]
|
496
|
-
expect(@mb_obj.message["v:my-data"]
|
532
|
+
expect(@mb_obj.message["v:my-data"]).to be_kind_of(String)
|
533
|
+
expect(@mb_obj.message["v:my-data"].to_s).to eq('{"key":"value"}')
|
497
534
|
end
|
498
535
|
it 'throws an exception on broken JSON.' do
|
499
536
|
data = 'This is some crappy JSON.'
|
500
|
-
expect {@mb_obj.
|
537
|
+
expect {@mb_obj.variable('my-data', data)}.to raise_error(Mailgun::ParameterError)
|
501
538
|
end
|
502
539
|
end
|
503
540
|
|
data/vcr_cassettes/events.yml
CHANGED
@@ -58,4 +58,51 @@ http_interactions:
|
|
58
58
|
\ }\n}"
|
59
59
|
http_version:
|
60
60
|
recorded_at: Thu, 07 Jan 2016 22:08:06 GMT
|
61
|
-
|
61
|
+
- request:
|
62
|
+
method: get
|
63
|
+
uri: https://api:<APIKEY>@api.mailgun.net/v3/DOMAIN.TEST/events
|
64
|
+
body:
|
65
|
+
encoding: US-ASCII
|
66
|
+
string: ''
|
67
|
+
headers:
|
68
|
+
Accept:
|
69
|
+
- "*/*"
|
70
|
+
Accept-Encoding:
|
71
|
+
- gzip, deflate
|
72
|
+
User-Agent:
|
73
|
+
- rest-client/2.0.1 (linux-gnu x86_64) ruby/2.3.3p222
|
74
|
+
Host:
|
75
|
+
- api.mailgun.net
|
76
|
+
response:
|
77
|
+
status:
|
78
|
+
code: 200
|
79
|
+
message: OK
|
80
|
+
headers:
|
81
|
+
Access-Control-Allow-Headers:
|
82
|
+
- Content-Type, x-requested-with
|
83
|
+
Access-Control-Allow-Methods:
|
84
|
+
- GET, POST, PUT, DELETE, OPTIONS
|
85
|
+
Access-Control-Allow-Origin:
|
86
|
+
- "*"
|
87
|
+
Access-Control-Max-Age:
|
88
|
+
- '600'
|
89
|
+
Content-Type:
|
90
|
+
- application/json
|
91
|
+
Date:
|
92
|
+
- Wed, 10 May 2017 20:06:54 GMT
|
93
|
+
Server:
|
94
|
+
- nginx
|
95
|
+
Content-Length:
|
96
|
+
- '2060'
|
97
|
+
Connection:
|
98
|
+
- keep-alive
|
99
|
+
body:
|
100
|
+
encoding: UTF-8
|
101
|
+
string: "{\n \"items\": [], \n \"paging\": {\n \"next\": \"https://api.mailgun.net/v3/DOMAIN.TEST/events/W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIFsiZiJdLCBudWxsLCBbWyJhY2NvdW50LmlkIiwgIjU4MDUyMTg2NzhmYTE2MTNjNzkwYjUwZiJdLCBbImRvbWFpbi5uYW1lIiwgInNhbmRib3gyOTcwMTUyYWYzZDM0NTU5YmZjN2U3MTcwM2E2Y2YyNC5tYWlsZ3VuLm9yZyJdXSwgMTAwLCBudWxsXQ==\",
|
102
|
+
\n \"last\": \"https://api.mailgun.net/v3/DOMAIN.TEST/events/W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTA4VDIwOjA2OjU0LjU3NyswMDowMCIsICJlIjogIjIwMTctMDUtMTBUMjA6MDY6NTQuNTc2KzAwOjAwIn0sIFsicCIsICJmIl0sIG51bGwsIFtbImFjY291bnQuaWQiLCAiNTgwNTIxODY3OGZhMTYxM2M3OTBiNTBmIl0sIFsiZG9tYWluLm5hbWUiLCAic2FuZGJveDI5NzAxNTJhZjNkMzQ1NTliZmM3ZTcxNzAzYTZjZjI0Lm1haWxndW4ub3JnIl1dLCAxMDAsIG51bGxd\",
|
103
|
+
\n \"first\": \"https://api.mailgun.net/v3/DOMAIN.TEST/events/W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIFsiZiJdLCBudWxsLCBbWyJhY2NvdW50LmlkIiwgIjU4MDUyMTg2NzhmYTE2MTNjNzkwYjUwZiJdLCBbImRvbWFpbi5uYW1lIiwgInNhbmRib3gyOTcwMTUyYWYzZDM0NTU5YmZjN2U3MTcwM2E2Y2YyNC5tYWlsZ3VuLm9yZyJdXSwgMTAwLCBudWxsXQ==\",
|
104
|
+
\n \"previous\": \"https://api.mailgun.net/v3/DOMAIN.TEST/events/W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMTBUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIFsicCIsICJmIl0sIG51bGwsIFtbImFjY291bnQuaWQiLCAiNTgwNTIxODY3OGZhMTYxM2M3OTBiNTBmIl0sIFsiZG9tYWluLm5hbWUiLCAic2FuZGJveDI5NzAxNTJhZjNkMzQ1NTliZmM3ZTcxNzAzYTZjZjI0Lm1haWxndW4ub3JnIl1dLCAxMDAsIG51bGxd\"\n
|
105
|
+
\ }\n}"
|
106
|
+
http_version:
|
107
|
+
recorded_at: Wed, 10 May 2017 20:06:54 GMT
|
108
|
+
recorded_with: VCR 3.0.3
|