Published on

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. It only needs one parameter, 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 will only return the latest emails - any emails received in the past 5 seconds. This can be changed by overriding the from_timestamp parameter. You can check the docs for more information.

With that in mind, let's change it so it gives us all the emails in the inbox, regardless of when they were received

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,
      spam_score: 0.1
    }
  ]
}

Sending emails

To make testing a bit easier we can also use mailisk to send emails. These can only be sent to mailisk namespaces though

...
const namespace = 'mynamespace'

await mailisk.sendVirtualEmail(namespace, {
  from: 'test@example.com',
  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.sendVirtualEmail(namespace, {
    from: 'test@example.com',
    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 additional information about options for fetching emails in the documentation and API Reference