Skip to main content

Schedule SendGrid emails 72+ hours in the future via Jiter

· 7 min read
Jose Valerio
Spencer Kaiser
⏱️TL;DR

We'll do our best to keep this short and sweet, but if you don't have the time, here's the gist:

SendGrid only allows for the scheduling of emails up to three days. Use Jiter and schedule emails weeks/months in advance with less than 30 lines of code!


The Problem

If you're trying to send a transactional email via SendGrid, you can delay it by a maximum of 72 hours:

sendgrid 72 hour delay limit

What if you want to delay it more than that? What if you want to send an email to that user 7 days after joining? What if you need to reevaluate whether you should send the email at that time?


The Solution

🔎Follow Along!

Check out our example repo on GitHub which includes code snippets you can use in your own project!

As you might have already guessed, the solution can be implemented in just nine simple steps (that aren't actually simple):

  1. Create a cron job manager in your app to initialize all cron jobs on app start
    • [Pause to question your architectural decisions and sanity]
  2. Create a new database table to keep track of user notifications (i.e., who needs to get notified and when)
    • Or you can just add another column, because your database can take another one for the team
  3. Create a cron job that checks your new table for any relevant records in order to determine who should be notified
    • And subsequently overburden your DB server with a super heavy query when the job runs because you forgot that indexes are a thing
  4. Spend 45 minutes creating a cron expression to schedule your cron job
    • All while recognizing the similarity to Regular Expressions, having a panic attack, and then accidentally setting your cron job to run 60 times per hour instead of once per hour
  5. Ensure that you are locking rows properly so your don't perform redundant tasks on multiple instances of the app (.e.g., sending the same user two notifications)
    • You are running multiple instances of the app, right?!
  6. Ensure that no two cron jobs referencing the same table run concurrently so they don't skip locked rows and exit prematurely
    • Alternatively, you can skip this step and spend 6 hours debugging why a user record was apparently ignored
  7. Take a break to reevaluate your career choices
    • This was probably on your schedule already
  8. Push your changes straight to production
    • #yolo
  9. Realize your jobs are not running at your desired time because you forgot about timezones

That's it! It's THAT simple 🚀

there has to be a better way gif with Joey from FRIENDS


The Actual Solution

Use Jiter 😉

But seriously, Jiter provides Just In Time (JIT) webhooks: you tell Jiter when you need to be reminded and what to remind you with, and we handle the rest.

To bypass this limitation with the SendGrid API, you can simply create an event with Jiter including a payload that will provide context (like what user to notify and what to notify them about), and then setup a webhook handler to actually trigger the email when the event is received.

Paulie Walnuts from The Sopranos describing Jiter

If you want to send an email to a new user seven days after they join your platform, simply create a Jiter event with a scheduledTime 7 days from now and include information about that user (like an ID) in the payload. 7 days later, we'll send a request to your app and you can trigger the email to be immediately sent! It's that simple.

Let's Build It...

The steps below describe how to use Jiter to schedule the delivery of an email one week after an API event takes place. Our example repo has the following components which are described in detail below:

  • An API endpoint to track the intent of purchasing grocery items
  • The creation of a Jiter event to remind the user to restock groceries 7 days later
  • A handler which receives the Jiter webhook event and triggers an email to SendGrid (which will be delivered 7 days after the initial event)

1. Jiter Auth

Check out our Getting Started page which walks you through the creation of your first org and how to get your API Key and Signing Secret.

The API Key is used for authenticating YOUR requests and the Signing Secret helps you verify the authenticity of OUR webhook requests when we send them to your app.

🛠️Try the API

We recently launched the Jiter Playground! You can create and receive events without setting anything up locally 🤯

An image showing the Jiter playground user interface

2. SendGrid Auth

  • Go to the API Keys page (or log in to SendGrid, go to Settings on the left sidebar, and click on API keys)
  • Click Create API Key in the top-right
  • Choose Restricted Access and enable the Mail Send permission: SendGrid mail send permissions
  • Copy your API key for use later

3. Jiter Setup

As mentioned earlier, we created an example repository; fork it and use it as a guide! You can copy snippets from that repo or follow our docs to configure the app your way.

The steps in the README.md are pretty straightforward, they involve setting up your credentials in a .env file and it's using ngrok to allow your local machine to receive events from our servers. If you don't want to set anything up locally you can use our Playground and if you're looking for a custom URL, we recommend requestcatcher.com.

Updating an Existing App

If you're solving this problem within an existing app, use the example repo as a guide and make sure to do the following:

4. Scheduling Events

The creation of an event is pretty simple via the Jiter SDK: just provide values for scheduledTime (when to deliver the webhook event), payload (what you want to receive as part of that event), and destination (the URL where we should send the POST request).

In our example (within the POST /api/events handler), we handle the API intent of purchasing groceries but added functionality to remind the user 7 days later to restock:

Code snippet showing how to create an event with Jiter

The snippet above is an abstraction of the example repo: we send an email confirming the user's intent to purchase groceries and then use the createEvent method from the SDK to schedule a reminder set for 7 days later (which will send an event to /api/webhooks/reminders).

5. Handling Webhook Events

It's 7 days later now... the future is here 🤖

When the webhook event comes to our app, we need to handle the request and take action using the payload as context.

In our example (within the POST api/webhooks/reminders handler) we use the Middleware method from the Jiter SDK to create a handler that accepts the request, verifies its authenticity, sends back a 200 status, and then provides the parsed payload:

The Webhook method from the Jiter SDK

Now that we're ready to receive the reminder event, we need to implement some business logic to send the restock reminder email:

Jiter webhook handler implementation

Because parse: true was passed to the Middleware method as an option, our payload was automatically parsed as JSON and we're able to safely deconstruct the items and email for use in our reminder email.

Tada! That's how you can use Jiter to schedule delayed emails with SendGrid and bypass the 72 hour limit.

What did you think?

Was this blog post helpful? Do you regret your decision to skip past the TL;DR and read anyways? Did you have an epiphany and choose to pursue your dreams of baking?

Our team is eager to hear from you and help however we can. Get in touch with us via the Jiter Discord Server or schedule time to chat with our dev team!




Still reading? We appreciate you... click here for your reward.

Thanks for reading ❤️