mailgun-ruby 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/mailgun.rb +2 -1
- data/lib/mailgun/events/events.rb +74 -0
- data/lib/mailgun/lists/opt_in_handler.rb +21 -9
- data/lib/mailgun/version.rb +1 -1
- data/spec/integration/mailgun_spec.rb +38 -38
- data/spec/unit/connection/test_client.rb +96 -40
- data/spec/unit/events/events_spec.rb +32 -0
- data/spec/unit/lists/opt_in_handler_spec.rb +1 -1
- data/spec/unit/mailgun_spec.rb +12 -20
- data/spec/unit/messages/batch_message_spec.rb +3 -11
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d2289f0c188dd1fd14e9560f3e7f9d8b14e9193
|
4
|
+
data.tar.gz: 35e39b90b7185d846a515c642b7eb2340f09d37d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad0617bd4042f6dc27561c5ee864ec84f034f40c2b2fde569d996e10adfe830dbc9983d71b1be34dfd236154918c2659d1cebdee0487cb7e70f7685419037503
|
7
|
+
data.tar.gz: 39002d5ffd24977418dadc676925df6503cd09aa73122bf3c5c2b15fac8575dcf3717e4a11b4d28229b283123c35ccf0b8aaaffb47c63b75dc5b9f201bf5fcde
|
data/README.md
CHANGED
data/lib/mailgun.rb
CHANGED
@@ -6,6 +6,7 @@ require 'json'
|
|
6
6
|
require "mailgun/version"
|
7
7
|
require "mailgun/lists/opt_in_handler"
|
8
8
|
require "mailgun/messages/batch_message"
|
9
|
+
require "mailgun/events/events"
|
9
10
|
require "mailgun/messages/message_builder"
|
10
11
|
require "mailgun/exceptions/exceptions"
|
11
12
|
|
@@ -84,7 +85,7 @@ module Mailgun
|
|
84
85
|
def get(resource_path, params=nil, accept="*/*")
|
85
86
|
begin
|
86
87
|
if params
|
87
|
-
response = http_client[resource_path].get(:params => params, :accept => accept)
|
88
|
+
response = @http_client[resource_path].get(:params => params, :accept => accept)
|
88
89
|
else
|
89
90
|
response = @http_client[resource_path].get(:accept => accept)
|
90
91
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'mailgun'
|
2
|
+
require "mailgun/exceptions/exceptions"
|
3
|
+
|
4
|
+
|
5
|
+
module Mailgun
|
6
|
+
|
7
|
+
# A Mailgun::Events object makes it really simple to consume
|
8
|
+
# Mailgun's events from the Events endpoint.
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# See the Github documentation for full examples.
|
12
|
+
|
13
|
+
class Events
|
14
|
+
|
15
|
+
def initialize(client, domain)
|
16
|
+
@client = client
|
17
|
+
@domain = domain
|
18
|
+
@paging_next = nil
|
19
|
+
@paging_previous = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
# Issues a simple get against the client.
|
23
|
+
#
|
24
|
+
# @param [Hash] params A hash of query options and/or filters.
|
25
|
+
# @return [Mailgun::Response] Mailgun Response object.
|
26
|
+
|
27
|
+
def get(params=nil)
|
28
|
+
_get(params)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Using built in paging, obtains the next set of data.
|
32
|
+
#
|
33
|
+
# @return [Mailgun::Response] Mailgun Response object.
|
34
|
+
|
35
|
+
def next()
|
36
|
+
_get(nil, @paging_next)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Using built in paging, obtains the previous set of data.
|
40
|
+
#
|
41
|
+
# @return [Mailgun::Response] Mailgun Response object.
|
42
|
+
|
43
|
+
def previous()
|
44
|
+
_get(nil, @paging_previous)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def _get(params=nil, paging=nil)
|
50
|
+
response = @client.get(construct_url(paging), params)
|
51
|
+
extract_paging(response)
|
52
|
+
response
|
53
|
+
end
|
54
|
+
|
55
|
+
def extract_paging(response)
|
56
|
+
paging_next = response.to_h["paging"]["next"]
|
57
|
+
paging_previous = response.to_h["paging"]["previous"]
|
58
|
+
|
59
|
+
# This is pretty hackish. But the URL will never change in API v2.
|
60
|
+
@paging_next = paging_next.split("/")[6]
|
61
|
+
@paging_previous = paging_previous.split("/")[6]
|
62
|
+
end
|
63
|
+
|
64
|
+
def construct_url(paging=nil)
|
65
|
+
if paging
|
66
|
+
"#{@domain}/events/#{paging}"
|
67
|
+
else
|
68
|
+
"#{@domain}/events"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'digest'
|
2
1
|
require 'json'
|
3
2
|
require 'uri'
|
4
3
|
require 'base64'
|
4
|
+
require 'digest/hmac'
|
5
5
|
|
6
6
|
module Mailgun
|
7
7
|
|
@@ -16,11 +16,19 @@ module Mailgun
|
|
16
16
|
# @return [String] A url encoded URL suffix hash.
|
17
17
|
|
18
18
|
def self.generate_hash(mailing_list, secret_app_id, recipient_address)
|
19
|
-
|
20
|
-
|
21
|
-
'r' => recipient_address}
|
19
|
+
innerPayload = {'l' => mailing_list,
|
20
|
+
'r' => recipient_address}
|
22
21
|
|
23
|
-
|
22
|
+
innerPayloadEncoded = Base64.encode64(JSON.generate(innerPayload))
|
23
|
+
|
24
|
+
digest = Digest::HMAC.hexdigest(innerPayloadEncoded, secret_app_id, Digest::SHA1)
|
25
|
+
|
26
|
+
outerPayload = {'h' => digest,
|
27
|
+
'p' => innerPayloadEncoded}
|
28
|
+
|
29
|
+
outerPayloadEncoded = Base64.encode64(JSON.generate(outerPayload))
|
30
|
+
|
31
|
+
URI.escape(outerPayloadEncoded)
|
24
32
|
end
|
25
33
|
|
26
34
|
# Validates the hash provided from the generate_hash method.
|
@@ -30,12 +38,16 @@ module Mailgun
|
|
30
38
|
# @return [Hash or Boolean] A hash with 'recipient_address' and 'mailing_list', if validates. Otherwise, boolean false.
|
31
39
|
|
32
40
|
def self.validate_hash(secret_app_id, unique_hash)
|
33
|
-
|
34
|
-
|
35
|
-
|
41
|
+
outerPayload = JSON.parse(Base64.decode64(URI.unescape(unique_hash)))
|
42
|
+
|
43
|
+
generated_hash = Digest::HMAC.hexdigest(outerPayload['p'], secret_app_id, Digest::SHA1)
|
44
|
+
|
45
|
+
innerPayload = JSON.parse(Base64.decode64(URI.unescape(outerPayload['p'])))
|
46
|
+
|
47
|
+
hash_provided = outerPayload['h']
|
36
48
|
|
37
49
|
if(generated_hash == hash_provided)
|
38
|
-
return {'recipient_address' =>
|
50
|
+
return {'recipient_address' => innerPayload['r'], 'mailing_list' => innerPayload['l']}
|
39
51
|
else
|
40
52
|
return false
|
41
53
|
end
|
data/lib/mailgun/version.rb
CHANGED
@@ -21,7 +21,7 @@ describe 'The method send_message()' do
|
|
21
21
|
:subject => 'Hash Integration Test',
|
22
22
|
:text => 'INTEGRATION TESTING',
|
23
23
|
'o:testmode' => true})
|
24
|
-
result.
|
24
|
+
result.to_h!
|
25
25
|
result.body.should include("message")
|
26
26
|
result.body.should include("id")
|
27
27
|
end
|
@@ -36,7 +36,7 @@ describe 'The method send_message()' do
|
|
36
36
|
|
37
37
|
result = @mg_obj.send_message(@domain, mb_obj)
|
38
38
|
|
39
|
-
result.
|
39
|
+
result.to_h!
|
40
40
|
result.body.should include("message")
|
41
41
|
result.body.should include("id")
|
42
42
|
end
|
@@ -63,7 +63,7 @@ Testing some Mailgun awesomness!'
|
|
63
63
|
|
64
64
|
result = @mg_obj.send_message(@domain, message_params)
|
65
65
|
|
66
|
-
result.
|
66
|
+
result.to_h!
|
67
67
|
result.body.should include("message")
|
68
68
|
result.body.should include("id")
|
69
69
|
end
|
@@ -82,7 +82,7 @@ describe 'For the domains endpoint' do
|
|
82
82
|
:smtp_password => 'super_secret',
|
83
83
|
:spam_action => 'tag'})
|
84
84
|
|
85
|
-
@result.
|
85
|
+
@result.to_h!
|
86
86
|
@result.body.should include("domain")
|
87
87
|
expect(@result.body["domain"]["name"]).to eq(@domain)
|
88
88
|
expect(@result.body["domain"]["spam_action"]).to eq("tag")
|
@@ -92,7 +92,7 @@ describe 'For the domains endpoint' do
|
|
92
92
|
it 'get the domain.' do
|
93
93
|
result = @mg_obj.get("domains/#{@domain}")
|
94
94
|
|
95
|
-
result.
|
95
|
+
result.to_h!
|
96
96
|
result.body.should include("domain")
|
97
97
|
result.body["domain"]["name"].should eq(@domain)
|
98
98
|
end
|
@@ -100,14 +100,14 @@ describe 'For the domains endpoint' do
|
|
100
100
|
it 'gets a list of domains.' do
|
101
101
|
result = @mg_obj.get("domains")
|
102
102
|
|
103
|
-
result.
|
103
|
+
result.to_h!
|
104
104
|
expect(result.body["total_count"]).to be > 0
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'deletes a domain.' do
|
108
108
|
result = @mg_obj.delete("domains/#{@domain}")
|
109
109
|
|
110
|
-
result.
|
110
|
+
result.to_h!
|
111
111
|
expect(result.body["message"]).to eq("Domain has been deleted")
|
112
112
|
end
|
113
113
|
|
@@ -131,7 +131,7 @@ describe 'For the Unsubscribes endpoint' do
|
|
131
131
|
{:address => @email,
|
132
132
|
:tag => '*'})
|
133
133
|
|
134
|
-
@result.
|
134
|
+
@result.to_h!
|
135
135
|
expect(@result.body["message"]).to eq("Address has been added to the unsubscribes table")
|
136
136
|
expect(@result.body["address"]).to eq(@email)
|
137
137
|
end
|
@@ -139,7 +139,7 @@ describe 'For the Unsubscribes endpoint' do
|
|
139
139
|
it 'get an unsubscribee.' do
|
140
140
|
result = @mg_obj.get("#{@domain}/unsubscribes/#{@email}")
|
141
141
|
|
142
|
-
result.
|
142
|
+
result.to_h!
|
143
143
|
expect(result.body["total_count"]).to eq 1
|
144
144
|
expect(result.body["items"][0]["address"]).to eq(@email)
|
145
145
|
end
|
@@ -147,7 +147,7 @@ describe 'For the Unsubscribes endpoint' do
|
|
147
147
|
it 'gets a list of unsubscribes.' do
|
148
148
|
result = @mg_obj.get("#{@domain}/unsubscribes")
|
149
149
|
|
150
|
-
result.
|
150
|
+
result.to_h!
|
151
151
|
expect(result.body["total_count"]).to be > 0
|
152
152
|
end
|
153
153
|
|
@@ -173,7 +173,7 @@ describe 'For the Complaints endpoint' do
|
|
173
173
|
@email = "integration-test-#{random_number}@example.com"
|
174
174
|
@result = @mg_obj.post("#{@domain}/complaints", {:address => @email})
|
175
175
|
|
176
|
-
@result.
|
176
|
+
@result.to_h!
|
177
177
|
expect(@result.body["message"]).to eq("Address has been added to the complaints table")
|
178
178
|
expect(@result.body["address"]).to eq(@email)
|
179
179
|
end
|
@@ -181,7 +181,7 @@ describe 'For the Complaints endpoint' do
|
|
181
181
|
it 'get a complaint.' do
|
182
182
|
result = @mg_obj.get("#{@domain}/complaints/#{@email}")
|
183
183
|
|
184
|
-
result.
|
184
|
+
result.to_h!
|
185
185
|
expect(result.body["complaint"]["count"]).to eq 1
|
186
186
|
expect(result.body["complaint"]["address"]).to eq(@email)
|
187
187
|
end
|
@@ -189,7 +189,7 @@ describe 'For the Complaints endpoint' do
|
|
189
189
|
it 'gets a list of complaints.' do
|
190
190
|
result = @mg_obj.get("#{@domain}/complaints")
|
191
191
|
|
192
|
-
result.
|
192
|
+
result.to_h!
|
193
193
|
expect(result.body["total_count"]).to be > 0
|
194
194
|
end
|
195
195
|
|
@@ -218,7 +218,7 @@ describe 'For the Bounces endpoint' do
|
|
218
218
|
:code => 550,
|
219
219
|
:error => "Integration Test"})
|
220
220
|
|
221
|
-
@result.
|
221
|
+
@result.to_h!
|
222
222
|
expect(@result.body["message"]).to eq("Address has been added to the bounces table")
|
223
223
|
expect(@result.body["address"]).to eq(@email)
|
224
224
|
end
|
@@ -226,7 +226,7 @@ describe 'For the Bounces endpoint' do
|
|
226
226
|
it 'get a bounce.' do
|
227
227
|
result = @mg_obj.get("#{@domain}/bounces/#{@email}")
|
228
228
|
|
229
|
-
result.
|
229
|
+
result.to_h!
|
230
230
|
expect(result.body["bounce"]["code"]).to eq("550")
|
231
231
|
expect(result.body["bounce"]["address"]).to eq(@email)
|
232
232
|
expect(result.body["bounce"]["error"]).to eq("Integration Test")
|
@@ -235,7 +235,7 @@ describe 'For the Bounces endpoint' do
|
|
235
235
|
it 'gets a list of bounces.' do
|
236
236
|
result = @mg_obj.get("#{@domain}/bounces")
|
237
237
|
|
238
|
-
result.
|
238
|
+
result.to_h!
|
239
239
|
expect(result.body["total_count"]).to be > 0
|
240
240
|
end
|
241
241
|
|
@@ -276,7 +276,7 @@ describe 'For the Events endpoint' do
|
|
276
276
|
it 'get an event.' do
|
277
277
|
result = @mg_obj.get("#{@domain}/events", {:limit => 1})
|
278
278
|
|
279
|
-
result.
|
279
|
+
result.to_h!
|
280
280
|
expect(result.body["items"].length).to be_within(1).of(1)
|
281
281
|
expect(result.body["paging"]).to include("next")
|
282
282
|
expect(result.body["paging"]).to include("previous")
|
@@ -298,7 +298,7 @@ describe 'For the Routes endpoint' do
|
|
298
298
|
:expression => 'match_recipient(".*@example.com")',
|
299
299
|
:action => 'forward("alice@example.com")'})
|
300
300
|
|
301
|
-
result.
|
301
|
+
result.to_h!
|
302
302
|
expect(result.body["message"]).to eq("Route has been created")
|
303
303
|
expect(result.body["route"]["description"]).to eq("Integration Test Route")
|
304
304
|
expect(result.body["route"]["actions"]).to include('forward("alice@example.com")')
|
@@ -311,7 +311,7 @@ describe 'For the Routes endpoint' do
|
|
311
311
|
it 'get the route.' do
|
312
312
|
result = @mg_obj.get("routes/#{@route_id}")
|
313
313
|
|
314
|
-
result.
|
314
|
+
result.to_h!
|
315
315
|
expect(result.body["route"]["description"]).to eq("Integration Test Route")
|
316
316
|
expect(result.body["route"]["actions"]).to include('forward("alice@example.com")')
|
317
317
|
expect(result.body["route"]["expression"]).to include('match_recipient(".*@example.com")')
|
@@ -321,7 +321,7 @@ describe 'For the Routes endpoint' do
|
|
321
321
|
it 'gets a list of all routes.' do
|
322
322
|
result = @mg_obj.get("routes", {:limit => 50})
|
323
323
|
|
324
|
-
result.
|
324
|
+
result.to_h!
|
325
325
|
expect(result.body["total_count"]).to be > 0
|
326
326
|
end
|
327
327
|
|
@@ -331,7 +331,7 @@ describe 'For the Routes endpoint' do
|
|
331
331
|
:expression => 'match_recipient(".*@example.com")',
|
332
332
|
:action => 'forward("update@example.com")'})
|
333
333
|
|
334
|
-
result.
|
334
|
+
result.to_h!
|
335
335
|
expect(result.body["message"]).to eq("Route has been updated")
|
336
336
|
expect(result.body["description"]).to eq("Integration Test Route Update")
|
337
337
|
expect(result.body["actions"]).to include('forward("update@example.com")')
|
@@ -358,7 +358,7 @@ describe 'For the campaigns endpoint' do
|
|
358
358
|
result = @mg_obj.post("#{@domain}/campaigns", {:name => 'My Campaign',
|
359
359
|
:id => @campaign_id})
|
360
360
|
|
361
|
-
result.
|
361
|
+
result.to_h!
|
362
362
|
expect(result.body["message"]).to eq("Campaign created")
|
363
363
|
expect(result.body["campaign"]["id"]).to eq(@campaign_id)
|
364
364
|
expect(result.body["campaign"]["name"]).to eq('My Campaign')
|
@@ -367,7 +367,7 @@ describe 'For the campaigns endpoint' do
|
|
367
367
|
it 'get a campaign.' do
|
368
368
|
result = @mg_obj.get("#{@domain}/campaigns/#{@campaign_id}")
|
369
369
|
|
370
|
-
result.
|
370
|
+
result.to_h!
|
371
371
|
expect(result.body["id"]).to eq(@campaign_id)
|
372
372
|
expect(result.body["name"]).to eq('My Campaign')
|
373
373
|
end
|
@@ -375,7 +375,7 @@ describe 'For the campaigns endpoint' do
|
|
375
375
|
it 'gets a list of all campaigns.' do
|
376
376
|
result = @mg_obj.get("#{@domain}/campaigns", {:limit => 50})
|
377
377
|
|
378
|
-
result.
|
378
|
+
result.to_h!
|
379
379
|
expect(result.body["total_count"]).to be > 0
|
380
380
|
end
|
381
381
|
|
@@ -383,7 +383,7 @@ describe 'For the campaigns endpoint' do
|
|
383
383
|
result = @mg_obj.put("#{@domain}/campaigns/#{@campaign_id}", {:name => 'My Updated Campaign',
|
384
384
|
:id => @campaign_id})
|
385
385
|
|
386
|
-
result.
|
386
|
+
result.to_h!
|
387
387
|
expect(result.body["message"]).to eq("Campaign updated")
|
388
388
|
expect(result.body["campaign"]["id"]).to eq(@campaign_id)
|
389
389
|
expect(result.body["campaign"]["name"]).to eq('My Updated Campaign')
|
@@ -419,7 +419,7 @@ describe 'For the webhooks endpoint' do
|
|
419
419
|
result = @mg_obj.post("domains/#{@domain}/webhooks", {:id => 'bounce',
|
420
420
|
:url => 'http://example.com/mailgun/events/bounce'})
|
421
421
|
|
422
|
-
result.
|
422
|
+
result.to_h!
|
423
423
|
expect(result.body["message"]).to eq("Webhook has been created")
|
424
424
|
expect(result.body["webhook"]["url"]).to eq('http://example.com/mailgun/events/bounce')
|
425
425
|
end
|
@@ -427,14 +427,14 @@ describe 'For the webhooks endpoint' do
|
|
427
427
|
it 'get a webhook.' do
|
428
428
|
result = @mg_obj.get("domains/#{@domain}/webhooks/bounce")
|
429
429
|
|
430
|
-
result.
|
430
|
+
result.to_h!
|
431
431
|
expect(result.body["webhook"]["url"]).to eq('http://example.com/mailgun/events/bounce')
|
432
432
|
end
|
433
433
|
|
434
434
|
it 'gets a list of all webhooks.' do
|
435
435
|
result = @mg_obj.get("domains/#{@domain}/webhooks")
|
436
436
|
|
437
|
-
result.
|
437
|
+
result.to_h!
|
438
438
|
expect(result.body["webhooks"]["bounce"]["url"]).to eq('http://example.com/mailgun/events/bounce')
|
439
439
|
end
|
440
440
|
|
@@ -442,7 +442,7 @@ describe 'For the webhooks endpoint' do
|
|
442
442
|
result = @mg_obj.put("domains/#{@domain}/webhooks/bounce", {:id => 'bounce',
|
443
443
|
:url => 'http://example.com/mailgun/events/new_bounce'})
|
444
444
|
|
445
|
-
result.
|
445
|
+
result.to_h!
|
446
446
|
expect(result.body["message"]).to eq("Webhook has been updated")
|
447
447
|
expect(result.body["webhook"]["url"]).to eq('http://example.com/mailgun/events/new_bounce')
|
448
448
|
end
|
@@ -472,7 +472,7 @@ describe 'For the Mailing Lists endpoint' do
|
|
472
472
|
:description => 'This list should be deleted automatically.',
|
473
473
|
:access_level => 'members'})
|
474
474
|
|
475
|
-
result.
|
475
|
+
result.to_h!
|
476
476
|
expect(result.body["message"]).to eq("Mailing list has been created")
|
477
477
|
expect(result.body["list"]["address"]).to eq(@ml_address)
|
478
478
|
expect(result.body["list"]["name"]).to eq('Integration Test List')
|
@@ -481,7 +481,7 @@ describe 'For the Mailing Lists endpoint' do
|
|
481
481
|
it 'get a list.' do
|
482
482
|
result = @mg_obj.get("lists/#{@ml_address}")
|
483
483
|
|
484
|
-
result.
|
484
|
+
result.to_h!
|
485
485
|
expect(result.body["list"]["address"]).to eq(@ml_address)
|
486
486
|
expect(result.body["list"]["name"]).to eq('Integration Test List')
|
487
487
|
end
|
@@ -489,7 +489,7 @@ describe 'For the Mailing Lists endpoint' do
|
|
489
489
|
it 'gets a list of all lists.' do
|
490
490
|
result = @mg_obj.get("lists", {:limit => 50})
|
491
491
|
|
492
|
-
result.
|
492
|
+
result.to_h!
|
493
493
|
expect(result.body["total_count"]).to be > 0
|
494
494
|
end
|
495
495
|
|
@@ -500,7 +500,7 @@ describe 'For the Mailing Lists endpoint' do
|
|
500
500
|
:description => 'This list should be deleted automatically.',
|
501
501
|
:access_level => 'readonly'})
|
502
502
|
|
503
|
-
result.
|
503
|
+
result.to_h!
|
504
504
|
expect(result.body["message"]).to eq("Mailing list has been updated")
|
505
505
|
expect(result.body["list"]["address"]).to eq(@ml_address)
|
506
506
|
expect(result.body["list"]["name"]).to eq('Integration Test List Update')
|
@@ -537,7 +537,7 @@ describe 'For the Mailing Lists Members endpoint' do
|
|
537
537
|
:subscribed => true,
|
538
538
|
:upsert => 'no'})
|
539
539
|
|
540
|
-
result.
|
540
|
+
result.to_h!
|
541
541
|
expect(result.body["message"]).to eq("Mailing list member has been created")
|
542
542
|
expect(result.body["member"]["address"]).to eq(@ml_member)
|
543
543
|
expect(result.body["member"]["name"]).to eq('Jane Doe')
|
@@ -546,7 +546,7 @@ describe 'For the Mailing Lists Members endpoint' do
|
|
546
546
|
it 'get a list member.' do
|
547
547
|
result = @mg_obj.get("lists/#{@ml_address}/members/#{@ml_member}")
|
548
548
|
|
549
|
-
result.
|
549
|
+
result.to_h!
|
550
550
|
expect(result.body["member"]["address"]).to eq(@ml_member)
|
551
551
|
expect(result.body["member"]["name"]).to eq('Jane Doe')
|
552
552
|
end
|
@@ -556,7 +556,7 @@ describe 'For the Mailing Lists Members endpoint' do
|
|
556
556
|
{:name => 'Jane Doe Update',
|
557
557
|
:subscribed => false})
|
558
558
|
|
559
|
-
result.
|
559
|
+
result.to_h!
|
560
560
|
expect(result.body["message"]).to eq("Mailing list member has been updated")
|
561
561
|
expect(result.body["member"]["address"]).to eq(@ml_member)
|
562
562
|
expect(result.body["member"]["name"]).to eq('Jane Doe Update')
|
@@ -581,7 +581,7 @@ describe 'For the Email Validation endpoint' do
|
|
581
581
|
result = @mg_obj.get("address/validate",
|
582
582
|
{:address => "test@example.com"})
|
583
583
|
|
584
|
-
result.
|
584
|
+
result.to_h!
|
585
585
|
expect(result.body["is_valid"]).to eq(false)
|
586
586
|
expect(result.body["address"]).to eq("test@example.com")
|
587
587
|
end
|
@@ -590,7 +590,7 @@ describe 'For the Email Validation endpoint' do
|
|
590
590
|
result = @mg_obj.get("address/parse",
|
591
591
|
{:addresses => "Alice <alice@example.com>,bob@example.com,example.com"})
|
592
592
|
|
593
|
-
result.
|
593
|
+
result.to_h!
|
594
594
|
expect(result.body["parsed"]).to include("Alice <alice@example.com>")
|
595
595
|
expect(result.body["parsed"]).to include("bob@example.com")
|
596
596
|
expect(result.body["unparseable"]).to include("example.com")
|
@@ -1,65 +1,73 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require
|
3
|
-
require
|
2
|
+
require 'time'
|
3
|
+
require 'json'
|
4
4
|
|
5
5
|
module Mailgun
|
6
6
|
class UnitClient
|
7
7
|
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :options, :block, :body, :code, :response
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@url = url
|
10
|
+
def initialize(endpoint, &block)
|
12
11
|
@block = block
|
13
|
-
@
|
12
|
+
@endpoint = endpoint
|
14
13
|
@body = nil
|
15
14
|
@code = nil
|
16
15
|
end
|
17
16
|
|
18
|
-
def [](
|
17
|
+
def [](endpoint, &new_block)
|
19
18
|
case
|
20
|
-
when block_given? then self.class.new(
|
21
|
-
when block then self.class.new(
|
19
|
+
when block_given? then self.class.new(endpoint, &new_block)
|
20
|
+
when block then self.class.new(endpoint, &block)
|
22
21
|
else
|
23
|
-
self.class.new(
|
22
|
+
self.class.new(endpoint)
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
26
|
+
def send_message(working_domain, data)
|
27
|
+
case data
|
28
|
+
when Hash
|
29
|
+
if data.has_key?(:message)
|
30
|
+
if data[:message].is_a?(String)
|
31
|
+
data[:message] = convert_string_to_file(data[:message])
|
32
|
+
end
|
33
|
+
post("#{working_domain}/messages.mime", data)
|
34
|
+
else
|
35
|
+
post("#{working_domain}/messages", data)
|
36
|
+
end
|
37
|
+
when MessageBuilder
|
38
|
+
post("#{working_domain}/messages", data.message)
|
39
|
+
else
|
40
|
+
raise ParameterError.new("Unknown data type for data parameter.", data)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def post(path, data)
|
28
45
|
begin
|
29
|
-
|
30
|
-
Response.new(response)
|
46
|
+
Response.new(response_generator(@endpoint))
|
31
47
|
rescue Exception => e
|
32
48
|
raise CommunicationError.new(e), e.response
|
33
49
|
end
|
34
50
|
end
|
35
51
|
|
36
|
-
def get(
|
52
|
+
def get(path, query_string = nil)
|
37
53
|
begin
|
38
|
-
|
39
|
-
|
40
|
-
response = response_generator("bounces")
|
41
|
-
else
|
42
|
-
response = response_generator("bounces")
|
43
|
-
end
|
44
|
-
Response.new(response)
|
54
|
+
Response.new(response_generator(@endpoint))
|
45
55
|
rescue Exception => e
|
46
56
|
raise CommunicationError.new(e), e.response
|
47
57
|
end
|
48
58
|
end
|
49
59
|
|
50
|
-
def put(
|
60
|
+
def put(path, data)
|
51
61
|
begin
|
52
|
-
|
53
|
-
Response.new(response)
|
62
|
+
Response.new(response_generator(@endpoint))
|
54
63
|
rescue Exception => e
|
55
64
|
raise CommunicationError.new(e), e.response
|
56
65
|
end
|
57
66
|
end
|
58
67
|
|
59
|
-
def delete()
|
68
|
+
def delete(path)
|
60
69
|
begin
|
61
|
-
|
62
|
-
Response.new(response)
|
70
|
+
Response.new(response_generator(@endpoint))
|
63
71
|
rescue Exception => e
|
64
72
|
raise CommunicationError.new(e), e.response
|
65
73
|
end
|
@@ -68,19 +76,23 @@ module Mailgun
|
|
68
76
|
private
|
69
77
|
|
70
78
|
def response_generator(resource_endpoint)
|
71
|
-
|
72
|
-
when "messages"
|
79
|
+
if resource_endpoint == "messages"
|
73
80
|
t = Time.now
|
74
81
|
id = "<#{t.to_i}.#{rand(99999999)}.5817@example.com>"
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
+
return JSON.generate({"message" => "Queued. Thank you.", "id" => id})
|
83
|
+
end
|
84
|
+
if resource_endpoint == "bounces"
|
85
|
+
return JSON.generate({"total_count" => 1, "items" => {"created_at" => "Fri, 21 Oct 2011 11:02:55 GMT", "code" => 550, "address" => "baz@example.com", "error" => "Message was not accepted -- invalid mailbox. Local mailbox baz@example.com is unavailable: user not found"}})
|
86
|
+
end
|
87
|
+
if resource_endpoint == "lists"
|
88
|
+
return JSON.generate({"member" => {"vars" => {"age" => 26}, "name" => "Foo Bar", "subscribed" => false, "address" => "bar@example.com"}, "message" => "Mailing list member has been updated"})
|
89
|
+
end
|
90
|
+
if resource_endpoint == "campaigns"
|
91
|
+
return JSON.generate({"message" => "Campaign has been deleted", "id" => "ABC123"})
|
92
|
+
end
|
93
|
+
if resource_endpoint == "events"
|
94
|
+
return JSON.generate({"items" => [], "paging" => {"next"=> "https://api.mailgun.net/v2/thisisatestdomainformailgun.com/events/W3siYiI6ICIyMDE0LTA1LTA3VDAwOjQ1OjUxLjc0MDg5MiswMDowMCIsICJlIjogIjIwMTQtMDUtMDVUMDA6NDU6NTEuNzQwOTgzKzAwOjAwIn0sIHsiYiI6ICIyMDE0LTA1LTA3VDAwOjQ1OjUxLjc0MDg5MiswMDowMCIsICJlIjogIjIwMTQtMDUtMDVUMDA6NDU6NTEuNzQwOTgzKzAwOjAwIn0sIFsiZiJdLCBudWxsLCB7ImFjY291bnQuaWQiOiAiNGU4MjMwZjYxNDc2ZDg2NzEzMDBjNDc2IiwgImRvbWFpbi5uYW1lIjogInRoaXNpc2F0ZXN0ZG9tYWluZm9ybWFpbGd1bi5jb20iLCAic2V2ZXJpdHkiOiAiTk9UIGludGVybmFsIn0sIDEwMCwgbnVsbF0=", "previous"=> "https://api.mailgun.net/v2/thisisatestdomainformailgun.com/events/W3siYiI6ICIyMDE0LTA1LTA3VDAwOjQ1OjUxLjc0MDg5MiswMDowMCIsICJlIjogIjIwMTQtMDUtMDVUMDA6NDU6NTEuNzQwOTgzKzAwOjAwIn0sIHsiYiI6ICIyMDE0LTA1LTA3VDAwOjQ1OjUxLjc0MDg5MiswMDowMCIsICJlIjogIjIwMTQtMDUtMDdUMDA6NDU6NTEuNzQxODkyKzAwOjAwIn0sIFsicCIsICJmIl0sIG51bGwsIHsiYWNjb3VudC5pZCI6ICI0ZTgyMzBmNjE0NzZkODY3MTMwMGM0NzYiLCAiZG9tYWluLm5hbWUiOiAidGhpc2lzYXRlc3Rkb21haW5mb3JtYWlsZ3VuLmNvbSIsICJzZXZlcml0eSI6ICJOT1QgaW50ZXJuYWwifSwgMTAwLCBudWxsXQ=="}})
|
82
95
|
end
|
83
|
-
self
|
84
96
|
end
|
85
97
|
end
|
86
98
|
|
@@ -89,14 +101,14 @@ module Mailgun
|
|
89
101
|
attr_accessor :body
|
90
102
|
|
91
103
|
def initialize(response)
|
92
|
-
@body = response
|
104
|
+
@body = response
|
93
105
|
end
|
94
106
|
|
95
107
|
# Return response as Ruby Hash
|
96
108
|
#
|
97
109
|
# @return [Hash] A standard Ruby Hash containing the HTTP result.
|
98
110
|
|
99
|
-
def
|
111
|
+
def to_h
|
100
112
|
begin
|
101
113
|
JSON.parse(@body)
|
102
114
|
rescue Exception => e
|
@@ -108,7 +120,7 @@ module Mailgun
|
|
108
120
|
#
|
109
121
|
# @return [Hash] A standard Ruby Hash containing the HTTP result.
|
110
122
|
|
111
|
-
def
|
123
|
+
def to_h!
|
112
124
|
begin
|
113
125
|
@body = JSON.parse(@body)
|
114
126
|
rescue Exception => e
|
@@ -139,5 +151,49 @@ module Mailgun
|
|
139
151
|
raise ParseError.new(e), e
|
140
152
|
end
|
141
153
|
end
|
154
|
+
|
155
|
+
def to_h
|
156
|
+
begin
|
157
|
+
JSON.parse(@body)
|
158
|
+
rescue Exception => e
|
159
|
+
raise ParseError.new(e), e
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Replace @body with Ruby Hash
|
164
|
+
#
|
165
|
+
# @return [Hash] A standard Ruby Hash containing the HTTP result.
|
166
|
+
|
167
|
+
def to_h!
|
168
|
+
begin
|
169
|
+
@body = JSON.parse(@body)
|
170
|
+
rescue Exception => e
|
171
|
+
raise ParseError.new(e), e
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Return response as Yaml
|
176
|
+
#
|
177
|
+
# @return [String] A string containing response as YAML
|
178
|
+
|
179
|
+
def to_y
|
180
|
+
begin
|
181
|
+
YAML::dump(JSON.parse(@body))
|
182
|
+
rescue Exception => e
|
183
|
+
raise ParseError.new(e), e
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Replace @body with YAML
|
188
|
+
#
|
189
|
+
# @return [String] A string containing response as YAML
|
190
|
+
|
191
|
+
def to_y!
|
192
|
+
begin
|
193
|
+
@body = YAML::dump(JSON.parse(@body))
|
194
|
+
rescue Exception => e
|
195
|
+
raise ParseError.new(e), e
|
196
|
+
end
|
197
|
+
end
|
142
198
|
end
|
143
199
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'The method get' do
|
4
|
+
it 'should return a proper hash of log data.' do
|
5
|
+
@mg_obj = Mailgun::UnitClient.new('events')
|
6
|
+
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
7
|
+
result = events.get()
|
8
|
+
result.body.should include("items")
|
9
|
+
result.body.should include("paging")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
describe 'The method next' do
|
15
|
+
it 'should return the next series of data.' do
|
16
|
+
@mg_obj = Mailgun::UnitClient.new('events')
|
17
|
+
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
18
|
+
result = events.next()
|
19
|
+
result.body.should include("items")
|
20
|
+
result.body.should include("paging")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'The method previous' do
|
25
|
+
it 'should return the previous series of data.' do
|
26
|
+
@mg_obj = Mailgun::UnitClient.new('events')
|
27
|
+
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
28
|
+
result = events.previous()
|
29
|
+
result.body.should include("items")
|
30
|
+
result.body.should include("paging")
|
31
|
+
end
|
32
|
+
end
|
@@ -5,7 +5,7 @@ describe 'The method generate_hash' do
|
|
5
5
|
@mailing_list = "mylist@example.com"
|
6
6
|
@secret_app_id = "mysupersecretpassword"
|
7
7
|
@recipient_address = "bob@example.com"
|
8
|
-
@precalculated_hash = "
|
8
|
+
@precalculated_hash = "eyJoIjoiMmY3ZmY1MzFlOGJmMjA0OWNhMTI3ZmU4ZTQyNjZkOTljYzhkMTdk%0AMiIsInAiOiJleUpzSWpvaWJYbHNhWE4wUUdWNFlXMXdiR1V1WTI5dElpd2lj%0AaUk2SW1KdllrQmxlR0Z0Y0d4bExtTnZcbmJTSjlcbiJ9%0A"
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'generates a web safe hash for the recipient wishing to subscribe' do
|
data/spec/unit/mailgun_spec.rb
CHANGED
@@ -1,22 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module Mailgun
|
4
|
-
class Client
|
5
|
-
def initialize(api_key, api_host="api.mailgun.net", api_version="v2")
|
6
|
-
@http_client = Mailgun::UnitClient::new(api_key, api_host, api_version)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
3
|
describe 'Mailgun instantiation' do
|
12
4
|
it 'instantiates an HttpClient object' do
|
13
|
-
expect {@mg_obj = Mailgun::
|
5
|
+
expect {@mg_obj = Mailgun::UnitClient.new("messages")}.not_to raise_error
|
14
6
|
end
|
15
7
|
end
|
16
8
|
|
17
9
|
describe 'The method send_message()' do
|
18
10
|
before(:each) do
|
19
|
-
@mg_obj = Mailgun::
|
11
|
+
@mg_obj = Mailgun::UnitClient.new("messages")
|
20
12
|
@domain = "test.com"
|
21
13
|
@list_address = "mylist@test.com"
|
22
14
|
@member_address = "subscribee@test.com"
|
@@ -38,7 +30,7 @@ describe 'The method send_message()' do
|
|
38
30
|
'text' => 'Test Data'}
|
39
31
|
result = @mg_obj.send_message("testdomain.com", data)
|
40
32
|
|
41
|
-
result.
|
33
|
+
result.to_h!
|
42
34
|
result.body.should include("message")
|
43
35
|
result.body.should include("id")
|
44
36
|
end
|
@@ -48,7 +40,7 @@ describe 'The method send_message()' do
|
|
48
40
|
'message' => 'Sample Data/mime.txt'}
|
49
41
|
result = @mg_obj.send_message("testdomain.com", data)
|
50
42
|
|
51
|
-
result.
|
43
|
+
result.to_h!
|
52
44
|
result.body.should include("message")
|
53
45
|
result.body.should include("id")
|
54
46
|
end
|
@@ -56,7 +48,7 @@ end
|
|
56
48
|
|
57
49
|
describe 'The method post()' do
|
58
50
|
before(:each) do
|
59
|
-
@mg_obj = Mailgun::
|
51
|
+
@mg_obj = Mailgun::UnitClient.new("messages")
|
60
52
|
@domain = "test.com"
|
61
53
|
end
|
62
54
|
it 'in this case, sends a simple message.' do
|
@@ -66,7 +58,7 @@ describe 'The method post()' do
|
|
66
58
|
'text' => 'Test Data'}
|
67
59
|
result = @mg_obj.post("#{@domain}/messages", data)
|
68
60
|
|
69
|
-
result.
|
61
|
+
result.to_h!
|
70
62
|
result.body.should include("message")
|
71
63
|
result.body.should include("id")
|
72
64
|
end
|
@@ -74,7 +66,7 @@ end
|
|
74
66
|
|
75
67
|
describe 'The method put()' do
|
76
68
|
before(:each) do
|
77
|
-
@mg_obj = Mailgun::
|
69
|
+
@mg_obj = Mailgun::UnitClient.new("lists")
|
78
70
|
@domain = "test.com"
|
79
71
|
@list_address = "mylist@test.com"
|
80
72
|
@member_address = "subscribee@test.com"
|
@@ -85,7 +77,7 @@ describe 'The method put()' do
|
|
85
77
|
'name' => 'Foo Bar'}
|
86
78
|
result = @mg_obj.put("lists/#{@list_address}/members#{@member_address}", data)
|
87
79
|
|
88
|
-
result.
|
80
|
+
result.to_h!
|
89
81
|
result.body.should include("member")
|
90
82
|
result.body["member"].should include("vars")
|
91
83
|
result.body["member"]["vars"].should include("age")
|
@@ -99,7 +91,7 @@ end
|
|
99
91
|
|
100
92
|
describe 'The method get()' do
|
101
93
|
before(:each) do
|
102
|
-
@mg_obj = Mailgun::
|
94
|
+
@mg_obj = Mailgun::UnitClient.new("bounces")
|
103
95
|
@domain = "test.com"
|
104
96
|
end
|
105
97
|
it 'in this case, obtains a list of bounces for the domain, limit of 5, skipping the first 10.' do
|
@@ -107,7 +99,7 @@ describe 'The method get()' do
|
|
107
99
|
'limit' => '5'}
|
108
100
|
result = @mg_obj.get("#{@domain}/bounces", query_string)
|
109
101
|
|
110
|
-
result.
|
102
|
+
result.to_h!
|
111
103
|
result.body.should include("total_count")
|
112
104
|
result.body.should include("items")
|
113
105
|
end
|
@@ -115,14 +107,14 @@ end
|
|
115
107
|
|
116
108
|
describe 'The method delete()' do
|
117
109
|
before(:each) do
|
118
|
-
@mg_obj = Mailgun::
|
110
|
+
@mg_obj = Mailgun::UnitClient.new("campaigns")
|
119
111
|
@domain = "test.com"
|
120
112
|
end
|
121
113
|
|
122
114
|
it 'issues a generic delete request.' do
|
123
115
|
result = @mg_obj.delete("#{@domain}/campaigns/ABC123")
|
124
116
|
|
125
|
-
result.
|
117
|
+
result.to_h!
|
126
118
|
result.body.should include("message")
|
127
119
|
result.body.should include("id")
|
128
120
|
end
|
@@ -1,16 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module Mailgun
|
4
|
-
class Client
|
5
|
-
def initialize(api_key, api_host="api.mailgun.net", api_version="v2")
|
6
|
-
@http_client = UnitClient::new(api_key, api_host, api_version)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
3
|
describe 'BatchMessage attribute readers' do
|
12
4
|
it 'should be readable' do
|
13
|
-
@mb_client = Mailgun::
|
5
|
+
@mb_client = Mailgun::UnitClient.new("messages")
|
14
6
|
@mb_obj = Mailgun::BatchMessage.new(@mb_client, "example.com")
|
15
7
|
@mb_obj.should respond_to(:message_ids)
|
16
8
|
@mb_obj.should respond_to(:message)
|
@@ -23,7 +15,7 @@ end
|
|
23
15
|
describe 'The instantiation of Batch Message' do
|
24
16
|
|
25
17
|
before(:each) do
|
26
|
-
@mb_client = Mailgun::
|
18
|
+
@mb_client = Mailgun::UnitClient.new("messages")
|
27
19
|
@mb_obj = Mailgun::BatchMessage.new(@mb_client, "example.com")
|
28
20
|
end
|
29
21
|
|
@@ -70,7 +62,7 @@ end
|
|
70
62
|
|
71
63
|
describe 'The method add_recipient' do
|
72
64
|
before(:each) do
|
73
|
-
@mb_client = Mailgun::
|
65
|
+
@mb_client = Mailgun::UnitClient.new("messages")
|
74
66
|
@mb_obj = Mailgun::BatchMessage.new(@mb_client, "example.com")
|
75
67
|
@address_1 = 'jane@example.com'
|
76
68
|
@variables_1 = {'first' => 'Jane', 'last' => 'Doe', 'tracking' => 'ABC123'}
|
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.0.
|
4
|
+
version: 1.0.2
|
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: 2014-
|
12
|
+
date: 2014-05-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -97,6 +97,7 @@ files:
|
|
97
97
|
- Rakefile
|
98
98
|
- Snippets.md
|
99
99
|
- lib/mailgun.rb
|
100
|
+
- lib/mailgun/events/events.rb
|
100
101
|
- lib/mailgun/exceptions/exceptions.rb
|
101
102
|
- lib/mailgun/lists/opt_in_handler.rb
|
102
103
|
- lib/mailgun/messages/batch_message.rb
|
@@ -107,6 +108,7 @@ files:
|
|
107
108
|
- spec/integration/messages/sample_data/mime.txt
|
108
109
|
- spec/spec_helper.rb
|
109
110
|
- spec/unit/connection/test_client.rb
|
111
|
+
- spec/unit/events/events_spec.rb
|
110
112
|
- spec/unit/lists/opt_in_handler_spec.rb
|
111
113
|
- spec/unit/mailgun_spec.rb
|
112
114
|
- spec/unit/messages/batch_message_spec.rb
|
@@ -147,6 +149,7 @@ test_files:
|
|
147
149
|
- spec/integration/messages/sample_data/mime.txt
|
148
150
|
- spec/spec_helper.rb
|
149
151
|
- spec/unit/connection/test_client.rb
|
152
|
+
- spec/unit/events/events_spec.rb
|
150
153
|
- spec/unit/lists/opt_in_handler_spec.rb
|
151
154
|
- spec/unit/mailgun_spec.rb
|
152
155
|
- spec/unit/messages/batch_message_spec.rb
|