postmark 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.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
|