November 1, 2022
Receive emails with Node
You've probably found a dozen posts about sending emails with Node. But what about receiving them?
Why?
When would you want to receive emails instead of sending them? The most common use cases are for testing password resets and email flows. A common email flow is signing up, receiving a code and entering that code to signup.
How?
We'll be using the mailisk library for receiving emails. This is a free email testing service which allows us to read emails. It works by creating a virtual email server that we can send emails to.
The email addreses look like this <anything>@mynamespace.mailisk.net. Where mynamespace is the name of your namespace. An email sent to an address that ends in @mynamespace.mailisk.net can be read using the API.
Setup
Install the library with
npm install mailisk
We'll interact with the API using the client, you can create one by passing your API Key
const { MailiskClient } = require('mailisk');
const mailisk = new MailiskClient({ apiKey: 'YOUR_API_KEY' });
Receiving Email
We can use the searchInbox function to receive emails. Its only required parameter is our namespace.
const { MailiskClient } = require('mailisk');
const mailisk = new MailiskClient({ apiKey: 'YOUR_API_KEY' });
mailisk.searchInbox('mynamespace').then(console.log);
A note here is that, by default, this only considers emails received in the past 15 minutes. You can change that lower bound with the from_timestamp parameter. See the Node.js guide for the available filters and waiting behavior.
Set from_timestamp to 0 when older retained emails should be eligible too:
mailisk.searchInbox('mynamespace', { from_timestamp: 0 }).then(console.log);
In order to show this works we'll need to send an email. You can send one using your own email provider (e.g. Gmail). Any address that ends with your namespace will work, here let's simply send it to john@mynamespace.mailisk.net
After sending the email and executing the script, this is what we get in the console
{
total_count: 1,
options: { limit: 10, offset: 0, from_timestamp: 0, wait: true },
data: [
{
id: '1667305800547-9KJHqVLG5',
from: { address: 'test@example.com', name: '' },
to: [ { address: 'john@mynamespace.mailisk.net', name: '' } ],
subject: 'This is a test',
html: 'false',
text: 'Something goes here',
received_date: '2022-11-01T12:30:00.000Z',
received_timestamp: 1667305800,
expires_timestamp: 1667565000,
}
]
}
Sending emails
To make testing easier, Mailisk can also send an email back into the same namespace:
const namespace = 'mynamespace';
await mailisk.sendEmail(namespace, {
to: [`john@${namespace}.mailisk.net`],
subject: 'Testing',
text: 'This is a test.',
});
As an example, let's send ourselves an email and then read it
const { MailiskClient } = require('mailisk');
const namespace = 'mynamespace';
// create client
const mailisk = new MailiskClient({ apiKey: 'YOUR_API_KEY' });
async function main() {
// send email
await mailisk.sendEmail(namespace, {
to: [`john@${namespace}.mailisk.net`],
subject: 'Testing',
text: 'This is a test.',
});
// receive latest email
const { data: emails } = await mailisk.searchInbox(namespace, {
to_addr_prefix: `john@${namespace}.mailisk.net`,
});
// print out the subjects of all the recieved emails
for (const email of emails) {
console.log(`Received email with subject '${email.subject}'`);
}
}
main().then(() => console.log('Done'));
You'll notice we also used to_addr_prefix here. This let's us filter the emails we fetch by their destination address. In this example we sent an email to john@..., and therefore we only care about emails sent to john@.... If we didn't filter this we would also return other emails, such as ones sent to somethingelse@...
Closing notes
This should be enough to get you up and started with receiving emails in Node.
If you're using Cypress take a look at our post on Password reset with Cypress, which features the Mailisk Cypress plugin and an example repository. Otherwise there's more information about fetching emails in the Node.js guide and API reference.