Introduction

Assume we want to add to a Todo application the “inline Notion-like reminders” feature.

For this example, we will assume that the front-end calls a POST /todos endpoint on our Express API:

src/api.ts
import express from 'express'

const app = express()

interface Todo {
  userId: string
  title: string
  assigneeId?: string
  remind?: Date
}

app.post('/todos', async function (req, res) {
  const todoRecord: Todo = /* ... */

  // ...do some validation...

  const todo = await prisma.todo.create({
    data: todoRecord,
  })

  res.send({ todo })
})

app.listen(3000)

Let’s now implement the reminder mail notification as a sendTodoReminder() background function.

The sendTodoReminder() background function

As stated in the “Getting started” guide, we create our sendTodoReminder() function in the defer/ folder:

- src/
  - defer/
    - sendTodoReminder.ts ⬅
  - api.ts
- package.json
- .env
- ...

Here is our sendTodoReminder() implementation, sending an email using Twilio Sengrid SingleMail API:

defer/sendTodoReminder.ts
const sgMail = require("@sendgrid/mail");
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

const sendTodoReminder = async (todo: Todo) => {
  const { email } = await prisma.user.findUnique({
    where: {
      id: todo.userId,
    },
  });
  const msg = {
    to: email,
    from: "test@todo.app",
    subject: "TodoApp reminder",
    text: todo.title,
    html: todo.title,
  };

  return sgMail.send(msg);
};

Why use a Defer background function instead of Twilio Sendgrid scheduled Single Send API?

Mail scheduled with Twilio Sendgrid Single Send API can only be scheduled 3 days in advance.

Also, Defer offers a better developer experience at creating and cancelling scheduled mails.

Schedule reminders when creating a Todo

src/api.ts
import express from "express";
import sendTodoReminder from "./defer/sendTodoReminder";

const app = express()

interface Todo {
  userId: string
  title: string
  assigneeId?: string
  remind?: Date
}

app.post('/todos', async function (req, res) {
  const todoRecord: Todo = /* ... */

  // ...do some validation...

  const todo = await prisma.todo.create({
    data: todoRecord,
  })

  await sendTodoReminder.delay(todo, { delay: todo.remind })

  res.send({ todo })
})

app.listen(3000)

That’s it 🎉

Your Todo App now offers resilient reminders sent by email:

  • resilient reminders: reminders will always happen, no matter the failures along the way, thanks to Defer’s smart retries.

  • stay in control: Access analytics and logs of your scheduled reminders on the Defer dashboard:


Try Defer in under 5 minutes

Give a try to our Next.js starter template demo application by running:

npx create-next-app -e https://github.com/defer-run/defer.demo/tree/master/nextjs/app-template

and follow the README.md instructions.