Skip to content

Using Postmark with Mail library

tomazy edited this page Apr 8, 2020 · 6 revisions

You can use Postmark with the mail gem.

gem install mail

Make sure you have a sender signature for every From email address you specify.

To send a Mail::Message via Postmark you’ll need to specify Mail::Postmark as a delivery method for the message:

message = Mail.new do
  # ...
  delivery_method Mail::Postmark, api_token: 'your-server-token'
end

Delivery method accepts all options supported by Postmark::ApiClient documented above. A new instance of Postmark::ApiClient is created every time you deliver a message to preserve thread safety.

If you would prefer to use Postmark as the default delivery method for all Mail::Message instances, you can call Mail.defaults method during the initialization step of your app:

Mail.defaults do
  delivery_method Mail::Postmark, api_token: 'your-server-token'
end

Check out couple of examples of Mail library usage with Postmark.

Plain text message

require 'rubygems'
require 'postmark'
require 'mail'
require 'json'

message = Mail.new do
  from            '[email protected]'
  to              'Leonard Hofstadter <[email protected]>'
  subject         'Re: Come on, Sheldon. It will be fun.'
  body            'That\'s what you said about the Green Lantern movie. You' \
                  'were 114 minutes of wrong.'
  message_stream  'outbound' # optional

  delivery_method Mail::Postmark, :api_token => 'your-postmark-api-token'
end

message.deliver

# => #<Mail::Message:70355890541720, Multipart: false, Headers: <From: [email protected]>, <To: [email protected]>, <Message-ID: e439fec0-4c89-475b-b3fc-eb446249a051>, <Subject: Re: Come on, Sheldon. It will be fun.>>

HTML message (with open tracking)

Notice that we set track_opens field to true, to enable open tracking for this message.

require 'rubygems'
require 'postmark'
require 'mail'
require 'json'

message = Mail.new do
  from            '[email protected]'
  to              'Leonard Hofstadter <[email protected]>'
  subject         'Re: What, to you, is a large crowd?'

  content_type    'text/html; charset=UTF-8'
  body            '<p>Any group big enough to trample me to death. General ' \
                  'rule of thumb is 36 adults or 70 children.</p>'

  track_opens     true 

  delivery_method Mail::Postmark, :api_token => 'your-postmark-api-token'
end

message.deliver

# => #<Mail::Message:70355902117460, Multipart: false, Headers: <From: [email protected]>, <To: [email protected]>, <Message-ID: 3a9370a2-6c24-4304-a03c-320a54cc59f7>, <Subject: Re: What, to you, is a large crowd?>, <Content-Type: text/html; charset=UTF-8>>

Multipart message (with link tracking)

Notice that we set track_links field to :html_and_text, to enable link tracking for both plain text and html parts for this message.

require 'rubygems'
require 'postmark'
require 'mail'
require 'json'

message = Mail.new do
  from            '[email protected]'
  to              'Leonard Hofstadter <[email protected]>'
  subject         'Re: What, to you, is a large crowd?'

  text_part do
    body          'Any group big enough to trample me to death. General rule of thumb is 36 adults or 70 children - http://www.example.com.'
  end

  html_part do
    content_type  'text/html; charset=UTF-8'
    body          '<p>Any group big enough to trample me to death. ' \
                  'General <a href="http://www.example.com">rule of thumb</a> is 36 adults or 70 ' \
                  'children.</p>'
  end

  track_links     :html_and_text

  delivery_method Mail::Postmark, :api_token => 'your-postmark-api-token'
end

message.deliver

# => #<Mail::Message:70355902117460, Multipart: true, Headers: <From: [email protected]>, <To: [email protected]>, <Message-ID: 1a1370a1-6c21-4304-a03c-320a54cc59f7>, <Subject: Re: What, to you, is a large crowd?>, <Content-Type: multipart/alternative; boundary=--==_mimepart_58380d6029b17_20543fd48543fa14977a>, <TRACK-LINKS: HtmlAndText>>

Message with metadata

message = Mail.new do
  from            '[email protected]'
  to              'Dr. Sheldon Cooper <[email protected]>'
  subject         'Have you seen these pictures of yours?'
  body            'You look like a real geek!'
  add_file        '1.jpeg'
  metadata        {"Example1"=>"value","Example2"=>"value"}

  delivery_method Mail::Postmark, :api_token => 'your-postmark-api-token'
end

message.deliver

# => #<Mail::Message:70185826686240, Multipart: true, Headers: <From: [email protected]>, <To: [email protected]>, <Message-ID: ba644cc1-b5b1-4bcb-aaf8-2f290b5aad80>, <Subject: Have you seen these pictures of yours?>, <Content-Type: multipart/mixed; boundary=--==_mimepart_5121f9f1ec653_12c53fd569035ad817726>>

Message with attachments

message = Mail.new do
  from            '[email protected]'
  to              'Dr. Sheldon Cooper <[email protected]>'
  subject         'Have you seen these pictures of yours?'
  body            'You look like a real geek!'
  add_file        '1.jpeg'

  delivery_method Mail::Postmark, :api_token => 'your-postmark-api-token'
end

message.attachments['sheldon.jpeg'] = File.read('2.jpeg')

message.deliver

# => #<Mail::Message:70185826686240, Multipart: true, Headers: <From: [email protected]>, <To: [email protected]>, <Message-ID: ba644cc1-b5b1-4bcb-aaf8-2f290b5aad80>, <Subject: Have you seen these pictures of yours?>, <Content-Type: multipart/mixed; boundary=--==_mimepart_5121f9f1ec653_12c53fd569035ad817726>>

Multipart message

You can send multipart messages containing both text and HTML using the Postmark gem.

require 'rubygems'
require 'postmark'
require 'mail'
require 'json'

message = Mail.new do
  from            '[email protected]'
  to              'Leonard Hofstadter <[email protected]>'
  subject         'Re: Anything Can Happen Thursday'
  delivery_method Mail::Postmark, :api_token => 'your-postmark-api-token'

  text_part do
    body          'Apparently the news didn\'t reach my digestive system,' \
                  ' which when startled has it\'s own version of "Anything' \
                  ' Can Happen Thursday"'
  end

  html_part do
    content_type  'text/html; charset=UTF-8'
    body          '<p>Apparently the news didn&rsquo;t reach my digestive ' \
                  'system, which when startled has it&rsquo;s own version ' \
                  'of &ldquo;Anything Can Happen Thursday&rdquo;</p>'
  end
end

message.deliver
# => #<Mail::Message:70355901588620, Multipart: true, Headers: <From: [email protected]>, <To: [email protected]>, <Message-ID: cadba131-f6d6-4cfc-9892-16ee738ba54c>, <Subject: Re: Anything Can Happen Thursday>, <Content-Type: multipart/alternative; boundary=--==_mimepart_50ef7a6234a69_a4c73ffd01035adc207b8>>

Sending in batches

You can also send Mail::Message objects in batches. Create an instance of Postmark::ApiClient as described in "Communicating with the API" section.

messages = []

messages << Mail.new do
  from            '[email protected]'
  to              'Leonard Hofstadter <[email protected]>'
  subject         'Re: Come on, Sheldon. It will be fun.'
  body            'That\'s what you said about the Green Lantern movie. You' \
                  'were 114 minutes of wrong.'
end

messages << Mail.new do
  from           '[email protected]'
  to             'Penny <[email protected]>'
  subject        'Re: You cleaned my apartment???'
  body           'I couldn\'t sleep knowing that just outside my bedroom is ' \
                 'our living room and just outside our living room is that ' \
                 'hallway and immediately adjacent to that hallway is this!'
  tag            'confidential'
end

client.deliver_messages(messages)
# => [{:to=>"[email protected]", :submitted_at=>"2013-05-10T01:59:29.830486-04:00", :message_id=>"8ad0e8b0-xxxx-xxxx-951d-223c581bb467", :error_code=>0, :message=>"OK"}, {:to=>"[email protected]", :submitted_at=>"2013-05-10T01:59:29.830486-04:00", :message_id=>"33c6240c-xxxx-xxxx-b0df-40bdfcf4e0f7", :error_code=>0, :message=>"OK"}]

After delivering a batch you can check on each message’s delivery status:

messages.first.delivered?
# => true

messages.all?(&:delivered)
# => true