mailgun-ruby 1.1.2 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|