WireMail Postmark API
Extends WireMail to use the Postmark API for sending emails.
Installation- Download the zip file at Github or clone the repo into your
site/modules
directory. - If you downloaded the zip file, extract it in your
sites/modules
directory. - In your admin, go to Modules > Refresh, then Modules > New, then click on the Install button for this module.
API
site/modules
directory.sites/modules
directory.Prior to using this module, you must set up a server in your Postmark account and create an API Token. You should also set up a Sender Signature. Add the API Token and Sender Signature to the module configuration.
Usage
Usage is similar to the basic WireMail implementation, although a few extra options are available. Please refer to the WireMail documentation for full instructions on using WireMail, and to the examples below.
Extra Methods
The following are extra methods implemented by this module:
Chainable
The following methods can be used in a chained statement:
setSenderSignature(string $senderSignature) - Set a different sender signature than the default.
- Must use a registered and confirmed Sender Signature.
- To include a name, use the format "Full Name <sender@domain.com>" for the address.
cc(string|array|null $email) - Set a "cc" email address.
- Only used when
$sendBatch
is set tofalse
. - Please refer to WireMail::to() for more information on how to use this method.
bcc(string|array|null $email) - Set a "bcc" email address.
- Only used when
$sendBatch
is set tofalse
. - Please refer to WireMail::to() for more information on how to use this method.
attachInlineImage(string $file, string $filename) - Add an inline image for referencing in HTML.
- Reference using "cid:" e.g.
<img src="https://raw.githubusercontent.com/nbcommunication/WireMailPostmarkApp/main/cid:filename.ext'>
setTag(string $tag) - Set the email tag.
setTrackOpens(bool $trackOpens) - Override "Track opens" module setting on a per-email basis.
- Disabled automatically for 'Forgot Password' emails from ProcessWire
setTrackLinks(bool $trackLinks) - Override "Track links" module setting on a per-email basis.
- Disabled automatically for 'Forgot Password' emails from ProcessWire
setMetaData(string|array $key, string $value = '') - Add custom metadata to the email.
setMessageStream(string $messageStream) - Set the message stream.
setSendBatch(bool $sendBatch) - Set the batch mode.
- This is off by default, meaning that a single email is sent with each recipient seeing the other recipients
- If this is on, any email addresses set by
cc()
andbcc()
will be ignored - Postmark has a limit on 50 email addresses per message and 500 messages per batch request. This module will split the recipients into batches if necessary and will also split up batches of messages too.
setRecipientVariables(array $variables, string $email = '') - Set the recipient variables
$variables
should be an array of data keyed by the recipient email address, or specific for a recipient specified by$email
.- Variables are only used when either
$sendBatch
or a template is being used.
setTemplate(string $template, array $variables = [], bool $inlineCss = true
) - Set the template alias or id
- You can set template variables by passing an array to
$variables
. - You can toggle the
$inlineCss
setting. More information
setTemplateVariables(array $variables) - Set the template variables.
- These are variables shared by each recipient's message
Other
getClient() - Return the Postmark client.
- For more details please see the documentation for postmark-php.
getResponse(int $index = null
) - Return the last send() response
- Returns a
Postmark\Models\DynamicResponseModel
object. - Pass an
$index
if you want to get a specific response from a batch send.
getResponses() - Return the last batch send() responses
- Returns an array of
Postmark\Models\DynamicResponseModel
objects.
send() - Send the email.
- Returns a positive number (indicating number of emails sent) or 0 on failure.
Examples
Basic Example
Send an email:
$postmark = $mail->new(); $sent = $postmark->to('user@domain.com') ->from('you@company.com') ->subject('Message Subject') ->body('Message Body') ->send();
Advanced Example
Send an email using all supported WireMail methods and extra methods implemented by WireMailPostmarkApp:
$postmark = $mail->new(); // WireMail methods $postmark->to([ 'user@domain.com' => 'A User', 'user2@domain.com' => 'Another User', ]) ->from('you@company.com', 'Company Name') ->replyTo('reply@company.com', 'Company Name') ->subject('Message Subject') ->bodyHTML( '<p>Message Body with variables: {{name}} = {{toName}} <{{toEmail}}> ({{key3}})</p>' . '<img src="https://raw.githubusercontent.com/nbcommunication/WireMailPostmarkApp/main/cid:filename-inline.jpg">' ) // A text version will be automatically created ->header('key1', 'value1') ->headers(['key2' => 'value2']) ->attachment('/path/to/file.ext', 'filename.ext'); // WireMailPostmarkApp methods $postmark->setSenderSignature('Alternate <another@company.com>') // Use a different Sender Signature ->cc('cc@domain.com') ->bcc(['bcc@domain.com', 'bcc2@domain.com']) ->attachInlineImage('/path/to/file-inline.jpg', 'filename-inline.jpg') // Add inline image ->setTag('tag1') // Set the tag ->setTrackOpens(false) // Disable tracking opens ->setTrackLinks(false) // Disable tracking clicks ->setMetaData('key1', 'value1') // Custom metadata ->setMetaData(['key2' => 'value2']) // Custom metadata as array ->setMessageStream('outbound') // The stream to use ->setSendBatch(false) // A single email will be sent, both 'to' recipients shown ->setRecipientVariables([ 'user@domain.com' => [ 'name' => 'user', ], 'user2@domain.com' => [ 'name' => 'user2', ] ]) // variables for each of the 'to' addresses ->setTemplate('template1') // The template to use ->setTemplateVariables(['key3' => 'value3']); // Set template variables // Batch mode is set to false, so 1 returned if successful $numSent = $postmark->send(); echo 'The email was ' . ($numSent ? '' : 'not ') . 'sent.';
Sending in Batch Mode// If using batch mode, the recipient variable 'toName' is inferred from the `to` addresses, e.g.
$postmark = $mail->new();
$postmark->to([
'user@domain.com' => 'A User',
'user2@domain.com' => 'Another User',
])
->setSendBatch(true)
->subject('Message Subject')
->bodyHTML('<p>Dear {{toName}},</p>')
->send();
// to =
// A User <user@domain.com>
// Another User <user2@domain.com>
//
// recipientVariables =
// {
// "user@domain.com": {
// "toName": "A User",
// "toEmail": "user@domain.com"
// },
// "user2@domain.com": {
// "toName": "Another User",
// "toEmail": "user2@domain.com"
// }
// }
//
// bodyHTML[user@domain.com] =
// <p>Dear A User,</p>
// bodyHTML[user2@domain.com] =
// <p>Dear Another User,</p>
// You can also use `setRecipientVariables()` to extend/override the inferred `recipientVariables` e.g.
$postmark = $mail->new();
$postmark->to([
'user@domain.com' => 'A User',
'user2@domain.com' => 'Another User',
])
->setRecipientVariables([
'user@domain.com' => [
'title' => 'A User (title)',
],
'user2@domain.com' => [
'toName' => 'Another User (changed name)',
'title' => 'Another User (title)',
],
])
->setSendBatch(true)
->subject('Message Subject')
->bodyHTML('<p>Dear {{toName}},</p><p>Title: {{title}}!</p>')
->send();
// to =
// A User <user@domain.com>
// Another User <user2@domain.com>
//
// recipientVariables =
// {
// "user@domain.com": {
// "toName": "A User",
// "toEmail": "user@domain.com",
// "title": "A User (title)"
// },
// "user@domain.com": {
// "toName": "Another User (changed name)",
// "toEmail": "user2@domain.com",
// "title": "Another User (title)"
// }
// }
//
// bodyHTML[user@domain.com] =
// <p>Dear A User,</p><p>Title: A User (title)!</p>
// bodyHTML[user2@domain.com] =
// <p>Dear Another User (changed name),</p><p>Title: Another User (title)!</p>
Sending with a template
How you set up your templates and layouts in Postmark is up to you, and this will determine which variables you pass to Postmark.
This module provides some defaults however. Alongside toName
and toEmail
, if a body
or bodyHTML
is set, these variables are also passed when using a template. The module will also attempt to replace any tags in these values with template/recipient variables. Hopefully the example below will demonstrate this:
$postmark = $mail->new(); $postmark->to('user@example.com, user2@example.com') ->setTemplate('template1') ->setTemplateVariables([ 'siteUrl' => $pages->get(1)->httpUrl, // https://www.example.com/ 'test' => 123, ]) ->setRecipientVariables([ 'user@example.com' => [ 'name' => 'User', 'toName' => 'User', ], 'user2@example.com' => [ 'name' => 'User 2', 'test' => 456, ], ]) ->bodyHTML( '<p>Dear {{name}}</p>' . '<p>This email was sent to {{toName}} <{{toEmail}}> from {{siteUrl}}.</p>' . '<p>{{test}}</p>' ) ->send();
The template subject:
Message from {{name}} on {{siteUrl}}
The HTML template (template1):
<table>
<tr>
<td>{{{bodyHTML}}}</td>
</tr>
</table>
Note the three curly braces being used - this prevents the value from being entity encoded (e.g. allows you to use HTML).
The Text template (template1)
{{body}}
The two HTML emails sent:
<!-- To: user@example.com --> <!-- Subject: Message from User on https://www.example.com/ --> <table> <tr> <td> <p>Dear User</p> <p>This email was sent to User <user@example.com> from https://www.example.com/.</p> <p>123</p> </td> </tr> </table> <!-- To: user2@example.com --> <!-- Subject: Message from User 2 on https://www.example.com/ --> <table> <tr> <td> <p>Dear User 2</p> <p>This email was sent to <user2@example.com> from https://www.example.com/.</p> <p>456</p> </td> </tr> </table>
Using postmark-php for extended integration$postmarkClient = $modules->get('WireMailPostmarkApp')->getClient();
$postmarkClient->getOpenStatistics();
Setting WireMailPostmarkApp as default
If WireMailPostmarkApp is the only WireMail module you have installed, then you can skip this step. However, if you have multiple WireMail modules installed, and you want WireMailPostmarkApp to be the default one used by ProcessWire, then you should add the following to your /site/config.php file:
$config->wireMail('module', 'WireMailPostmarkApp');
Install and use modules at your own risk. Always have a site and database backup before installing new modules.