docs: update produce review request email

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

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/10146
GitOrigin-RevId: c6a08396ffb5437c8d779ba2b2ffabbd3c5c645b
This commit is contained in:
Rob Dominguez 2023-08-21 07:32:52 -05:00 committed by hasura-bot
parent 7f48bb9df6
commit 7bfb3b6169
2 changed files with 61 additions and 85 deletions

View File

@ -16,6 +16,7 @@ sidebar_position: 1
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 Product Review Request Email
@ -27,15 +28,21 @@ order is delivered. We'll do this by executing this trigger every day at midnigh
days since an order has been completed, if it has, and the user has not already received a reminder and has not left a
review for their purchase, we'll send them an email asking them to do so.
<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
@ -47,68 +54,11 @@ 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 there are three tables in our database: `orders`, `products`, and `users`. The `orders`
table contains the details of all orders placed by customers, including the product ID, customer ID, order status, and
Our sample app's database contains, among others, three tables: `orders`, `products`, and `users`. The `orders` table
contains the details of all orders placed by customers, including the product ID, customer ID, order status, and
delivery date. The `products` table contains the details of all products, including the product name and description.
The `users` table contains the details of all users, including the user's email address.
<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 'products' table
CREATE TABLE public.products (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT
);
-- Create the 'orders' table
CREATE TABLE public.orders (
id SERIAL PRIMARY KEY,
product_id INTEGER NOT NULL REFERENCES products(id),
customer_id INTEGER NOT NULL REFERENCES users(id),
status VARCHAR(255),
delivery_date DATE,
is_reviewed BOOLEAN DEFAULT FALSE
);
-- 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 'products' table
INSERT INTO public.products (name, description) VALUES
('Product A', 'Description for Product A'),
('Product B', 'Description for Product B'),
('Product C', 'Description for Product C');
-- Seed data for the 'orders' table
INSERT INTO public.orders (product_id, customer_id, status, delivery_date) VALUES
(1, 1, 'Delivered', NOW() - INTERVAl '7 days'),
(2, 1, 'In Progress', NOW() - INTERVAl '14 days'),
(3, 2, 'Delivered', NOW() - INTERVAl '7 days'),
(1, 3, 'Cancelled', NOW() - INTERVAl '30 days');
```
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.
**For any order that is delivered, do be sure to change the date to a time within the last seven days.**
</details>
## Step 1: Create the Scheduled Event
Head to your the Hasura Console of your project and navigate to the "Events" tab. From there, click on the
@ -126,21 +76,31 @@ First, provide a name for your trigger, e.g., `send_review_request_email`. Then,
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.
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:
The route on our webhook we'll use is `/review-request`. Below, we'll see what this looks like with a service like
[ngrok](https://ngrok.com/), but the format will follow this template:
```
http://host.docker.internal:4000/review-request
```text
https://<your-webhook-url>/review-request
```
:::info Tunneling your webhook endpoint
If you're not running your Hasura instance on the same machine as your webhook endpoint, you'll need to use a tunneling
service such as [ngrok](https://ngrok.com/) to expose your webhook endpoint to the internet. This will allow you to
expose a public URL that will forward requests to your local machine and the server we'll configure below.
Since our project is running on Hasura Cloud, and our handler will run on our local machine, we'll use ngrok to expose
the webhook endpoint to the internet. This will allow us to expose a public URL that will forward requests to our local
machine and the server we'll configure below.
You'll need to modify your webhook URL to use the public URL provided by ngrok.
After installing ngrok and
[authenticating](https://ngrok.com/docs/secure-tunnels/ngrok-agent/tunnel-authtokens/#:~:text=Once%20you've%20signed%20up,make%20installing%20the%20authtoken%20simple.),
you can do this by running:
```bash
ngrok http 4000
```
Then, copy the `Forwarding` value for use in our webhook 🎉
:::
Next, we'll configure the cron expression that will trigger the event. In this example, we want to send requests at
@ -233,26 +193,42 @@ nodemailer.createTestAccount((err, account) => {
});
}
// get our date ready for the query
const today = new Date();
const sevenDaysAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
const formattedDate = `${sevenDaysAgo.getFullYear()}-${String(sevenDaysAgo.getMonth() + 1).padStart(
2,
'0'
)}-${String(sevenDaysAgo.getDate()).padStart(2, '0')}`;
// get our timestamp strings for the query
const currentDate = new Date();
const currentUTCDate = new Date(
Date.UTC(
currentDate.getUTCFullYear(),
currentDate.getUTCMonth(),
currentDate.getUTCDate(),
currentDate.getUTCHours(),
currentDate.getUTCMinutes(),
currentDate.getUTCSeconds()
)
);
const sevenDaysAgoMidnight = new Date(currentUTCDate);
sevenDaysAgoMidnight.setDate(currentUTCDate.getUTCDate() - 7);
sevenDaysAgoMidnight.setUTCHours(0, 0, 0, 0);
const sevenDaysAgoEOD = new Date(currentUTCDate);
sevenDaysAgoEOD.setDate(currentUTCDate.getUTCDate() - 7);
sevenDaysAgoEOD.setUTCHours(23, 59, 0, 0);
const sevenDaysAgoMidnightString = sevenDaysAgoMidnight.toISOString();
const sevenDaysAgoEODString = sevenDaysAgoEOD.toISOString();
// Fetch the data from our Hasura instance
async function getRecentOrders() {
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 ReviewRequestQuery($delivery_date: date!) {
orders(where: {delivery_date: {_eq: $delivery_date}, is_reviewed: {_eq: false}}) {
query ReviewRequestQuery($after: timestamptz!, $before: timestamptz!) {
orders(where: {delivery_date: {_gte: $after, _lte: $before}, is_reviewed: {_eq: false}}) {
user {
id
name
@ -263,11 +239,11 @@ nodemailer.createTestAccount((err, account) => {
name
}
}
}
}
`,
variables: {
delivery_date: formattedDate,
after: sevenDaysAgoMidnightString,
before: sevenDaysAgoEODString,
},
}),
});

View File

@ -2,7 +2,7 @@ import React from 'react';
import styles from './styles.module.scss';
import Beaker from '@site/static/icons/beaker.svg';
const isDependent = `This quickstart is dependent upon the docs e-commerce sample app. If you haven't already deployed the sample app, you can do so with one click below. If you've already deployed the sample app, simply use <a href="https://cloud.hasura.io" target="_blank" rel="noopener noreferrer">your existing project.</a>`;
const isDependent = `This quickstart/recipe is dependent upon the docs e-commerce sample app. If you haven't already deployed the sample app, you can do so with one click below. If you've already deployed the sample app, simply use <a href="https://cloud.hasura.io" target="_blank" rel="noopener noreferrer">your existing project.</a>`;
const isStandalone = `You can use this quickstart with any project, but it pairs well with our docs e-commerce sample app, which you can deploy to Hasura Cloud with one click below. If you've already deployed the sample app, <a href="https://cloud.hasura.io" target="_blank" rel="noopener noreferrer">access your existing project.</a>`;
function createMarkup(dependent) {