This workflow follows the Google Sheets → OpenAI recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "b717d887-4d4b-4f21-97a3-978fcde2c9f6",
"name": "slack_action_payload",
"type": "n8n-nodes-base.set",
"position": [
-1020,
100
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "= {{ $json.body.payload }}"
},
"typeVersion": 3.4
},
{
"id": "046950ad-a40c-47d9-8dab-406bc6bf6e12",
"name": "slack_action_drink_data",
"type": "n8n-nodes-base.set",
"position": [
-800,
100
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3d208143-1b80-4701-bff7-fc1dfbf9b89c",
"name": "value",
"type": "string",
"value": "={{ $json.actions[0].value }}"
},
{
"id": "1600b553-8ef1-44ac-9ae7-d33be8e539e5",
"name": "message_text",
"type": "string",
"value": "={{ $json.message.text }}"
},
{
"id": "5ea5f093-7e36-4de0-aa14-fb2bc0788e84",
"name": "shortcut_url",
"type": "string",
"value": "=shortcuts://run-shortcut?name=darrell_water&input="
},
{
"id": "5d9e4946-10eb-48ed-87d8-978235d44ec1",
"name": "shortcut_url_data",
"type": "string",
"value": "={\"value\":{{ $json.actions[0].value }},\"time\":\"{{ $now.format(\"yyyy-MM-dd\") }}T{{ $now.format(\"HH:mm:ss\") }}\"}"
},
{
"id": "625258d8-55eb-4252-b313-b4954da57de1",
"name": "message_ts",
"type": "string",
"value": "={{ $json.container.message_ts }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f90ec31c-b63e-470c-84ba-9429539d6bf4",
"name": "OpenAI",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
140,
-800
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {
"temperature": 1
},
"messages": {
"values": [
{
"content": "=Remind to drink water, the last time you drank water was {{ DateTime.fromISO($('combine data').item.json.date +\"T\"+$('combine data').item.json.time).format('yyyy-MM-dd HH:mm:ss') }}\nThe current time is {{ $now.format('yyyy-MM-dd HH:mm:ss') }}\nThe user has drunk water {{ $('combine data').item.json.count_date }} times today"
},
{
"role": "assistant",
"content": "You are a gentle and professional Chinese medicine practitioner who provides health advice in a friendly, encouraging tone. Please generate a response in JSON format with the structure {\"message\": \"...\"}, keeping the message brief (<100-200 words), persuasive, reminding me to drink water, clearly specifying intervals (such as 2 hours), and mentioning at least one benefit of drinking water (such as replenishing qi) and one negative effect of dehydration (such as blood stasis), encouraging me to take action to drink water, ending with an action prompt. Start directly without using any form of address. "
},
{
"role": "system",
"content": "must return {\\\"message\\\": \\\"...\\\"} and **responding in English**"
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "28fe1f82-a8d6-4a9a-9061-ec94a7344fa3",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1260,
-800
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "=0 {{ Math.floor(Math.random() * 11) }} 8-23 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "ef12fb27-4377-42be-b9bc-bdbaaaa4c754",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
-840,
-640
],
"parameters": {
"keep": "lastItems"
},
"typeVersion": 1
},
{
"id": "e36862e2-912f-4e41-80b0-6f66cc8ba0ba",
"name": "Google Sheets - Get Target",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1040,
-820
],
"parameters": {
"options": {
"returnFirstMatch": false
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 2141999480,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI/edit#gid=2141999480",
"cachedResultName": "setting"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI/edit?usp=drivesdk",
"cachedResultName": "n8n-drink-water"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "9809c9bd-51ff-4277-9f0f-5e1438c25fe8",
"name": "Summarize",
"type": "n8n-nodes-base.summarize",
"position": [
-840,
-500
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "value",
"aggregation": "sum"
},
{
"field": "date"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "ca995a95-9c35-43e4-ab68-0f7aa44f99d1",
"name": "combine data",
"type": "n8n-nodes-base.merge",
"position": [
-620,
-800
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition",
"numberInputs": 3
},
"typeVersion": 3
},
{
"id": "44da169c-a2da-427c-aa46-54082b27e94b",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-200,
-800
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "350fc192-3049-407a-b468-bfdcfbdde966",
"operator": {
"type": "dateTime",
"operation": "after"
},
"leftValue": "={{ DateTime.fromISO($('combine data').item.json.date +\"T\"+$('combine data').item.json.time).format('yyyy-MM-dd HH:mm:ss') }}",
"rightValue": "={{ $now.minus(30, \"minutes\") }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "bc85d85a-cee2-43ab-a434-b26c5cd69122",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"notes": "If the user log water recently. \nWait for another 3x minutes",
"position": [
-20,
-640
],
"parameters": {
"unit": "minutes",
"amount": "={{ Math.floor(Math.random() * 11) + 21 }}"
},
"notesInFlow": true,
"typeVersion": 1.1
},
{
"id": "551c217e-9192-486e-ae9f-068bebd0792a",
"name": "slack drink webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-1200,
100
],
"parameters": {
"path": "f992f346-0076-4a79-a046-5b5c295bf6c2",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "c000d036-7246-47a5-9001-ffc482c74371",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1340,
-960
],
"parameters": {
"width": 1060,
"height": 620,
"content": "## Grab recent drink data\n"
},
"typeVersion": 1
},
{
"id": "fd4bdbf4-c2d0-497c-891e-2667a85fa2ad",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-260,
-960
],
"parameters": {
"color": 2,
"width": 360,
"height": 500,
"content": "If already drink recently. Delay the notification in 3x minutes randomly\n"
},
"typeVersion": 1
},
{
"id": "cd4b4928-a858-4f12-b294-51ba8a4484da",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
120,
-960
],
"parameters": {
"color": 5,
"width": 580,
"height": 360,
"content": "## Send the slack notification with AI wording. Also have the drink water action buttons"
},
"typeVersion": 1
},
{
"id": "cc7c8459-a97d-4ee9-b97c-b4a95afecf5a",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1340,
-320
],
"parameters": {
"color": 3,
"width": 1300,
"height": 660,
"content": "## When User interact the drink button. Record the drink value to sheet and send back the iOS health log water url to start the shortcut\n\n**Note for Shortcut:**\n\nThe shortcul url will be like `shortcuts://run-shortcut?name=darrell_water&input=%7B%22value%22%3A100%2C%22time%22%3A%222025-03-04T16%3A10%3A15%22%7D`\n\nIt's url encoded. The decoded version will be:\n`shortcuts://run-shortcut?name=darrell_water&input={\"value\":100,\"time\":\"2025-03-04T16:10:15\"}`\n\nWe can see it pass the shortcut name and input with json string value. This will be used in iOS shortcut"
},
"typeVersion": 1
},
{
"id": "e8e388e0-dddc-4db2-b5fa-acb76d025580",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1700,
-960
],
"parameters": {
"color": 7,
"width": 340,
"height": 240,
"content": "## Created by darrell_tw_ \n\nAn engineer now focus on AI and Automation\n\n### contact me with following:\n[X](https://x.com/darrell_tw_)\n[Threads](https://www.threads.net/@darrell_tw_)\n[Instagram](https://www.instagram.com/darrell_tw_/)\n[Website](https://www.darrelltw.com/)"
},
"typeVersion": 1
},
{
"id": "32b098ea-a72f-4906-9a39-916afcf47dc8",
"name": "Slack send drink notification",
"type": "n8n-nodes-base.slack",
"position": [
480,
-800
],
"parameters": {
"text": "\u559d\u6c34\u63d0\u9192",
"select": "channel",
"blocksUi": "={\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"{{ $json.message.content.message ? $json.message.content.message : 'Time to drink\uff01' }}\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"{{ $('Edit Fields-Set progress').item.json.progress_image }}\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"actions\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"emoji\": true,\n\t\t\t\t\t\t\"text\": \"100\"\n\t\t\t\t\t},\n\t\t\t\t\t\"style\": \"primary\",\n\t\t\t\t\t\"value\": \"100\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"emoji\": true,\n\t\t\t\t\t\t\"text\": \"150\"\n\t\t\t\t\t},\n\t\t\t\t\t\"style\": \"primary\",\n\t\t\t\t\t\"value\": \"150\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"emoji\": true,\n\t\t\t\t\t\t\"text\": \"200\"\n\t\t\t\t\t},\n\t\t\t\t\t\"style\": \"primary\",\n\t\t\t\t\t\"value\": \"200\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"emoji\": true,\n\t\t\t\t\t\t\"text\": \"250\"\n\t\t\t\t\t},\n\t\t\t\t\t\"style\": \"primary\",\n\t\t\t\t\t\"value\": \"250\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"emoji\": true,\n\t\t\t\t\t\t\"text\": \"300\"\n\t\t\t\t\t},\n\t\t\t\t\t\"style\": \"primary\",\n\t\t\t\t\t\"value\": \"300\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C08FW6YKVC1",
"cachedResultName": "n8n-drink-water-nofity-demo"
},
"messageType": "block",
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "8f550d8f-b960-41df-8a3b-2443327d5892",
"name": "Send to Slack with confirm",
"type": "n8n-nodes-base.slack",
"position": [
-560,
0
],
"parameters": {
"text": "=Log Successfully",
"select": "channel",
"blocksUi": "={\n\t\"blocks\": [\n {\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Already log the water\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Click me to Shortcut\"\n\t\t\t},\n\t\t\t\"accessory\": {\n\t\t\t\t\"type\": \"button\",\n\t\t\t\t\"text\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"iOS Health\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"value\": \"click\",\n\t\t\t\t\"url\": \"{{ $('slack_action_drink_data').item.json.shortcut_url}}{{ $('slack_action_drink_data').item.json.shortcut_url_data.urlEncode() }}\",\n\t\t\t\t\"action_id\": \"button-action\"\n\t\t\t}\n\t\t}\n\t]\n}",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C08FW6YKVC1",
"cachedResultName": "n8n-drink-water-nofity-demo"
},
"messageType": "block",
"otherOptions": {
"thread_ts": {
"replyValues": {
"thread_ts": "={{ $('slack_action_drink_data').item.json.message_ts }}"
}
}
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "3383574c-7c96-4332-9876-2e47ad21f3de",
"name": "Edit Fields-Set progress",
"type": "n8n-nodes-base.set",
"position": [
-420,
-800
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "427f1878-99a0-446a-b4a2-2c49c919c809",
"name": "progress_percent",
"type": "number",
"value": "={{ ($json.sum_value/$json.target) }}"
},
{
"id": "3fd85387-6ad3-4f4a-92ee-1db7e84f065b",
"name": "progress_image",
"type": "string",
"value": "={{ (function() { let p = $json.sum_value / $json.target; let n = Math.round(p * 10); n = Math.max(0, Math.min(10, n)); return '\ud83d\udca7'.repeat(n) + '\u2b1c'.repeat(10 - n); })() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "67fa160d-0ea2-48c2-83b5-2f5f1b6a01b5",
"name": "Google Sheets - log water value to sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-560,
180
],
"parameters": {
"columns": {
"value": {
"date": "={{ $now.format('yyyy-MM-dd') }}",
"time": "={{ $now.format('HH:mm:ss') }}",
"value": "={{ $json.value }}"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "time",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "time",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "value",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "value",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI/edit?usp=drivesdk",
"cachedResultName": "n8n-drink-water"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "6d336f63-0016-46ae-b71f-2e1dfac06826",
"name": "Google Sheets - Get Today Water Log",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1040,
-640
],
"parameters": {
"options": {
"returnFirstMatch": false
},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $now.format('yyyy-MM-dd') }}",
"lookupColumn": "date"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI/edit#gid=0",
"cachedResultName": "log"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NRPq87zvNiBGKzVJaT0YYc55qp-6-9kGA4VpqkylpbI/edit?usp=drivesdk",
"cachedResultName": "n8n-drink-water"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
}
],
"connections": {
"If": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
],
[
{
"node": "OpenAI",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "OpenAI",
"type": "main",
"index": 0
}
]
]
},
"Limit": {
"main": [
[
{
"node": "combine data",
"type": "main",
"index": 1
}
]
]
},
"OpenAI": {
"main": [
[
{
"node": "Slack send drink notification",
"type": "main",
"index": 0
}
]
]
},
"Summarize": {
"main": [
[
{
"node": "combine data",
"type": "main",
"index": 2
}
]
]
},
"combine data": {
"main": [
[
{
"node": "Edit Fields-Set progress",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Google Sheets - Get Target",
"type": "main",
"index": 0
},
{
"node": "Google Sheets - Get Today Water Log",
"type": "main",
"index": 0
}
]
]
},
"slack drink webhook": {
"main": [
[
{
"node": "slack_action_payload",
"type": "main",
"index": 0
}
]
]
},
"slack_action_payload": {
"main": [
[
{
"node": "slack_action_drink_data",
"type": "main",
"index": 0
}
]
]
},
"slack_action_drink_data": {
"main": [
[
{
"node": "Google Sheets - log water value to sheet",
"type": "main",
"index": 0
},
{
"node": "Send to Slack with confirm",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields-Set progress": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets - Get Target": {
"main": [
[
{
"node": "combine data",
"type": "main",
"index": 0
}
]
]
},
"Send to Slack with confirm": {
"main": [
[]
]
},
"Google Sheets - Get Today Water Log": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
},
{
"node": "Summarize",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2ApiopenAiApislackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow ensures your automated processes never exceed predefined limits by intelligently monitoring and pausing operations, saving you from unnecessary resource waste and potential overruns. It's ideal for teams managing repetitive tasks like data processing or notifications, particularly those using Google Sheets for tracking and OpenAI for decision-making. The key step involves the Limit node, which checks against thresholds pulled from Google Sheets before proceeding, allowing seamless integration with tools like Slack for alerts on nearing limits.
Use this workflow for scheduled jobs, such as daily data syncs or AI-driven summaries, where you need to cap executions to stay within budgets or quotas. Avoid it for real-time, high-volume streams that require instant responses rather than cron-based timing. Common variations include adapting the limit checks for email campaigns via Gmail or scaling pauses for API rate limits in custom scripts.
About this workflow
Wait Limit. Uses openAi, scheduleTrigger, limit, googleSheets. Scheduled trigger; 21 nodes.
Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow monitors your Gmail support inbox every minute, automatically sending each unread email to OpenAI for intelligent analysis. The AI evaluates sentiment (Positive/Neutral/Negative/Critical
YouTube to X Post- AlexK1919. Uses twitter, stickyNote, youTube, toolCalculator. Scheduled trigger; 28 nodes.
AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs and upload to all social networks. Uses httpRequest, openAi, stickyNote, googleDrive. Scheduled trigger; 51 nodes.
AI Automated TikTok/Youtube Shorts/Reels Generator. Uses httpRequest, openAi, stickyNote, googleDrive. Scheduled trigger; 41 nodes.
Splitout Code. Uses googleSheetsTrigger, httpRequest, splitInBatches, googleSheets. Event-driven trigger; 35 nodes.