Extends WireMail to use the Postmark API for sending emails.
- 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.
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 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.
The following are extra methods implemented by this module:
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 <[email protected]>" 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='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
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.
Send an email:
$postmark = $mail->new();
$sent = $postmark->to('[email protected]')
->from('[email protected]')
->subject('Message Subject')
->body('Message Body')
->send();
Send an email using all supported WireMail methods and extra methods implemented by WireMailPostmarkApp:
$postmark = $mail->new();
// WireMail methods
$postmark->to([
'[email protected]' => 'A User',
'[email protected]' => 'Another User',
])
->from('[email protected]', 'Company Name')
->replyTo('[email protected]', 'Company Name')
->subject('Message Subject')
->bodyHTML(
'<p>Message Body with variables: {{name}} = {{toName}} <{{toEmail}}> ({{key3}})</p>' .
'<img src="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 <[email protected]>') // Use a different Sender Signature
->cc('[email protected]')
->bcc(['[email protected]', '[email protected]'])
->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([
'[email protected]' => [
'name' => 'user',
],
'[email protected]' => [
'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.';
// If using batch mode, the recipient variable 'toName' is inferred from the `to` addresses, e.g.
$postmark = $mail->new();
$postmark->to([
'[email protected]' => 'A User',
'[email protected]' => 'Another User',
])
->setSendBatch(true)
->subject('Message Subject')
->bodyHTML('<p>Dear {{toName}},</p>')
->send();
// to =
// A User <[email protected]>
// Another User <[email protected]>
//
// recipientVariables =
// {
// "[email protected]": {
// "toName": "A User",
// "toEmail": "[email protected]"
// },
// "[email protected]": {
// "toName": "Another User",
// "toEmail": "[email protected]"
// }
// }
//
// bodyHTML[[email protected]] =
// <p>Dear A User,</p>
// bodyHTML[[email protected]] =
// <p>Dear Another User,</p>
// You can also use `setRecipientVariables()` to extend/override the inferred `recipientVariables` e.g.
$postmark = $mail->new();
$postmark->to([
'[email protected]' => 'A User',
'[email protected]' => 'Another User',
])
->setRecipientVariables([
'[email protected]' => [
'title' => 'A User (title)',
],
'[email protected]' => [
'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 <[email protected]>
// Another User <[email protected]>
//
// recipientVariables =
// {
// "[email protected]": {
// "toName": "A User",
// "toEmail": "[email protected]",
// "title": "A User (title)"
// },
// "[email protected]": {
// "toName": "Another User (changed name)",
// "toEmail": "[email protected]",
// "title": "Another User (title)"
// }
// }
//
// bodyHTML[[email protected]] =
// <p>Dear A User,</p><p>Title: A User (title)!</p>
// bodyHTML[[email protected]] =
// <p>Dear Another User (changed name),</p><p>Title: Another User (title)!</p>
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('[email protected], [email protected]')
->setTemplate('template1')
->setTemplateVariables([
'siteUrl' => $pages->get(1)->httpUrl, // https://www.example.com/
'test' => 123,
])
->setRecipientVariables([
'[email protected]' => [
'name' => 'User',
'toName' => 'User',
],
'[email protected]' => [
'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: [email protected] -->
<!-- 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: [email protected] -->
<!-- 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>
$postmarkClient = $modules->get('WireMailPostmarkApp')->getClient();
$postmarkClient->getOpenStatistics();
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');