From 6f812f4afeb7fbdd4565d124023a8f86706cc2e6 Mon Sep 17 00:00:00 2001 From: nusquama Date: Tue, 16 Dec 2025 05:01:01 +0100 Subject: [PATCH] creation --- .../readme-11759.md | 436 ++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 workflows/Email Newsletter System with SendGrid, Google Sheets & Freemium Rate Limiting-11759/readme-11759.md diff --git a/workflows/Email Newsletter System with SendGrid, Google Sheets & Freemium Rate Limiting-11759/readme-11759.md b/workflows/Email Newsletter System with SendGrid, Google Sheets & Freemium Rate Limiting-11759/readme-11759.md new file mode 100644 index 000000000..372668b18 --- /dev/null +++ b/workflows/Email Newsletter System with SendGrid, Google Sheets & Freemium Rate Limiting-11759/readme-11759.md @@ -0,0 +1,436 @@ +Email Newsletter System with SendGrid, Google Sheets & Freemium Rate Limiting + +https://n8nworkflows.xyz/workflows/email-newsletter-system-with-sendgrid--google-sheets---freemium-rate-limiting-11759 + + +# Email Newsletter System with SendGrid, Google Sheets & Freemium Rate Limiting + +### 1. Workflow Overview + +This workflow implements an **Email Newsletter System** integrating **SendGrid**, **Google Sheets**, and a **Freemium Rate Limiting** mechanism. Its primary purpose is to process email newsletter requests received via a webhook, differentiate between free ("demo") and pro users, enforce a daily sending limit for free users, and update user sending statistics in a Google Sheet. It also sends email notifications through SendGrid and alerts the administrator via Telegram. + +The workflow is logically divided into the following blocks: + +- **1.1 Input Reception and User Mode Check:** Receives newsletter data via webhook and checks if the user is "demo" (free) or "pro". +- **1.2 User Existence Verification:** Reads Google Sheets to check if the user exists and retrieves their sending history. +- **1.3 Rate Limiting Check:** For demo users, verifies if the daily sending limit (5 emails/day) has been reached. +- **1.4 User Data Update and Email Sending:** Updates Google Sheets with new usage counts and sends the email via SendGrid. +- **1.5 Response and Notifications:** Sends success or limit-exceeded responses to the requester and sends Telegram notifications to the administrator. + +--- + +### 2. Block-by-Block Analysis + +#### 2.1 Input Reception and User Mode Check + +- **Overview:** + Receives incoming newsletter requests from a web form, parses the payload, and routes processing based on user mode ("demo" or "pro"). + +- **Nodes Involved:** + - Webhook1 + - Check Mode1 + - Send Email (Pro) + - Success Response (Pro)1 + +- **Node Details:** + + - **Webhook1** + - Type: Webhook + - Role: Entry point; listens for HTTP POST requests at path `236f9261-dd76-47e7-b09a-2667a0f315bf`. + - Config: Receives JSON body containing email data including mode, from, to, subject, html content. + - Inputs: None + - Outputs: To Check Mode1 + - Edge Cases: Invalid/malformed payload, unauthorized requests (no auth configured here). + - Version: 1 + + - **Check Mode1** + - Type: If + - Role: Determines if the user is "demo" (free) or "pro" based on `mode` field in payload. + - Config: String condition checking if `mode` contains "demo". + - Inputs: From Webhook1 + - Outputs: True branch (demo) -> Google Sheets Read; False branch (pro) -> Send Email (Pro) + - Edge Cases: Missing or unexpected mode value may misroute flow. + - Version: 1 + + - **Send Email (Pro)** + - Type: SendGrid + - Role: Sends the email for pro users without limit checks. + - Config: Uses `from`, `to`, `subject`, `html` from webhook data; sender email hardcoded; content type HTML. + - Inputs: False branch from Check Mode1 + - Outputs: Success Response (Pro)1 + - Credentials: SendGrid API required. + - Edge Cases: SendGrid API failures, invalid emails, quota exceeded. + - Version: 1 + + - **Success Response (Pro)1** + - Type: Respond to Webhook + - Role: Sends JSON success response to pro users after email is sent. + - Config: Response body confirms success with mode "pro". + - Inputs: From Send Email (Pro) node + - Outputs: None (ends flow) + - Edge Cases: Response failures if webhook is closed. + - Version: 1 + +--- + +#### 2.2 User Existence Verification + +- **Overview:** + For demo users, reads Google Sheet to find existing user data, then uses code logic to determine if user exists or not. + +- **Nodes Involved:** + - Google Sheets Read + - Check User Exists2 (Code) + - Check User Exists1 (If) + +- **Node Details:** + + - **Google Sheets Read** + - Type: Google Sheets + - Role: Reads rows from "Email_Tracker" sheet filtering by `Email` matching webhook `from` email. + - Config: Filter `Email` column equals webhook `body.from`. Sheet ID and GID specified. + - Inputs: True branch from Check Mode1 + - Outputs: To Check User Exists2 + - Credentials: Google Sheets OAuth2 required. + - Edge Cases: API limits, missing sheet, no matching rows. + - Version: 4.5 + + - **Check User Exists2** + - Type: Code + - Role: Processes Google Sheet results to determine if user exists; marks existence flag. + - Config: Checks for non-empty Email rows; sets `exists` boolean accordingly. + - Inputs: From Google Sheets Read + - Outputs: To Check User Exists1 + - Edge Cases: Empty result sets, case sensitivity in email. + - Version: 2 + + - **Check User Exists1** + - Type: If + - Role: Branches flow based on user existence flag. + - Config: Boolean condition on `exists` field. + - Inputs: From Check User Exists2 + - Outputs: True (user exists) -> Check Limit Logic; False (new user) -> Create New User1 + - Edge Cases: Improper boolean evaluation, missing flag. + - Version: 2 + +--- + +#### 2.3 Rate Limiting Check + +- **Overview:** + Checks if the demo user has sent fewer than 5 emails today; resets daily counter if needed. + +- **Nodes Involved:** + - Check Limit Logic (Code) + - Can Send?1 (If) + - Limit Reached Response1 + - Update User Count1 + - Create New User1 + +- **Node Details:** + + - **Check Limit Logic** + - Type: Code + - Role: Implements logic to check if daily email count is below 5, resets count on new day, returns updated counters and flags. + - Config: Uses JavaScript Date to compare today's date with last send date; increments or resets send count accordingly; flags canSend boolean. + - Inputs: True branch from Check User Exists1 (user exists) + - Outputs: To Can Send?1 + - Edge Cases: Date format mismatches, missing fields, parsing errors. + - Version: 2 + + - **Can Send?1** + - Type: If + - Role: Branches flow depending on canSend boolean from previous node. + - Config: Boolean condition on `$json.canSend === true` + - Inputs: From Check Limit Logic + - Outputs: True -> Update User Count1; False -> Limit Reached Response1 + - Edge Cases: Missing or malformed canSend field. + - Version: 2 + + - **Limit Reached Response1** + - Type: Respond to Webhook + - Role: Sends HTTP 429 error response indicating daily free email limit reached. + - Config: Response includes error message, limit info, and current count. + - Inputs: From Can Send?1 (false branch) + - Outputs: None (ends flow) + - Edge Cases: Response delivery failures. + - Version: 1 + + - **Update User Count1** + - Type: Google Sheets + - Role: Updates existing user row with incremented daily and total send counts, and last send date. + - Config: Update by matching `Email` column; increments `Total_Sent` by 1; updates `Send_Count` and `Last_Send_Date`. + - Inputs: From Can Send?1 (true branch) + - Outputs: To Send Email (Demo)1 and Telegram Notification1 + - Credentials: Google Sheets OAuth2 required. + - Edge Cases: Update conflicts, concurrency issues, API errors. + - Version: 4 + + - **Create New User1** + - Type: Google Sheets + - Role: Appends new user row for a previously unseen demo user with initial counts set to 1. + - Config: Creates row with email, `Send_Count = 1`, `Total_Sent = 1`, and current date as `Last_Send_Date`. + - Inputs: False branch from Check User Exists1 (new user) + - Outputs: To Telegram Notification1 and Send Email (Demo)1 + - Credentials: Google Sheets OAuth2 required. + - Edge Cases: Append errors, duplicate entries. + - Version: 4 + +--- + +#### 2.4 User Data Update and Email Sending + +- **Overview:** + Sends the demo user email using SendGrid, then sends success response and Telegram notification. + +- **Nodes Involved:** + - Send Email (Demo)1 + - Success Response (Demo)1 + - Telegram Notification1 + +- **Node Details:** + + - **Send Email (Demo)1** + - Type: SendGrid + - Role: Sends the email for demo users after passing the limit checks. + - Config: Uses email parameters from webhook; sender name is the `from` field in webhook; content type HTML. + - Inputs: From Update User Count1 or Create New User1 + - Outputs: To Success Response (Demo)1 + - Credentials: SendGrid API required. + - Edge Cases: API errors, invalid email data. + - Version: 1 + + - **Success Response (Demo)1** + - Type: Respond to Webhook + - Role: Sends JSON success response confirming email sent for demo user, includes remaining emails count for the day. + - Config: Response JSON includes success flag, message, mode "demo", and remaining emails (5 - newCount). + - Inputs: From Send Email (Demo)1 + - Outputs: None (ends flow) + - Edge Cases: Response failures. + - Version: 1 + + - **Telegram Notification1** + - Type: Telegram + - Role: Sends notification message to administrator Telegram chat about demo email sent and remaining quota. + - Config: Custom text including sender, recipient, and remaining emails; uses configured chat ID. + - Inputs: From Update User Count1 and Create New User1 (parallel) + - Outputs: None + - Credentials: Telegram API credentials required. + - Edge Cases: Telegram API errors, invalid chat ID. + - Version: 1.2 + +--- + +### 3. Summary Table + +| Node Name | Node Type | Functional Role | Input Node(s) | Output Node(s) | Sticky Note | +|-----------------------|--------------------|-----------------------------------------------|------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------| +| Webhook1 | Webhook | Receives newsletter data via HTTP POST | None | Check Mode1 | ## 1. Receive data from newsletter page, validate if free or pro user. Process free user and send pro user's message | +| Check Mode1 | If | Checks if user mode is demo or pro | Webhook1 | Google Sheets Read (demo), Send Email (Pro) (pro) | | +| Google Sheets Read | Google Sheets | Reads user data from sheet based on email | Check Mode1 (demo) | Check User Exists2 | | +| Check User Exists2 | Code | Determines if user exists in Google Sheet | Google Sheets Read | Check User Exists1 | | +| Check User Exists1 | If | Branches on existence of user | Check User Exists2 | Check Limit Logic (exists), Create New User1 (not exists) | ## 2. Check if user has used up the 5 free email limit daily. Send error message if exceeded | +| Check Limit Logic | Code | Checks and updates daily send count | Check User Exists1 | Can Send?1 | | +| Can Send?1 | If | Branches on if user can send email or not | Check Limit Logic | Update User Count1 (can send), Limit Reached Response1 (limit reached) | | +| Update User Count1 | Google Sheets | Updates user's send counts in Google Sheet | Can Send?1 (true) | Send Email (Demo)1, Telegram Notification1 | ## 3. Update database, send email and notification to self | +| Create New User1 | Google Sheets | Creates new user entry in Google Sheet | Check User Exists1 (false) | Telegram Notification1, Send Email (Demo)1 | | +| Send Email (Pro) | SendGrid | Sends email for pro users | Check Mode1 (pro) | Success Response (Pro)1 | | +| Success Response (Pro)1| Respond to Webhook | Sends success JSON response to pro user | Send Email (Pro) | None | | +| Send Email (Demo)1 | SendGrid | Sends email for demo users | Update User Count1/Create New User1 | Success Response (Demo)1 | | +| Success Response (Demo)1| Respond to Webhook| Sends success JSON response to demo user | Send Email (Demo)1 | None | | +| Limit Reached Response1| Respond to Webhook | Sends 429 error response when limit reached | Can Send?1 (false) | None | | +| Telegram Notification1 | Telegram | Sends Telegram admin notification | Update User Count1, Create New User1 | None | | +| Sticky Note | Sticky Note | Notes for block 2 (limit check) | None | None | ## 2. Check if user has used up the 5 free email limit daily. Send error message if exceeded | +| Sticky Note1 | Sticky Note | Notes for block 3 (update & notification) | None | None | ## 3. Update database, send email and notification to self | +| Sticky Note2 | Sticky Note | Notes for block 1 (input & validation) | None | None | ## 1. Receive data from newsletter page, validate if free or pro user. Process free user and send pro user's message | +| Sticky Note3 | Sticky Note | Full workflow overview and setup instructions | None | None | ## Email Newsletter Builder with Rate Limiting and User Tracking [Get the Email Newsletter Builder Webform](https://drive.google.com/file/d/1ZipYXImNi8JbwnekzphqHoFKf5Qbhu6g/view?usp=sharing) [Get the Google Sheet Template](https://docs.google.com/spreadsheets/d/1JvsOzkCaJzJN8-x1hldFA-H6iPc0A9MH-mVYBCEWtJw/edit?usp=sharing) | + +--- + +### 4. Reproducing the Workflow from Scratch + +1. **Create Webhook Node:** + - Name: `Webhook1` + - Type: Webhook (HTTP POST) + - Path: `236f9261-dd76-47e7-b09a-2667a0f315bf` + - Response Mode: Response Node + - No authentication configured here (consider adding for production) + +2. **Create If Node to Check Mode:** + - Name: `Check Mode1` + - Type: If + - Condition: String contains + - Value1: `{{$json.body.mode}}` + - Value2: `demo` + - Connect `Webhook1` main output to `Check Mode1` input. + +3. **Create Google Sheets Read Node:** + - Name: `Google Sheets Read` + - Type: Google Sheets (Read) + - Document ID: Your Google Sheet ID (e.g., `1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q`) + - Sheet Name: `Sheet1` (gid=0) + - Filters: Filter by column `Email` equals `={{ $json.body.from }}` + - Credentials: Configure Google Sheets OAuth2 API + - Connect `Check Mode1` TRUE output (demo) to this node. + +4. **Create Code Node to Check User Exists:** + - Name: `Check User Exists2` + - Type: Code + - Code: + ```javascript + const email = $node["Webhook1"].json.body.from.toLowerCase(); + const realRows = items.filter(item => item.json.Email && item.json.Email.trim() !== ''); + if (realRows.length > 0) { + return realRows.map(item => ({ json: {...item.json, email, exists: true} })); + } + return [{ json: { email, exists: false, matches: 0 } }]; + ``` + - Connect `Google Sheets Read` to this node. + +5. **Create If Node to Branch on User Existence:** + - Name: `Check User Exists1` + - Type: If + - Condition: Boolean + - Left Value: `={{ $json.exists }}` + - Operation: Equals `true` + - Connect `Check User Exists2` output to this node. + +6. **Create Code Node for Limit Check:** + - Name: `Check Limit Logic` + - Type: Code + - Code: + ```javascript + const today = new Date().toISOString().split('T')[0]; + const userDate = $input.item.json.Last_Send_Date; + const sendCount = parseInt($input.item.json.Send_Count) || 0; + let newCount1 = sendCount; + let newCount = $input.item.json.Total_Sent; + let canSend = false; + if (userDate === today) { + if (sendCount < 5) { + canSend = true; + newCount1 = sendCount + 1; + } + } else { + canSend = true; + newCount1 = 1; + } + return { + canSend, + Total_Sent: newCount, + Send_Count: newCount1, + Email: $input.item.json.Email, + rowNumber: $input.item.json.row_number, + Last_Send_Date: today + }; + ``` + - Connect TRUE output from `Check User Exists1` to this node. + +7. **Create If Node for Can Send?:** + - Name: `Can Send?1` + - Type: If + - Condition: Boolean equals `true` on `{{$json.canSend}}` + - Connect `Check Limit Logic` output to this node. + +8. **Create Google Sheets Update Node:** + - Name: `Update User Count1` + - Type: Google Sheets (Update) + - Document ID and Sheet Name same as before + - Matching Column: `Email` + - Columns to update: + - Email: `{{$json.Email}}` + - Send_Count: `{{$json.Send_Count}}` + - Total_Sent: `{{$json.Total_Sent + 1}}` + - Last_Send_Date: `{{$json.Last_Send_Date}}` + - row_number: 0 (read-only, ignored in update) + - Connect TRUE output of `Can Send?1` to this node. + +9. **Create Google Sheets Append Node for New Users:** + - Name: `Create New User1` + - Type: Google Sheets (Append) + - Columns: + - Email: `{{$node["Webhook1"].item.json.body.from}}` + - Send_Count: 1 + - Total_Sent: 1 + - Last_Send_Date: `{{$now.format("yyyy-MM-dd")}}` + - Connect FALSE output of `Check User Exists1` here. + +10. **Create SendGrid Node to Send Demo Email:** + - Name: `Send Email (Demo)1` + - Type: SendGrid + - Parameters: + - Subject: `{{$node["Webhook1"].item.json.body.subject}}` + - To Email: `{{$node["Webhook1"].item.json.body.to}}` + - From Name: `{{$node["Webhook1"].item.json.body.from}}` + - From Email: Your verified sender email address + - Content Type: `text/html` + - Content Value: `{{$node["Webhook1"].item.json.body.html}}` + - Credentials: SendGrid API credentials required + - Connect outputs of `Update User Count1` and `Create New User1` to this node. + +11. **Create Success Response Node for Demo:** + - Name: `Success Response (Demo)1` + - Type: Respond to Webhook + - Response Mode: JSON + - Response Body: + ```json + { + "success": true, + "message": "Email sent successfully!", + "mode": "demo", + "remaining": 5 - {{$json.Send_Count}} + } + ``` + - Connect output of `Send Email (Demo)1` here. + +12. **Create Limit Reached Response Node:** + - Name: `Limit Reached Response1` + - Type: Respond to Webhook + - HTTP Response Code: 429 + - Response Mode: JSON + - Response Body: + ```json + { + "success": false, + "error": "Daily limit reached (5 emails/day)", + "message": "You've reached your daily limit. Upgrade to Pro for unlimited sends!", + "current_count": {{$json.Send_Count}} + } + ``` + - Connect FALSE output of `Can Send?1` here. + +13. **Create Telegram Notification Node:** + - Name: `Telegram Notification1` + - Type: Telegram + - Chat ID: Your Telegram chat ID + - Text: + ``` + 📧 Demo email sent from: {{$node["Webhook1"].item.json.body.from}} + ✉️ To: {{$node["Webhook1"].item.json.body.to}} + 📊 Remaining today: {{5 - $json.Send_Count}} + ``` + - Credentials: Telegram Bot API credentials required + - Connect outputs of `Update User Count1` and `Create New User1` here. + +14. **Connect Pro User Branch:** + - Connect FALSE output of `Check Mode1` to `Send Email (Pro)`. + - Configure `Send Email (Pro)` similarly to demo email node but with fixed `From Name` "Pro User". + - Connect `Send Email (Pro)` output to `Success Response (Pro)1` node. + +15. **Test the workflow end-to-end** ensuring correct data flows and credentials are valid. + +--- + +### 5. General Notes & Resources + +| Note Content | Context or Link | +|------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------| +| Email Newsletter Builder with Rate Limiting and User Tracking. Setup instructions and webform & sheet templates included. | See Sticky Note3 content inside the workflow JSON. | +| Register on SendGrid and link the API key to SendGrid nodes for email sending. | https://login.sendgrid.com/login/ | +| Create a Telegram bot and get chat ID for notification node credentials. | https://web.telegram.org/a/ | +| Download the Email Newsletter Builder Webform template. | https://drive.google.com/file/d/1ZipYXImNi8JbwnekzphqHoFKf5Qbhu6g/view?usp=sharing | +| Download the Google Sheet Template for tracking user email sends. | https://docs.google.com/spreadsheets/d/1JvsOzkCaJzJN8-x1hldFA-H6iPc0A9MH-mVYBCEWtJw/edit?usp=sharing | + +--- + +**Disclaimer:** The provided text originates exclusively from an automated n8n workflow and adheres strictly to content policies. It contains no illegal or offensive elements. All data handled is legal and public. \ No newline at end of file