Did you know you can use GraphQL to send and receive emails? That's right - there is a free API at graphql.mailslurp.com you can use to create disposable email accounts for testing and application development.

Create a test project

Use NPM to initialize a new node project and add the AVA test library (you can use any test library you wish).

npm init ava -y

Then add the graphql-request library so we can call the GraphQL endpoints.

npm install --save graphql-request

Our package json now looks something like this:

{
  "name": "graphql",
  "version": "1.0.0",
  "description": "MailSlurp graphql usage example",
  "main": "index.js",
  "scripts": {
    "test": "ava"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ava": "^4.0.0"
  },
  "dependencies": {
    "graphql-request": "^3.7.0"
  }
}

To use ESM style imports add the type: module flag to your package.

{
  "main": "index.mjs",
  "type": "module"
}

Configure a graphql client for email accounts

Create an index.mjs file and add the code below:

import { GraphQLClient } from "graphql-request";

export function getClient(apiKey) {
  // create a new graphql-request client using the MailSlurp graphql endpoint
  // and passing a headers map including your MailSlurp API Key using "x-api-key" header
  return new GraphQLClient("https://graphql.mailslurp.com", {
    headers: {
      "x-api-key": apiKey,
    },
  });
}

Testing disposable email accounts with AVA

Now we have a client let us write some tests to demonstrate usage of email accounts. Create a file test.mjs and add a test.

import test from "ava";

test("bar", async (t) => {
  const bar = Promise.resolve("bar");
  t.is(await bar, "bar");
});

If we run npm t we will see passing tests in your console output.

npm run test

> graphql@1.0.0 test
> ava


  ✔ bar
  ─

  1 test passed

Given that the dummy tests are passing we can add gql queries to our test to create a disposable email account, send and email to it and receive said email.

Create an email address with GraphQL

Create a new disposable email account using MailSlurp's createInbox mutation. Use a custom domain for permanent inboxes.

import test from "ava";
import { gql } from "graphql-request";
import { getClient } from "./index.mjs";

const apiKey = process.env.API_KEY;

test("can create inbox", async (t) => {
  const { createInbox } = await getClient(apiKey).request(gql`
    mutation {
      createInbox {
        id
        emailAddress
      }
    }
  `);
  t.is(!!createInbox.id, true);
  t.is(createInbox.emailAddress.indexOf("@mailslurp") > -1, true);
});

Send emails

test("can send an email", async (t) => {
  // create an inbox
  const { createInbox } = await getClient(apiKey).request(gql`
    mutation {
      createInbox {
        id
        emailAddress
      }
    }
  `);
  // send an email using mutation
  const { sendEmail } = await getClient(apiKey).request(gql`
        mutation {
            sendEmail(fromInboxId: "${createInbox.id}", to: ["${createInbox.emailAddress}"], subject: "Test subject") {
                from
                to
                subject
            }
        }
    `);
  t.is(sendEmail.from, createInbox.emailAddress);
  t.is(sendEmail.subject, "Test subject");
  t.is(sendEmail.to.indexOf(createInbox.emailAddress) > -1, true);
});

Receive and read emails in GraphQL

test("can send an email and receive the contents", async (t) => {
  // create an inbox
  const { createInbox } = await getClient(apiKey).request(gql`
    mutation {
      createInbox {
        id
        emailAddress
      }
    }
  `);
  // send an email using mutation
  const { sendEmail } = await getClient(apiKey).request(gql`
        mutation {
            sendEmail(fromInboxId: "${createInbox.id}", to: ["${createInbox.emailAddress}"], subject: "Test subject", body: "Hello") {
                from
                to
                subject
            }
        }
    `);

  // wait for the email to arrive
  const { waitForLatestEmail } = await getClient(apiKey).request(gql`
        query {
            waitForLatestEmail(inboxId: "${createInbox.id}", timeout: 60000, unreadOnly: true) {
                id
                from
                to
                subject
                body
            }
        }
    `);
  t.is(waitForLatestEmail.body.indexOf("Hello") > -1, true);
  t.is(waitForLatestEmail.subject.indexOf(sendEmail.subject) > -1, true);
  t.is(waitForLatestEmail.from.indexOf(sendEmail.from) > -1, true);

  // delete the email afterwards
  const { deleteEmail } = await getClient(apiKey).request(gql`
        mutation {
            deleteEmail(emailId: "${waitForLatestEmail.id}")
        }
    `);
  t.is(deleteEmail === "deleted", true);
});