# Email Sequence
Source: https://www.inngest.com/docs/examples/email-sequence
Description: See how to implement an email sequence with Inngest

A drip campaign is usually based on your user's behavior.

Let's say you want to create the following campaign:

- Send every user a welcome email when they join.
  - If a user received an email: wait a day and then follow-up with pro user tips meant for highly engaged users.
  - Otherwise: wait for up to three days and then send them the default trial offer, but only if the user hasn't already upgraded their plan in the meantime.

This page provides an overview on how to use Inngest to build reliable marketing campaigns, as well as all the related materials to this feature.

## Quick Snippet

Below is an example of how such a campaign would look like:

```javascript
inngest.createFunction(
  { id: "signup-drip-campaign" },
  { event: "app/signup.completed" },
  async ({ event, step }) => {
    event.data;
    user
    "Welcome to ACME";

    await step.run("welcome-email", async () => {
      return await sendEmail(
        email,
        welcome,
        <div>
          <h1>Welcome to ACME, {user.firstName}</h1>
        </div>
      );
    });

    // Wait up to 3 days for the user open the email and click any link in it
    await step.waitForEvent("wait-for-engagement", {
      event: "resend/email.clicked",
      if: `async.data.email_id == ${emailId}`,
      timeout: "3 days",
    });

    // if the user clicked the email, send them power user tips
    if (clickEvent) {
      await step.sleep("delay-power-tips-email", "1 day");
      await step.run("send-power-user-tips", async () => {
        await sendEmail(
          email,
          "Supercharge your ACME experience",
          <h1>
            Hello {firstName}, here are tips to get the most out of ACME
          </h1>
        );
      });

      // wait one more day before sending the trial offer
      await step.sleep("delay-trial-email", "1 day");
    }

    // check that the user is not already on the pro plan
    db.users.byEmail(email);

    if (dbUser.plan !== "pro") {
      // send them a free trial offer
      await step.run("trial-offer-email", async () => {
        await sendEmail(
          email,
          "Free ACME Pro trial",
          <h1>
            Hello {firstName}, try our Pro features for 30 days for free
          </h1>
        );
      });
    }
  }
);
```

## Code examples

Here are apps which use Inngest to power email campaigns.

<Example wide example={{
  title: "Integrate email events with Resend webhooks",
  technology: "Next.js, Resend",
  description: "Transactional emails in Next.js using Resend and Inngest. Get started sending customer lifecycle emails. ",
  pattern: 1,
  demo: "https://inngest-resend.vercel.app/",
  github: "https://github.com/joelhooks/inngest-resend-example",
  image: "/assets/docs/examples/email-sequence/nextjs-resend-inngest-email.png",
  author: "Joel Hooks",
  authorSocial: "https://twitter.com/jhooks"
}}/>

## More context

Check the resources below to learn more about building email sequences with Inngest.

<ResourceGrid cols={2}>

<Resource resource={{
  href: "/docs/guides/resend-webhook-events",
  name: "Guide: Integrate email events with Resend webhooks",
  icon: PencilSquareIcon,
  description: "Resend webhooks can be used to build functionality into your application based on changes in the email status. In this guide, you will learn how to build a dynamic drip marketing campaign which responds to a user's behavior.",
  pattern: 1,
}}/>

<Resource resource={{
  href: "https://www.youtube.com/watch?v=44WEb7SCgAw",
  name: 'Talk: "Background jobs 101: building reliable apps with Inngest"',
  icon: VideoCameraIcon,
  description: "In this talk Sylwia Vargas explains why the DIY approaches to user onboarding email campaigns tend to be slow and unreliable, and how we can leverage background jobs to deliver a great UX.",
  pattern: 1,
}}/>

<Resource resource={{
  href: "https://www.youtube.com/watch?v=EoFI_Bmzb4g",
  name: 'Talk: "Automate All of Your Customer Emails with AI in Next.js"',
  icon: VideoCameraIcon,
  description: "In this talk Joel Hooks dives into managing long-running processes like generative AI to enhance our processes and handle the human interaction required at each step of the workflow process.",
  pattern: 1,
}}/>

<Resource resource={{
  href: "/blog/lifecycle-emails-with-resend",
  name: 'Blog post: "Sending customer lifecycle emails with Resend and Inngest"',
  icon: BookOpenIcon,
  description: "In this blog post Joel Hooks implements customer lifecycle emails using Inngest, Next.js, Prisma, and Resend, building a highly personalized and automated email workflows.",
  pattern: 1,
}}/>

</ResourceGrid>

## How it works

With Inngest, you define functions or workflows using its SDK right in your own codebase and serve them through an HTTP endpoint in your application. Inngest uses this endpoint to download the function definitions and to execute them.

When a specific event is triggered, Inngest takes care of reliably executing the function (or functions).

In case of failure, Inngest will retry until it succeeds or you will see the failure on the Inngest dashboard, which you can debug and then retrigger so no data is lost.

## Related concepts

- [Steps](/docs/learn/inngest-steps)
- [Fan-out jobs](/docs/guides/fan-out-jobs)
- [Delayed functions](/docs/guides/delayed-functions#delaying-jobs)
- [Scheduled functions](/docs/guides/scheduled-functions)