mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-09-11 10:46:25 +03:00
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:
parent
7f48bb9df6
commit
7bfb3b6169
@ -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,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user