How to send emails using EmailEngine
EmailEngine makes it possible to send emails using the registered accounts' SMTP servers and external sending services.
When sending an email, EmailEngine first queues the email for delivery. Once the email has been queued, EmailEngine would then try to transfer that message to the accounts' SMTP server or sending service.
While you obviously could do this directly, using EmailEngine means you do not have to store and manage the credentials of the email accounts. All you need is access to EmailEngine and to know the account ID you want to send the email from.
See also – sending emails using Email Templates and mail-merge.
Sending emails using the API
You can send emails through a specific email account using the submit API endpoint.
curl -XPOST "http://127.0.0.1:3000/v1/account/example/submit" \
-H "Authorization: Bearer f77cf263b70488c7a35bf1539fd544a81a88711ff74326ce9793022df08d91b9" \
-H "Content-type: application/json" \
-d '{
"from": {
"name": "Andris Reinman",
"address": "andris@example.com"
},
"to": [
{
"name": "Ethereal",
"address": "andris@ethereal.email"
}
],
"subject": "Test message",
"text": "Hello from myself!",
"html": "<p>Hello from myself!</p>"
}'
TIP: The
from
address in the request payload is optional. EmailEngine will use the account's registered email and name if it is not set.
The response for a queued delivery includes the queue ID (you can use it to cancel the delivery).
{
"response": "Queued for delivery",
"messageId": "<78aa92af-67c9-4130-b1bf-c22feb2ec3f6@example.com>",
"sendAt": "2022-03-24T10:23:38.196Z",
"queueId": "17fbb7408d44367d9b7"
}
Raw message
To send a prepared RFC822 formatted email message, you can provide it as a base64 encoded raw
property value. Unless you specify the envelope
property, recipient addresses are derived from email headers.
The following snippet creates the base64 raw
value from a RFC822 formatted string value and submits the email for delivery.
curl -XPOST "http://127.0.0.1:3000/v1/account/example/submit" \
-H "Authorization: Bearer f77cf263b70488c7a35bf1539fd544a81a88711ff74326ce9793022df08d91b9" \
-H "Content-type: application/json" \
-d "{
\"raw\" : \"` echo 'From: andris@example.com
To: andris@ethereal.email
Subject: test message
Mime-Version: 1.0
Hello world!
' | base64`\"
}"
Sending via the bundled SMTP interface
To use the bundled SMTP interface, you must first enable it from the SMTP Interface configuration page.
You can then configure EmailEngine as the SMTP server for your email sending library. SMTP username is the account ID, and password is the SMTP password
field value from the SMTP Server configuration page. The bundled SMTP server does not support encryption so make sure you do not configure tls/ssl settings.
EmailEngine responds the queue ID and the expected delivery time in the SMTP server response.
250 Message queued for delivery as 17fbb0a97504803a15a (2022-03-24T08:28:27.856Z)
Below you can find example configurations for different email client libraries.
Nodemailer
const transporter = nodemailer.createTransport({
host: 'localhost',
port: 2525,
auth: {
user: 'example',
pass: 'a57518a9e8858187463d53d5b7d3aa0c'
}
});
PHPMailer
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'localhost';
$mail->SMTPAuth = true;
$mail->Username = 'example';
$mail->Password = 'PUg6PzUe3ErkAKUqJ6';
$mail->SMTPSecure = 'a57518a9e8858187463d53d5b7d3aa0c';
$mail->Port = 2525;
SwiftMailer
$transport = (new Swift_SmtpTransport('localhost', 2525))
->setUsername('example')
->setPassword('a57518a9e8858187463d53d5b7d3aa0c');
Tracking user action events
EmailEngine supports basic open and clicks tracking. By default, tracking is disabled, and all email messages are sent unmodified. If you enable tracking, then EmailEngine rewrites HTML content of the emails so that all links would be redirected through EmailEngine. Whenever a user clicks on such a link, EmailEngine then sends a webhook notification about it.
Navigate to the Service configuration page and check the "Track opens and clicks" checkbox to enable tracking by default. Also, make sure that EmailEngine is configured to send webhooks for the "trackOpen" and "trackClick" events on the Webhooks configuration page.
You can manage tracking in the message level by using trackingEnabled
API option or X-EE-Tracking-Enabled
SMTP header.
Using the trackingEnabled
option:
curl -XPOST "http://127.0.0.1:3000/v1/account/example/submit" \
-H "Authorization: Bearer f77cf263b70488c7a35bf1539fd544a81a88711ff74326ce9793022df08d91b9" \
-H "Content-type: application/json" \
-d '{
"from": {
"name": "Andris Reinman",
"address": "andris@example.com"
},
...
"trackingEnabled": true
}'
Using X-EE-Tracking-Enabled
message header:
From: Andris Ethereal <andris@example.com>
To: Andris Ethereal <andris@ethereal.email>
Subject: Tracking test
Message-ID: <2d4696ea-cb47-7af4-0bc3-81ea7a8008be@pangalink.net>
Date: Thu, 24 Mar 2022 08:28:27 +0000
MIME-Version: 1.0
X-EE-Tracking-Enabled: true
EmailEngine sends trackOpen
webhooks whenever the tracking beacon is loaded and trackClick
whenever a tracking link is clicked.
NB! Both events might include false positives. Webmail clients that cache or mask included images might trigger
trackOpen
webhooks, and security scanners that scan incoming emails for malicious links might trigger thetrackClick
webhooks.
Webhooks always include the Message-ID
header value but not the internal identifier for EmailEngine messages. EmailEngine does not store this information and cannot match user action events against specific emails in the Sent Mail folder (this behavior might change in the future).
Email client loaded the open tracking beacon.
{
"account": "example",
"date": "2022-03-24T08:28:32.992Z",
"event": "trackOpen",
"data": {
"messageId": "<2d4696ea-cb47-7af4-0bc3-81ea7a8008be@example.com>",
"remoteAddress": "1.2.3.4",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36"
}
}
Be aware that open tracking can be extremely misleading. The industry standard for open tracking is to include a beacon image in the email HTML code. Modern email clients often do not load remote images at all or use image preloading.
A tracked link was clicked.
{
"account": "example",
"date": "2022-03-24T08:27:24.572Z",
"event": "trackClick",
"data": {
"messageId": "<49b6cdb1-5d43-e100-0833-bd61867b7bb3@example.com>",
"url": "https://google.com/",
"remoteAddress": "1.2.3.4",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36"
}
}
Send emails at a specific time
You can schedule sending emails at a specific time. In that case, EmailEngine would queue the message but would not try to transfer it to the account's SMTP server until the requested time.
Using the sendAt
option:
curl -XPOST "http://127.0.0.1:3000/v1/account/example/submit" \
-H "Authorization: Bearer f77cf263b70488c7a35bf1539fd544a81a88711ff74326ce9793022df08d91b9" \
-H "Content-type: application/json" \
-d '{
"from": {
"name": "Andris Reinman",
"address": "andris@example.com"
},
...
"sendAt": "2023-07-08T07:06:34.336Z"
}'
Using X-EE-Send-At
message header:
From: Andris Ethereal <andris@example.com>
To: Andris Ethereal <andris@ethereal.email>
Subject: Tracking test
Message-ID: <2d4696ea-cb47-7af4-0bc3-81ea7a8008be@pangalink.net>
Date: Thu, 24 Mar 2022 08:28:27 +0000
MIME-Version: 1.0
X-EE-Send-At: 2023-07-08T07:06:34.336Z
Send emails through an external service
By default, EmailEngine uses the account's SMTP server to send emails. Sometimes this might not be enough. For example, when you need to send a larger volume of emails. For these use cases, you can skip the account's SMTP server and use a dedicated sending service like Sendgrid, Mailgun, Postmark, AWS SES, or others.
First, register the gateway using the API.
curl -XPOST "http://127.0.0.1:3000/v1/gateway" \
-H "Authorization: Bearer f77cf263b70488..." \
-H "Content-type: application/json" \
-d '{
"gateway": "sendgrid",
"name": "Sendgrid",
"user": "apikey",
"pass": "<YOUR_API_KEY>",
"host": "smtp.sendgrid.net",
"port": 465,
"secure": true
}'
Next, send an email from an email account, and specify the gateway option for routing.
curl -XPOST "http://127.0.0.1:3000/v1/account/example/submit" \
-H "Authorization: Bearer f77cf263b70488c7a35bf1539fd544a81a88711ff74326ce9793022df08d91b9" \
-H "Content-type: application/json" \
-d '{
"from": {
"name": "Andris Reinman",
"address": "andris@example.com"
},
"to": [
{
"name": "Ethereal",
"address": "andris@ethereal.email"
}
],
"subject": "Test message",
"text": "Hello from myself!",
"html": "<p>Hello from myself!</p>",
"gateway": "sendgrid"
}'
SMTP settings do not need to be configured for the account when using gateways to send emails.
Managing queued emails
EmailEngine allows you to list and delete emails that have been queued but are not yet transferred to the account's SMTP server. Outbox includes all emails that are scheduled to be delivered in the future, and it also contains emails that should have been sent but for whatever reason are not – for example, the SMTP server is currently not accessible.
Outbox is global as it includes queued emails for all accounts. It is not account-specific.
You can access the Outbox using the outbox API endpoints.
You can read about detecting and handling bounces from here.
EmailEngine includes helpers that mimic regular email clients when replying or forwarding emails. Read about it here.