docs: update expiration recipe to match new schema

[DOCS-1196]: https://hasurahq.atlassian.net/browse/DOCS-1196?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/10160
GitOrigin-RevId: bec5c163167141414b170430c4867141749a88fe
This commit is contained in:
Rob Dominguez 2023-08-22 08:00:20 -05:00 committed by hasura-bot
parent f63845b436
commit 484f5fe9b6

View File

@ -15,6 +15,7 @@ keywords:
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Thumbnail from '@site/src/components/Thumbnail';
import SampleAppBlock from '@site/src/components/SampleAppBlock';
# Send a Coupon Expiration Reminder Email
@ -25,15 +26,21 @@ guide, we'll walk through how to use Scheduled Triggers on an e-commerce type ap
users when their coupon is about to expire. Nudges like this can help increase conversion rates and improve the overall
user experience.
<SampleAppBlock dependent />
## Prerequisites
Before getting started, ensure that you have the following in place:
- A Hasura project, either locally or using [Hasura Cloud](https://cloud.hasura.io/?skip_onboarding=true).
- The docs e-commerce sample app deployed to Hasura Cloud.
- A working SMTP server or email-sending service that you can integrate with to send emails.
- If you plan on using a webhook endpoint hosted on your own machine with a Hasura project hosted elsewhere, ensure that
you have a tunneling service such as [ngrok](https://ngrok.com/) set up so that a remotely hosted instance can
communicate with your local machine.
:::info Tunneling your webhook endpoint from your local machine
If you plan on using a webhook endpoint hosted on your own machine, ensure that you have a tunneling service such as
[ngrok](https://ngrok.com/) set up so that your Cloud Project can communicate with your local machine.
:::
## Our model
@ -45,50 +52,8 @@ When sending transactional emails such as this, there are three fundamental comp
email? How will you return information so that you have the correct data to include in the email?
- **Your email templating**: How will you generate and send the email containing the information you want to send?
For simplicity, we're assuming two tables in our database: `users` and `coupons`. The `users` table contains the details
of our users, and the `coupons` table contains the details of the coupons that we want to send reminders for.
<details>
<summary>
Click here for the SQL to generate these tables and some seed data.
</summary>
```sql
-- Create the 'users' table
CREATE TABLE public.users (
id SERIAL PRIMARY KEY,
name VARCHAR(255),
email TEXT NOT NULL
);
-- Create the 'coupons' table
CREATE TABLE public.coupons (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES public.users(id),
code VARCHAR(255),
expiration_date DATE
);
-- Seed data for the 'users' table
INSERT INTO public.users (name, email) VALUES
('Daniel Ricciardo', 'user1@example.com'),
('Charles Leclerc', 'user2@example.com'),
('Carlos Sainz', 'user3@example.com');
-- Seed data for the 'coupons' table
INSERT INTO public.coupons (user_id, code, expiration_date) VALUES
(1, 'COUPON3', NOW() + INTERVAL '2 day'),
(2, 'COUPON16', NOW() + INTERVAL '2 day'),
(3, 'COUPON55', NOW() + INTERVAL '2 day');
```
You can copy / paste this into the `RUN SQL` tab in the Hasura Console on the `Data` page. Then, track all relationships
under the `Public` schema on the `Data` page.
**We're generating coupons that expire in two days so that we can test our Scheduled Trigger. If you run this SQL and
come back to the project later, remember to update the `expiration_date` field.**
</details>
Our sample app's database contains, among others, two tables: `users` and `coupons`. The `users` table contains the
details of our users, and the `coupons` table contains the details of the coupons that we want to send reminders for.
## Step 1: Create the Scheduled Event
@ -104,14 +69,14 @@ Head to your the Hasura Console of your project and navigate to the "Events" tab
## Step 2: Configure the Scheduled Event
First, provide a name for your trigger, e.g., `send_coupon_expiration_email`. Then, enter a webhook URL that will be
called when the event is triggered. This webhook will be responsible for sending the review request email and can be
hosted anywhere, and written in any language, you like.
called when the event is triggered. This webhook will be responsible for sending the email and can be hosted anywhere,
and written in any language, you like.
In the example below, if we're using Docker, we'll use a webhook endpoint hosted on our own machine running on port
`4000`. Let's enter the following URL to allow Docker to communicate with the host machine:
```
http://host.docker.internal:4000/expiration_check
https://<your-webhook-url>/expiration_check
```
:::info Tunneling your webhook endpoint
@ -207,6 +172,12 @@ nodemailer.createTestAccount((err, account) => {
},
});
// helper function to turn timestamp into a date
function timestampToDate(timestamp) {
const date = new Date(timestamp);
return date;
}
// Our route for the webhook
app.post('/expiration_check', async (req, res) => {
// confirm the auth header is correct — ideally, you'd keep the secret in an environment variable
@ -220,19 +191,19 @@ nodemailer.createTestAccount((err, account) => {
// get our date ready for the query
const today = new Date();
const twoDaysFromNow = today.setDate(today.getDate() + 2);
const twoDaysFromNowString = new Date(twoDaysFromNow).toISOString().split('T')[0];
const twoDaysFromNowTimestamp = new Date(twoDaysFromNow).toISOString();
// Fetch the data from our Hasura instance
async function getExpiringCoupons() {
const response = await fetch('http://localhost:8080/v1/graphql', {
const response = await fetch('<YOUR_CLOUD_PROJECT_ENDPOINT>', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
// "x-hasura-admin-secret": "<YOUR-ADMIN-KEY>",
'x-hasura-admin-secret': '<YOUR_ADMIN_SECRET>',
},
body: JSON.stringify({
query: `
query GetExpiringCoupons($two_days_from_now: date!) {
query GetExpiringCoupons($two_days_from_now: timestamptz!) {
coupons(where: {expiration_date: {_lte: $two_days_from_now}}) {
id
code
@ -246,7 +217,7 @@ nodemailer.createTestAccount((err, account) => {
}
`,
variables: {
two_days_from_now: twoDaysFromNowString,
two_days_from_now: twoDaysFromNowTimestamp,
},
}),
});
@ -267,7 +238,7 @@ nodemailer.createTestAccount((err, account) => {
subject: `You've got a coupon expiring soon, ${coupon.user.name.split(' ')[0]}!`,
text: `Yo ${coupon.user.name.split(' ')[0]},\n\nYour coupon code, ${
coupon.code
}, is expiring soon! Use it before ${coupon.expiration_date}.\n\nThanks,\nSuperStore.com`,
}, is expiring soon! Use it before ${timestampToDate(coupon.expiration_date)}.\n\nThanks,\nSuperStore.com`,
};
// Send the message using the Nodemailer transporter