mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-10-26 10:20:54 +03:00
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:
parent
f63845b436
commit
484f5fe9b6
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user