postmark 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +6 -0
- data/Gemfile +1 -0
- data/README.md +18 -38
- data/VERSION +1 -1
- data/lib/postmark.rb +0 -1
- data/lib/postmark/api_client.rb +47 -0
- data/lib/postmark/mail_message_converter.rb +3 -2
- data/lib/postmark/message_extensions/mail.rb +42 -1
- data/lib/postmark/version.rb +1 -1
- data/spec/integration/account_api_client_spec.rb +6 -8
- data/spec/integration/api_client_resources_spec.rb +22 -0
- data/spec/unit/postmark/api_client_spec.rb +151 -2
- data/spec/unit/postmark/helpers/message_helper_spec.rb +13 -1
- data/spec/unit/postmark/mail_message_converter_spec.rb +35 -8
- metadata +2 -3
- data/lib/postmark/message_extensions/shared.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c414ac502ae3d54ffecc5b0d6a04a667c1a654c2
|
4
|
+
data.tar.gz: 908d808ab21e2e296464ba06e7d27e4d8af39585
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a4f9cf05ae33f8f0ca016a652cf64bf9efd2c7963c7fd48880f6ea7656247267802a3da886ee43174e8ceecdde33056d8e0339de8ca6a64473e0154ab5f6728
|
7
|
+
data.tar.gz: da5f57cc564fa14b9110b36e5bd2f6adcf6dc149ba03d092ba1affc0eef337afc3c6ee1be12a3069bc57f37e2b1f34ca177dc684ca4522c5de7f136e6a2a6add
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 1.3.0
|
4
|
+
|
5
|
+
* Add support for TrackOpens flag of the Delivery API.
|
6
|
+
* Add support for the Opens API.
|
7
|
+
* Add support for the Triggers API.
|
8
|
+
|
3
9
|
== 1.2.1
|
4
10
|
|
5
11
|
* Fixed a bug in Postmark::ApiClient causing #get_bounces to return unexpected value.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -67,7 +67,9 @@ client.deliver(from: 'sheldon@bigbangtheory.com',
|
|
67
67
|
# => {:to=>"Leonard Hofstadter <leonard@bigbangtheory.com>", :submitted_at=>"2013-05-09T02:45:16.2059023-04:00", :message_id=>"b2b268e3-6a70-xxxx-b897-49c9eb8b1d2e", :error_code=>0, :message=>"OK"}
|
68
68
|
```
|
69
69
|
|
70
|
-
## Sending an HTML message
|
70
|
+
## Sending an HTML message (with open tracking!)
|
71
|
+
|
72
|
+
Simply pass an HTML document as html_body parameter to `#deliver`. You can also enable open tracking by setting `track_opens` to `true`.
|
71
73
|
|
72
74
|
``` ruby
|
73
75
|
client.deliver(from: 'sheldon@bigbangtheory.com',
|
@@ -75,7 +77,8 @@ client.deliver(from: 'sheldon@bigbangtheory.com',
|
|
75
77
|
subject: 'Re: What, to you, is a large crowd?',
|
76
78
|
html_body: '<p>Any group big enough to trample me to death. ' \
|
77
79
|
'General rule of thumb is 36 adults or 70 ' \
|
78
|
-
'children.</p>'
|
80
|
+
'children.</p>',
|
81
|
+
track_opens: true)
|
79
82
|
# => {:to=>"Leonard Hofstadter <leonard@bigbangtheory.com>", :submitted_at=>"2013-05-09T02:51:08.8789433-04:00", :message_id=>"75c28987-564e-xxxx-b6eb-e8071873ac06", :error_code=>0, :message=>"OK"}
|
80
83
|
```
|
81
84
|
|
@@ -227,41 +230,6 @@ ruby_hash = Postmark::Inbound.to_ruby_hash(postmark_hash)
|
|
227
230
|
# => {:from=>"myUser@theirDomain.com", :from_full=>{:email=>"myUser@theirDomain.com", :name=>"John Doe"}, :to=>"451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com", :to_full=>[{:email=>"451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com", :name=>""}], :cc=>"\"Full name\" <sample.cc@emailDomain.com>, \"Another Cc\" <another.cc@emailDomain.com>", :cc_full=>[{:email=>"sample.cc@emailDomain.com", :name=>"Full name"}, {:email=>"another.cc@emailDomain.com", :name=>"Another Cc"}], :reply_to=>"myUsersReplyAddress@theirDomain.com", :subject=>"This is an inbound message", :message_id=>"22c74902-a0c1-4511-804f2-341342852c90", :date=>"Thu, 5 Apr 2012 16:59:01 +0200", :mailbox_hash=>"ahoy", :text_body=>"[ASCII]", :html_body=>"[HTML(encoded)]", :tag=>"", :headers=>[{:name=>"X-Spam-Checker-Version", :value=>"SpamAssassin 3.3.1 (2010-03-16) onrs-ord-pm-inbound1.wildbit.com"}, {:name=>"X-Spam-Status", :value=>"No"}, {:name=>"X-Spam-Score", :value=>"-0.1"}, {:name=>"X-Spam-Tests", :value=>"DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_PASS"}, {:name=>"Received-SPF", :value=>"Pass (sender SPF authorized) identity=mailfrom; client-ip=209.85.160.180; helo=mail-gy0-f180.google.com; envelope-from=myUser@theirDomain.com; receiver=451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com"}, {:name=>"DKIM-Signature", :value=>"v=1; a=rsa-sha256; c=relaxed/relaxed; d=wildbit.com; s=google; h=mime-version:reply-to:date:message-id:subject:from:to:cc :content-type; bh=cYr/+oQiklaYbBJOQU3CdAnyhCTuvemrU36WT7cPNt0=; b=QsegXXbTbC4CMirl7A3VjDHyXbEsbCUTPL5vEHa7hNkkUTxXOK+dQA0JwgBHq5C+1u iuAJMz+SNBoTqEDqte2ckDvG2SeFR+Edip10p80TFGLp5RucaYvkwJTyuwsA7xd78NKT Q9ou6L1hgy/MbKChnp2kxHOtYNOrrszY3JfQM="}, {:name=>"MIME-Version", :value=>"1.0"}, {:name=>"Message-ID", :value=>"<CAGXpo2WKfxHWZ5UFYCR3H_J9SNMG+5AXUovfEFL6DjWBJSyZaA@mail.gmail.com>"}], :attachments=>[{:name=>"myimage.png", :content=>"[BASE64-ENCODED CONTENT]", :content_type=>"image/png", :content_length=>4096}, {:name=>"mypaper.doc", :content=>"[BASE64-ENCODED CONTENT]", :content_type=>"application/msword", :content_length=>16384}]}
|
228
231
|
```
|
229
232
|
|
230
|
-
## Working with messages
|
231
|
-
|
232
|
-
Use `#get_messages` to retrieve messages (`:count` and `:offset` parameters
|
233
|
-
control pagination). Access inbound messages by passing `:inbound => true` as
|
234
|
-
a parameter.
|
235
|
-
|
236
|
-
``` ruby
|
237
|
-
client.get_messages(count: 1, offset: 0)
|
238
|
-
# => [{:message_id=>"41f03342-xxxx-xxxx-xxxx-558caedb5e82", :to=>[{"Email"=>"info@wildbit.com", "Name"=>nil}], :cc=>[], :bcc=>[], :recipients=>["info@wildbit.com"], :received_at=>"2014-01-15T16:41:22.4533537-05:00", :from=>"\"Postmark\" <support@postmarkapp.com>", :subject=>"Good Luck With The Gem", :attachments=>[]}]
|
239
|
-
```
|
240
|
-
|
241
|
-
Use `#get_message` to get details for a specific message using ID:
|
242
|
-
|
243
|
-
``` ruby
|
244
|
-
client.get_message('41f03342-xxxx-xxxx-xxxx-558caedb5e82')
|
245
|
-
# => {:text_body=>"...", :body=>"...", :message_id=>"41f03342-xxxx-xxxx-xxxx-558caedb5e82", :to=>[{"Email"=>"info@wildbit.com", "Name"=>nil}], :cc=>[], :bcc=>[], :recipients=>["info@wildbit.com"], :received_at=>"2014-01-15T16:41:22.4533537-05:00", :from=>"\"Postmark\" <support@postmarkapp.com>", :subject=>"Good Luck With The Gem", :attachments=>[]}
|
246
|
-
```
|
247
|
-
|
248
|
-
Use `#dump_message` to get the full message body:
|
249
|
-
|
250
|
-
``` ruby
|
251
|
-
client.dump_message('41f03342-xxxx-xxxx-xxxx-558caedb5e82')
|
252
|
-
# => {:body=>"..."}
|
253
|
-
```
|
254
|
-
|
255
|
-
There is also a handy `#messages` enumerator allowing you to easily manipulate big data arrays.
|
256
|
-
|
257
|
-
``` ruby
|
258
|
-
client.messages.lazy.select { |m| DateTime.parse(m[:received_at]).day.even? }.first(5)
|
259
|
-
# => [{...}, {...}]
|
260
|
-
```
|
261
|
-
|
262
|
-
You can get more details about the underlying endpoints and parameters they
|
263
|
-
accept in [Postmark Developer Docs](http://developer.postmarkapp.com/developer-messages.html).
|
264
|
-
|
265
233
|
## Working with bounces
|
266
234
|
|
267
235
|
Use `#get_bounces` to retrieve a list of bounces (use `:count` and `:offset`
|
@@ -379,7 +347,9 @@ message.deliver
|
|
379
347
|
# => #<Mail::Message:70355890541720, Multipart: false, Headers: <From: sheldon@bigbangtheory.com>, <To: leonard@bigbangtheory.com>, <Message-ID: e439fec0-4c89-475b-b3fc-eb446249a051>, <Subject: Re: Come on, Sheldon. It will be fun.>>
|
380
348
|
```
|
381
349
|
|
382
|
-
## HTML message
|
350
|
+
## HTML message (with open tracking)
|
351
|
+
|
352
|
+
Notice that we set `track_opens` field to `true`, to enable open tracking for this message.
|
383
353
|
|
384
354
|
``` ruby
|
385
355
|
require 'rubygems'
|
@@ -396,6 +366,8 @@ message = Mail.new do
|
|
396
366
|
body '<p>Any group big enough to trample me to death. General ' \
|
397
367
|
'rule of thumb is 36 adults or 70 children.</p>'
|
398
368
|
|
369
|
+
track_opens true
|
370
|
+
|
399
371
|
delivery_method Mail::Postmark, :api_key => 'your-postmark-api-key'
|
400
372
|
end
|
401
373
|
|
@@ -565,6 +537,14 @@ message.message_id
|
|
565
537
|
|
566
538
|
Postmark allows you to automatically scale your sending infrastructure with the Account API. Learn how in the [Account API Support](https://github.com/wildbit/postmark-gem/wiki/The-Account-API-Support) guide.
|
567
539
|
|
540
|
+
## The Triggers API Support
|
541
|
+
|
542
|
+
[The Triggers API](https://github.com/wildbit/postmark-gem/wiki/The-Triggers-API-Support) can be used to tell Postmark to automatically track opens for all messages with a certain tag.
|
543
|
+
|
544
|
+
## The Messages API Support
|
545
|
+
|
546
|
+
If you ever need to access your messages or their metadata (i.e. open tracking info), [the Messages API](https://github.com/wildbit/postmark-gem/wiki/The-Messages-API-support) is a great place to start.
|
547
|
+
|
568
548
|
## ActiveModel-like Interface For Bounces
|
569
549
|
|
570
550
|
To provide an interface similar to ActiveModel for bounces, the Postmark gem adds
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.3.0
|
data/lib/postmark.rb
CHANGED
@@ -13,7 +13,6 @@ require 'postmark/http_client'
|
|
13
13
|
require 'postmark/client'
|
14
14
|
require 'postmark/api_client'
|
15
15
|
require 'postmark/account_api_client'
|
16
|
-
require 'postmark/message_extensions/shared'
|
17
16
|
require 'postmark/message_extensions/mail'
|
18
17
|
require 'postmark/handlers/mail'
|
19
18
|
|
data/lib/postmark/api_client.rb
CHANGED
@@ -109,6 +109,53 @@ module Postmark
|
|
109
109
|
format_response http_client.put("bounces/#{id}/activate")["Bounce"]
|
110
110
|
end
|
111
111
|
|
112
|
+
def opens(options = {})
|
113
|
+
find_each('messages/outbound/opens', 'Opens', options)
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_opens(options = {})
|
117
|
+
_, batch = load_batch('messages/outbound/opens', 'Opens', options)
|
118
|
+
batch
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_opens_by_message_id(message_id, options ={})
|
122
|
+
_, batch = load_batch("messages/outbound/opens/#{message_id}",
|
123
|
+
'Opens',
|
124
|
+
options)
|
125
|
+
batch
|
126
|
+
end
|
127
|
+
|
128
|
+
def opens_by_message_id(message_id, options = {})
|
129
|
+
find_each("messages/outbound/opens/#{message_id}", 'Opens', options)
|
130
|
+
end
|
131
|
+
|
132
|
+
def create_trigger(type, options)
|
133
|
+
data = serialize(HashHelper.to_postmark(options))
|
134
|
+
format_response http_client.post("triggers/#{type}", data)
|
135
|
+
end
|
136
|
+
|
137
|
+
def get_trigger(type, id)
|
138
|
+
format_response http_client.get("triggers/#{type}/#{id}")
|
139
|
+
end
|
140
|
+
|
141
|
+
def update_trigger(type, id, options)
|
142
|
+
data = serialize(HashHelper.to_postmark(options))
|
143
|
+
format_response http_client.put("triggers/#{type}/#{id}", data)
|
144
|
+
end
|
145
|
+
|
146
|
+
def delete_trigger(type, id)
|
147
|
+
format_response http_client.delete("triggers/#{type}/#{id}")
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_triggers(type, options = {})
|
151
|
+
_, batch = load_batch("triggers/#{type}", 'Tags', options)
|
152
|
+
batch
|
153
|
+
end
|
154
|
+
|
155
|
+
def triggers(type, options = {})
|
156
|
+
find_each("triggers/#{type}", 'Tags', options)
|
157
|
+
end
|
158
|
+
|
112
159
|
def server_info
|
113
160
|
format_response http_client.get("server")
|
114
161
|
end
|
@@ -17,7 +17,7 @@ module Postmark
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def delete_blank_fields(message_hash)
|
20
|
-
message_hash.delete_if { |k, v| v.nil? || v.empty? }
|
20
|
+
message_hash.delete_if { |k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }
|
21
21
|
end
|
22
22
|
|
23
23
|
def headers_part
|
@@ -29,7 +29,8 @@ module Postmark
|
|
29
29
|
'Bcc' => @message['bcc'].to_s,
|
30
30
|
'Subject' => @message.subject,
|
31
31
|
'Headers' => @message.export_headers,
|
32
|
-
'Tag' => @message.tag.to_s
|
32
|
+
'Tag' => @message.tag.to_s,
|
33
|
+
'TrackOpens' => !!@message.track_opens
|
33
34
|
}
|
34
35
|
end
|
35
36
|
|
@@ -1,7 +1,43 @@
|
|
1
1
|
module Mail
|
2
2
|
class Message
|
3
3
|
|
4
|
-
|
4
|
+
attr_accessor :delivered, :postmark_response
|
5
|
+
|
6
|
+
def delivered?
|
7
|
+
self.delivered
|
8
|
+
end
|
9
|
+
|
10
|
+
def tag(val = nil)
|
11
|
+
default 'TAG', val
|
12
|
+
end
|
13
|
+
|
14
|
+
def tag=(val)
|
15
|
+
header['TAG'] = val
|
16
|
+
end
|
17
|
+
|
18
|
+
def track_opens(val = nil)
|
19
|
+
default 'TRACK-OPENS', !!val
|
20
|
+
end
|
21
|
+
|
22
|
+
def track_opens=(val)
|
23
|
+
header['TRACK-OPENS'] = !!val
|
24
|
+
end
|
25
|
+
|
26
|
+
def postmark_attachments=(value)
|
27
|
+
Kernel.warn("Mail::Message#postmark_attachments= is deprecated and will " \
|
28
|
+
"be removed in the future. Please consider using the native " \
|
29
|
+
"attachments API provided by Mail library.")
|
30
|
+
@_attachments = value
|
31
|
+
end
|
32
|
+
|
33
|
+
def postmark_attachments
|
34
|
+
return [] if @_attachments.nil?
|
35
|
+
Kernel.warn("Mail::Message#postmark_attachments is deprecated and will " \
|
36
|
+
"be removed in the future. Please consider using the native " \
|
37
|
+
"attachments API provided by Mail library.")
|
38
|
+
|
39
|
+
::Postmark::MessageHelper.attachments_to_postmark(@_attachments)
|
40
|
+
end
|
5
41
|
|
6
42
|
def html?
|
7
43
|
content_type && content_type.include?('text/html')
|
@@ -45,6 +81,10 @@ module Mail
|
|
45
81
|
|
46
82
|
protected
|
47
83
|
|
84
|
+
def pack_attachment_data(data)
|
85
|
+
::Postmark::MessageHelper.encode_in_base64(data)
|
86
|
+
end
|
87
|
+
|
48
88
|
def export_native_attachments
|
49
89
|
attachments.map do |attachment|
|
50
90
|
basics = {"Name" => attachment.filename,
|
@@ -65,6 +105,7 @@ module Mail
|
|
65
105
|
cc bcc
|
66
106
|
subject tag
|
67
107
|
attachment to
|
108
|
+
track-opens
|
68
109
|
]
|
69
110
|
end
|
70
111
|
|
data/lib/postmark/version.rb
CHANGED
@@ -12,10 +12,9 @@ describe 'Account API client usage' do
|
|
12
12
|
new_sender = nil
|
13
13
|
|
14
14
|
# create & count
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
}.to change { subject.get_senders_count }.by(1)
|
15
|
+
new_sender = subject.create_sender(:name => 'Integration Test',
|
16
|
+
:from_email => unique_from_email)
|
17
|
+
expect(subject.get_senders_count).to be > 0
|
19
18
|
|
20
19
|
# get
|
21
20
|
expect(subject.get_sender(new_sender[:id])[:id]).to eq(new_sender[:id])
|
@@ -51,10 +50,9 @@ describe 'Account API client usage' do
|
|
51
50
|
new_server = nil
|
52
51
|
|
53
52
|
# create & count
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
}.to change { subject.get_servers_count }.by(1)
|
53
|
+
new_server = subject.create_server(:name => "server-#{unique_token}",
|
54
|
+
:color => 'red')
|
55
|
+
expect(subject.get_servers_count).to be > 0
|
58
56
|
|
59
57
|
# get
|
60
58
|
expect(subject.get_server(new_server[:id])[:id]).to eq(new_server[:id])
|
@@ -17,6 +17,28 @@ describe 'Accessing server resources using the API' do
|
|
17
17
|
}
|
18
18
|
}
|
19
19
|
|
20
|
+
context 'Triggers API' do
|
21
|
+
|
22
|
+
let(:unique_token) { rand(36**32).to_s(36) }
|
23
|
+
|
24
|
+
it 'can be used to manage tag triggers via the API' do
|
25
|
+
trigger = api_client.create_trigger(:tags,
|
26
|
+
:match_name => "gemtest_#{unique_token}",
|
27
|
+
:track_opens => true)
|
28
|
+
api_client.update_trigger(:tags,
|
29
|
+
trigger[:id],
|
30
|
+
:match_name => "pre_#{trigger[:match_name]}")
|
31
|
+
updated = api_client.get_trigger(:tags, trigger[:id])
|
32
|
+
|
33
|
+
expect(updated[:id]).to eq(trigger[:id])
|
34
|
+
expect(updated[:match_name]).not_to eq(trigger[:id])
|
35
|
+
expect(api_client.triggers(:tags).map { |t| t[:id] }).to include(trigger[:id])
|
36
|
+
|
37
|
+
api_client.delete_trigger(:tags, trigger[:id])
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
20
42
|
context 'Messages API' do
|
21
43
|
|
22
44
|
def with_retries(max_retries = 20, wait_seconds = 3)
|
@@ -102,7 +102,7 @@ describe Postmark::ApiClient do
|
|
102
102
|
|
103
103
|
describe "#deliver_message" do
|
104
104
|
let(:email) { message.to_postmark_hash }
|
105
|
-
let(:email_json) {
|
105
|
+
let(:email_json) { Postmark::Json.encode(email) }
|
106
106
|
let(:http_client) { subject.http_client }
|
107
107
|
|
108
108
|
it 'turns message into a JSON document and posts it to /email' do
|
@@ -135,7 +135,7 @@ describe Postmark::ApiClient do
|
|
135
135
|
|
136
136
|
let(:email) { message.to_postmark_hash }
|
137
137
|
let(:emails) { [email, email, email] }
|
138
|
-
let(:emails_json) {
|
138
|
+
let(:emails_json) { Postmark::Json.encode(emails) }
|
139
139
|
let(:http_client) { subject.http_client }
|
140
140
|
let(:response) { [{}, {}, {}] }
|
141
141
|
|
@@ -391,6 +391,155 @@ describe Postmark::ApiClient do
|
|
391
391
|
end
|
392
392
|
end
|
393
393
|
|
394
|
+
describe '#opens' do
|
395
|
+
|
396
|
+
it 'returns an Enumerator' do
|
397
|
+
expect(subject.opens).to be_kind_of(Enumerable)
|
398
|
+
end
|
399
|
+
|
400
|
+
it 'performs a GET request to /opens/tags' do
|
401
|
+
allow(subject.http_client).to receive(:get).
|
402
|
+
with('messages/outbound/opens', an_instance_of(Hash)).
|
403
|
+
and_return('TotalCount' => 1, 'Opens' => [{}])
|
404
|
+
expect(subject.opens.first(5).count).to eq(1)
|
405
|
+
end
|
406
|
+
|
407
|
+
end
|
408
|
+
|
409
|
+
describe '#get_opens' do
|
410
|
+
let(:http_client) { subject.http_client }
|
411
|
+
let(:options) { {:offset => 5} }
|
412
|
+
let(:response) { {'Opens' => [], 'TotalCount' => 0} }
|
413
|
+
|
414
|
+
it 'performs a GET request to /messages/outbound/opens' do
|
415
|
+
allow(http_client).to receive(:get).with('messages/outbound/opens', options) { response }
|
416
|
+
expect(subject.get_opens(options)).to be_an(Array)
|
417
|
+
expect(subject.get_opens(options).count).to be_zero
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
describe '#get_opens_by_message_id' do
|
422
|
+
let(:http_client) { subject.http_client }
|
423
|
+
let(:message_id) { 42 }
|
424
|
+
let(:options) { {:offset => 5} }
|
425
|
+
let(:response) { {'Opens' => [], 'TotalCount' => 0} }
|
426
|
+
|
427
|
+
it 'performs a GET request to /messages/outbound/opens' do
|
428
|
+
allow(http_client).
|
429
|
+
to receive(:get).with("messages/outbound/opens/#{message_id}",
|
430
|
+
options).
|
431
|
+
and_return(response)
|
432
|
+
expect(subject.get_opens_by_message_id(message_id, options)).to be_an(Array)
|
433
|
+
expect(subject.get_opens_by_message_id(message_id, options).count).to be_zero
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
describe '#opens_by_message_id' do
|
438
|
+
let(:message_id) { 42 }
|
439
|
+
|
440
|
+
it 'returns an Enumerator' do
|
441
|
+
expect(subject.opens_by_message_id(message_id)).to be_kind_of(Enumerable)
|
442
|
+
end
|
443
|
+
|
444
|
+
it 'performs a GET request to /opens/tags' do
|
445
|
+
allow(subject.http_client).to receive(:get).
|
446
|
+
with("messages/outbound/opens/#{message_id}", an_instance_of(Hash)).
|
447
|
+
and_return('TotalCount' => 1, 'Opens' => [{}])
|
448
|
+
expect(subject.opens_by_message_id(message_id).first(5).count).to eq(1)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
describe '#create_trigger' do
|
453
|
+
let(:http_client) { subject.http_client }
|
454
|
+
let(:options) { {:foo => 'bar'} }
|
455
|
+
let(:response) { {'Foo' => 'Bar'} }
|
456
|
+
|
457
|
+
it 'performs a POST request to /triggers/tags with given options' do
|
458
|
+
allow(http_client).to receive(:post).with('triggers/tags',
|
459
|
+
{'Foo' => 'bar'}.to_json)
|
460
|
+
subject.create_trigger(:tags, options)
|
461
|
+
end
|
462
|
+
|
463
|
+
it 'symbolizes response keys' do
|
464
|
+
allow(http_client).to receive(:post).and_return(response)
|
465
|
+
expect(subject.create_trigger(:tags, options)).to eq(:foo => 'Bar')
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
describe '#get_trigger' do
|
470
|
+
let(:http_client) { subject.http_client }
|
471
|
+
let(:id) { 42 }
|
472
|
+
|
473
|
+
it 'performs a GET request to /triggers/tags/:id' do
|
474
|
+
allow(http_client).to receive(:get).with("triggers/tags/#{id}")
|
475
|
+
subject.get_trigger(:tags, id)
|
476
|
+
end
|
477
|
+
|
478
|
+
it 'symbolizes response keys' do
|
479
|
+
allow(http_client).to receive(:get).and_return('Foo' => 'Bar')
|
480
|
+
expect(subject.get_trigger(:tags, id)).to eq(:foo => 'Bar')
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
describe '#update_trigger' do
|
485
|
+
let(:http_client) { subject.http_client }
|
486
|
+
let(:options) { {:foo => 'bar'} }
|
487
|
+
let(:id) { 42 }
|
488
|
+
|
489
|
+
it 'performs a PUT request to /triggers/tags/:id' do
|
490
|
+
allow(http_client).to receive(:put).with("triggers/tags/#{id}",
|
491
|
+
{'Foo' => 'bar'}.to_json)
|
492
|
+
subject.update_trigger(:tags, id, options)
|
493
|
+
end
|
494
|
+
|
495
|
+
it 'symbolizes response keys' do
|
496
|
+
allow(http_client).to receive(:put).and_return('Foo' => 'Bar')
|
497
|
+
expect(subject.update_trigger(:tags, id, options)).to eq(:foo => 'Bar')
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
describe '#delete_trigger' do
|
502
|
+
let(:http_client) { subject.http_client }
|
503
|
+
let(:id) { 42 }
|
504
|
+
|
505
|
+
it 'performs a DELETE request to /triggers/tags/:id' do
|
506
|
+
allow(http_client).to receive(:delete).with("triggers/tags/#{id}")
|
507
|
+
subject.delete_trigger(:tags, id)
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'symbolizes response keys' do
|
511
|
+
allow(http_client).to receive(:delete).and_return('Foo' => 'Bar')
|
512
|
+
expect(subject.delete_trigger(:tags, id)).to eq(:foo => 'Bar')
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
describe '#get_triggers' do
|
517
|
+
let(:http_client) { subject.http_client }
|
518
|
+
let(:options) { {:offset => 5} }
|
519
|
+
let(:response) { {'Tags' => [], 'TotalCount' => 0} }
|
520
|
+
|
521
|
+
it 'performs a GET request to /triggers/tags' do
|
522
|
+
allow(http_client).to receive(:get).with('triggers/tags', options) { response }
|
523
|
+
expect(subject.get_triggers(:tags, options)).to be_an(Array)
|
524
|
+
expect(subject.get_triggers(:tags, options).count).to be_zero
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
describe '#triggers' do
|
529
|
+
|
530
|
+
it 'returns an Enumerator' do
|
531
|
+
expect(subject.triggers(:tags)).to be_kind_of(Enumerable)
|
532
|
+
end
|
533
|
+
|
534
|
+
it 'performs a GET request to /triggers/tags' do
|
535
|
+
allow(subject.http_client).to receive(:get).
|
536
|
+
with('triggers/tags', an_instance_of(Hash)).
|
537
|
+
and_return('TotalCount' => 1, 'Tags' => [{}])
|
538
|
+
expect(subject.triggers(:tags).first(5).count).to eq(1)
|
539
|
+
end
|
540
|
+
|
541
|
+
end
|
542
|
+
|
394
543
|
describe "#server_info" do
|
395
544
|
let(:http_client) { subject.http_client }
|
396
545
|
let(:response) { {"Name" => "Testing",
|
@@ -56,7 +56,7 @@ describe Postmark::MessageHelper do
|
|
56
56
|
"Tag" => "Invitation",
|
57
57
|
"HtmlBody" => "<b>Hello</b>",
|
58
58
|
"TextBody" => "Hello",
|
59
|
-
"ReplyTo" => "reply@example.com"
|
59
|
+
"ReplyTo" => "reply@example.com",
|
60
60
|
}
|
61
61
|
}
|
62
62
|
|
@@ -76,6 +76,14 @@ describe Postmark::MessageHelper do
|
|
76
76
|
postmark_message_with_headers.merge("Attachments" => postmark_attachments)
|
77
77
|
}
|
78
78
|
|
79
|
+
let(:message_with_open_tracking) {
|
80
|
+
message.merge(:track_opens => true)
|
81
|
+
}
|
82
|
+
|
83
|
+
let(:postmark_message_with_open_tracking) {
|
84
|
+
postmark_message.merge("TrackOpens" => true)
|
85
|
+
}
|
86
|
+
|
79
87
|
it 'converts messages without custom headers and attachments correctly' do
|
80
88
|
subject.to_postmark(message).should == postmark_message
|
81
89
|
end
|
@@ -88,6 +96,10 @@ describe Postmark::MessageHelper do
|
|
88
96
|
subject.to_postmark(message_with_headers_and_attachments).should == postmark_message_with_headers_and_attachments
|
89
97
|
end
|
90
98
|
|
99
|
+
it 'includes open tracking flag when specified' do
|
100
|
+
expect(subject.to_postmark(message_with_open_tracking)).to eq(postmark_message_with_open_tracking)
|
101
|
+
end
|
102
|
+
|
91
103
|
end
|
92
104
|
|
93
105
|
describe ".headers_to_postmark" do
|
@@ -23,6 +23,17 @@ describe Postmark::MailMessageConverter do
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
let(:mail_message_with_tracking) do
|
27
|
+
mail = Mail.new do
|
28
|
+
from "sheldon@bigbangtheory.com"
|
29
|
+
to "lenard@bigbangtheory.com"
|
30
|
+
subject "Hello!"
|
31
|
+
content_type 'text/html; charset=UTF-8'
|
32
|
+
body "<b>Hello Sheldon!</b>"
|
33
|
+
track_opens true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
26
37
|
|
27
38
|
let(:tagged_mail_message) do
|
28
39
|
Mail.new do
|
@@ -72,7 +83,7 @@ describe Postmark::MailMessageConverter do
|
|
72
83
|
to "\"Leonard Hofstadter\" <leonard@bigbangtheory.com>"
|
73
84
|
subject "Hello!"
|
74
85
|
body "Hello Sheldon!"
|
75
|
-
reply_to 'Penny
|
86
|
+
reply_to '"Penny The Neighbor" <penny@bigbangtheory.com>'
|
76
87
|
end
|
77
88
|
end
|
78
89
|
|
@@ -81,7 +92,8 @@ describe Postmark::MailMessageConverter do
|
|
81
92
|
"From" => "sheldon@bigbangtheory.com",
|
82
93
|
"Subject" => "Hello!",
|
83
94
|
"TextBody" => "Hello Sheldon!",
|
84
|
-
"To" => "lenard@bigbangtheory.com"
|
95
|
+
"To" => "lenard@bigbangtheory.com",
|
96
|
+
'TrackOpens' => false}
|
85
97
|
end
|
86
98
|
|
87
99
|
it 'converts tagged text messages correctly' do
|
@@ -90,14 +102,16 @@ describe Postmark::MailMessageConverter do
|
|
90
102
|
"Subject" => "Hello!",
|
91
103
|
"TextBody" => "Hello Sheldon!",
|
92
104
|
"Tag" => "sheldon",
|
93
|
-
"To"=>"lenard@bigbangtheory.com"
|
105
|
+
"To"=>"lenard@bigbangtheory.com",
|
106
|
+
'TrackOpens' => false}
|
94
107
|
end
|
95
108
|
|
96
109
|
it 'converts plain text messages without body correctly' do
|
97
110
|
subject.new(mail_message_without_body).run.should == {
|
98
111
|
"From" => "sheldon@bigbangtheory.com",
|
99
112
|
"Subject" => "Hello!",
|
100
|
-
"To" => "lenard@bigbangtheory.com"
|
113
|
+
"To" => "lenard@bigbangtheory.com",
|
114
|
+
'TrackOpens' => false}
|
101
115
|
end
|
102
116
|
|
103
117
|
it 'converts html messages correctly' do
|
@@ -105,7 +119,8 @@ describe Postmark::MailMessageConverter do
|
|
105
119
|
"From" => "sheldon@bigbangtheory.com",
|
106
120
|
"Subject" => "Hello!",
|
107
121
|
"HtmlBody" => "<b>Hello Sheldon!</b>",
|
108
|
-
"To" => "lenard@bigbangtheory.com"
|
122
|
+
"To" => "lenard@bigbangtheory.com",
|
123
|
+
'TrackOpens' => false}
|
109
124
|
end
|
110
125
|
|
111
126
|
it 'converts multipart messages correctly' do
|
@@ -114,7 +129,8 @@ describe Postmark::MailMessageConverter do
|
|
114
129
|
"Subject" => "Hello!",
|
115
130
|
"HtmlBody" => "<b>Hello Sheldon!</b>",
|
116
131
|
"TextBody" => "Hello Sheldon!",
|
117
|
-
"To" => "lenard@bigbangtheory.com"
|
132
|
+
"To" => "lenard@bigbangtheory.com",
|
133
|
+
'TrackOpens' => false}
|
118
134
|
end
|
119
135
|
|
120
136
|
it 'converts messages with attachments correctly' do
|
@@ -125,7 +141,8 @@ describe Postmark::MailMessageConverter do
|
|
125
141
|
"Content"=>encoded_empty_gif_data,
|
126
142
|
"ContentType"=>"image/gif"}],
|
127
143
|
"TextBody"=>"Hello Sheldon!",
|
128
|
-
"To"=>"lenard@bigbangtheory.com"
|
144
|
+
"To"=>"lenard@bigbangtheory.com",
|
145
|
+
'TrackOpens' => false}
|
129
146
|
end
|
130
147
|
|
131
148
|
it 'converts messages with named addresses correctly' do
|
@@ -134,10 +151,20 @@ describe Postmark::MailMessageConverter do
|
|
134
151
|
"Subject" => "Hello!",
|
135
152
|
"TextBody" => "Hello Sheldon!",
|
136
153
|
"To" => "Leonard Hofstadter <leonard@bigbangtheory.com>",
|
137
|
-
"ReplyTo" =>
|
154
|
+
"ReplyTo" => 'Penny The Neighbor <penny@bigbangtheory.com>',
|
155
|
+
'TrackOpens' => false
|
138
156
|
}
|
139
157
|
end
|
140
158
|
|
159
|
+
it 'recognizes when open tracking is enabled' do
|
160
|
+
subject.new(mail_message_with_tracking).run.should == {
|
161
|
+
"From" => "sheldon@bigbangtheory.com",
|
162
|
+
"Subject" => "Hello!",
|
163
|
+
"HtmlBody" => "<b>Hello Sheldon!</b>",
|
164
|
+
"To" => "lenard@bigbangtheory.com",
|
165
|
+
"TrackOpens" => true}
|
166
|
+
end
|
167
|
+
|
141
168
|
context 'when bcc is empty' do
|
142
169
|
it 'excludes bcc from message' do
|
143
170
|
mail_message.bcc = nil
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postmark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Petyo Ivanov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-05
|
13
|
+
date: 2014-06-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
@@ -117,7 +117,6 @@ files:
|
|
117
117
|
- lib/postmark/json.rb
|
118
118
|
- lib/postmark/mail_message_converter.rb
|
119
119
|
- lib/postmark/message_extensions/mail.rb
|
120
|
-
- lib/postmark/message_extensions/shared.rb
|
121
120
|
- lib/postmark/response_parsers/active_support.rb
|
122
121
|
- lib/postmark/response_parsers/json.rb
|
123
122
|
- lib/postmark/response_parsers/yajl.rb
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Postmark
|
2
|
-
module SharedMessageExtensions
|
3
|
-
|
4
|
-
def self.included(klass)
|
5
|
-
klass.instance_eval do
|
6
|
-
attr_accessor :delivered, :postmark_response
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def delivered?
|
11
|
-
self.delivered
|
12
|
-
end
|
13
|
-
|
14
|
-
def tag(val = nil)
|
15
|
-
default 'TAG', val
|
16
|
-
end
|
17
|
-
|
18
|
-
def tag=(val)
|
19
|
-
header['TAG'] = val
|
20
|
-
end
|
21
|
-
|
22
|
-
def postmark_attachments=(value)
|
23
|
-
Kernel.warn("Mail::Message#postmark_attachments= is deprecated and will " \
|
24
|
-
"be removed in the future. Please consider using the native " \
|
25
|
-
"attachments API provided by Mail library.")
|
26
|
-
@_attachments = value
|
27
|
-
end
|
28
|
-
|
29
|
-
def postmark_attachments
|
30
|
-
return [] if @_attachments.nil?
|
31
|
-
Kernel.warn("Mail::Message#postmark_attachments is deprecated and will " \
|
32
|
-
"be removed in the future. Please consider using the native " \
|
33
|
-
"attachments API provided by Mail library.")
|
34
|
-
|
35
|
-
Postmark::MessageHelper.attachments_to_postmark(@_attachments)
|
36
|
-
end
|
37
|
-
|
38
|
-
protected
|
39
|
-
|
40
|
-
def pack_attachment_data(data)
|
41
|
-
MessageHelper.encode_in_base64(data)
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|