This workflow corresponds to n8n.io template #15204 — we link there as the canonical source.
This workflow follows the Agent → Gmail 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 →
{
"id": "6SmexSPg5EApcVTo",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI-Powered Wealth Management",
"tags": [],
"nodes": [
{
"id": "09bdd0fa-1be8-4151-84ec-fca21d83cfb7",
"name": "Trigger: Portfolio Updated",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
-432,
208
],
"parameters": {
"event": "rowUpdate",
"options": {
"columnsToWatch": [
"Trigger_Status"
]
},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug/edit#gid=0",
"cachedResultName": "\u0936\u0940\u091f1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug/edit?usp=drivesdk",
"cachedResultName": "Wealth Management - Portfolio Updates"
}
},
"credentials": {
"googleSheetsTriggerOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "b7107526-0faf-4824-aabb-0dc5d996bcc0",
"name": "Parse Trades & Tickers",
"type": "n8n-nodes-base.code",
"position": [
-208,
208
],
"parameters": {
"jsCode": "for (const item of $input.all()) {\n // 1. Parse the stringified trades from Google Sheets into a real JSON object\n const trades = JSON.parse(item.json.Trades_Made);\n item.json.trades_parsed = trades;\n\n // 2. Extract just the ticker symbols (e.g., \"AAPL,NVDA\") for our News API\n const tickers = trades.map(trade => trade.ticker).join(',');\n item.json.tickers_list = tickers;\n}\nreturn $input.all();"
},
"typeVersion": 2
},
{
"id": "3f48d70c-d38c-481b-848f-746412aadd60",
"name": "Mock: Client Risk Profile",
"type": "n8n-nodes-base.set",
"position": [
16,
208
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "4a0267ba-97ed-46be-8fa1-b7be9107332a",
"name": "Client_Risk_Profile",
"type": "string",
"value": "Conservative"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "01655eee-4c00-4e96-aeef-c7410c79eaef",
"name": "Mock: Market Context",
"type": "n8n-nodes-base.set",
"position": [
240,
208
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "8a88e3df-e1c5-4cce-ade2-6cf2a9e7d4b0",
"name": "Market_Context",
"type": "string",
"value": "Tech stocks are currently experiencing high volatility due to supply chain issues. We are shifting capital towards more stable, high-demand sectors like defense and AI infrastructure."
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "a2a5d510-ffb3-4f2b-983a-eeff39dd0a74",
"name": "AI: Draft Client Email",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
464,
208
],
"parameters": {
"text": "=You are a senior wealth management advisor. Write a concise, professional and easy-to-understand email to your client explaining recent changes to their portfolio. \n\nDo not use overly complex financial jargon. Adjust your tone based on the client's risk profile.\n\nHere is the context for the email:\nClient Name: {{ $json.Client_Name }}\nClient Risk Profile: {{ $json.Client_Risk_Profile }}\nRecent Market News: {{ $json.Market_Context }}\nTrades Executed: {{ JSON.stringify($json.trades_parsed) }}\n\nFormat the email with:\n1. A polite greeting.\n2. What changed in their portfolio.\n3. Why we made the change (reference the market news).\n4. The expected impact on their portfolio.\n5. A professional sign-off.",
"options": {},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "087de054-d7d8-44d8-adad-e2d9c79b339f",
"name": "LLM: Gemini",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
464,
416
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "c5a83320-1dd4-4677-aab3-caa35a5ecb08",
"name": "Slack: Request Advisor Approval",
"type": "n8n-nodes-base.slack",
"position": [
816,
208
],
"parameters": {
"text": "= *New Portfolio Update Draft for {{ $('Mock: Market Context').item.json.Client_Name }}* *Drafted Email:* > {{ $json.output }} *Action Required:* <{{ $execution.resumeUrl }}?action=approve|Approve & Send to Client> <{{ $execution.resumeUrl }}?action=reject|Reject & Discard>\n\n",
"user": {
"__rl": true,
"mode": "id",
"value": "U0AP17N3QRY"
},
"select": "user",
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.4
},
{
"id": "291ae347-4121-487f-bacf-57ce07307817",
"name": "Wait: Advisor Action",
"type": "n8n-nodes-base.wait",
"position": [
1040,
208
],
"parameters": {
"resume": "webhook",
"options": {},
"resumeUnit": "days",
"resumeAmount": 2,
"limitWaitTime": true
},
"typeVersion": 1.1
},
{
"id": "781ced2c-33ee-4305-84b6-7e7fef34ac4b",
"name": "Route: Approve vs Reject",
"type": "n8n-nodes-base.switch",
"position": [
1264,
208
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "29be4920-80af-467f-80a5-31e84a4da0a9",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.query.action }}",
"rightValue": "approve"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "25305078-bc02-4569-8014-569af3f37d0f",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "= {{ $json.query.action }}",
"rightValue": "reject"
}
]
}
}
]
},
"options": {
"fallbackOutput": 1
}
},
"typeVersion": 3.4
},
{
"id": "946e95f0-b396-4581-a779-8d681cc93840",
"name": "Gmail: Send to Client",
"type": "n8n-nodes-base.gmail",
"position": [
1488,
112
],
"parameters": {
"sendTo": "user@example.com",
"message": "={{ $('AI: Draft Client Email').item.json.output }}",
"options": {
"appendAttribution": false
},
"subject": "Important Update Regarding Your Portfolio",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "c35846b1-170e-4a68-8147-14acd7e39b27",
"name": "Sheet: Mark as Completed",
"type": "n8n-nodes-base.googleSheets",
"position": [
1712,
112
],
"parameters": {
"columns": {
"value": {
"Client_ID": "={{ $('Trigger: Portfolio Updated').item.json.Client_ID }}",
"Trigger_Status": "Completed"
},
"schema": [
{
"id": "Client_ID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Client_ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client_Name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Client_Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Trades_Made",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Trades_Made",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Trigger_Status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Trigger_Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Client_ID"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug/edit#gid=0",
"cachedResultName": "\u0936\u0940\u091f1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug/edit?usp=drivesdk",
"cachedResultName": "Wealth Management - Portfolio Updates"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "f63ac374-88cd-4eed-9bb9-14fbaf1fffab",
"name": "Slack: Draft Rejected Alert",
"type": "n8n-nodes-base.slack",
"position": [
1488,
320
],
"parameters": {
"text": "= *Draft discarded.* The AI-generated email for {{ $('Parse Trades & Tickers').item.json.Client_Name }} was rejected and has not been sent. Please reach out to the client manually.",
"user": {
"__rl": true,
"mode": "id",
"value": "U0AP17N3QRY"
},
"select": "user",
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.4
},
{
"id": "dbbce757-21f5-429e-a6b5-497df3f764de",
"name": "Sheet: Mark 'Needs Review'",
"type": "n8n-nodes-base.googleSheets",
"position": [
1712,
320
],
"parameters": {
"columns": {
"value": {
"Client_ID": "={{ $('Trigger: Portfolio Updated').item.json.Client_ID }}",
"Trigger_Status": "Needs Manual Review"
},
"schema": [
{
"id": "Client_ID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Client_ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client_Name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Client_Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Trades_Made",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Trades_Made",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Trigger_Status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Trigger_Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Client_ID"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug/edit#gid=0",
"cachedResultName": "\u0936\u0940\u091f1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zvjvsgxrtNQSeULTIs21Be0p2xzTZMU-mxFsV_B46ug/edit?usp=drivesdk",
"cachedResultName": "Wealth Management - Portfolio Updates"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "63a49551-adbf-4810-8779-d4f8a5e6100b",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-832,
-432
],
"parameters": {
"width": 688,
"height": 496,
"content": "## AI-Powered Wealth Management\n\n## How it works:\nThis workflow detects when a client's portfolio is updated in Google Sheets. It formats the trade data, pulls the client's risk profile and uses an AI Agent to draft a personalized explanation email. The workflow pauses and sends the draft to an advisor via Slack. It only emails the client if the advisor clicks \"Approve.\"\n\n## Setup steps:\n\nConnect Google Sheets credentials to the Trigger and both Update nodes.\n\nConnect your AI model credentials (e.g., Google Gemini / OpenAI) to the Chat Model node.\n\nConnect Slack credentials and set the correct Advisor Channel ID.\n\nAdd your email credentials to the Gmail node."
},
"typeVersion": 1
},
{
"id": "b02193de-e1de-4883-b94a-f7c8bbca9aff",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-512,
80
],
"parameters": {
"color": 7,
"width": 912,
"height": 320,
"content": "## Data Ingestion & Formatting\nWatches Google Sheets for \"Pending\" portfolio changes. It parses the raw trade data into a clean JSON format and attaches the client's risk profile and market context."
},
"typeVersion": 1
},
{
"id": "3575740e-88fd-4e7e-8982-4a4bb5a8dbef",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
80
],
"parameters": {
"color": 7,
"width": 960,
"height": 320,
"content": "## AI Drafting & Human-in-the-Loop\nThe AI writes a personalized client email based on the context. The workflow then halts (Wait node) and sends a Slack message with Approve/Reject links to the advisor."
},
"typeVersion": 1
},
{
"id": "274b5029-08aa-49a7-b922-0cff0513f299",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1440,
-64
],
"parameters": {
"color": 7,
"width": 496,
"height": 560,
"content": "## Execution & Logging\nRoutes based on the advisor's click.\nApproved: Emails the client and marks the sheet \"Completed.\"\nRejected: Alerts the advisor to handle manually and marks the sheet \"Needs Review.\""
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "566316e5-53dd-415b-a93b-b427ec148a90",
"connections": {
"LLM: Gemini": {
"ai_languageModel": [
[
{
"node": "AI: Draft Client Email",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Mock: Market Context": {
"main": [
[
{
"node": "AI: Draft Client Email",
"type": "main",
"index": 0
}
]
]
},
"Wait: Advisor Action": {
"main": [
[
{
"node": "Route: Approve vs Reject",
"type": "main",
"index": 0
}
]
]
},
"Gmail: Send to Client": {
"main": [
[
{
"node": "Sheet: Mark as Completed",
"type": "main",
"index": 0
}
]
]
},
"AI: Draft Client Email": {
"main": [
[
{
"node": "Slack: Request Advisor Approval",
"type": "main",
"index": 0
}
]
]
},
"Parse Trades & Tickers": {
"main": [
[
{
"node": "Mock: Client Risk Profile",
"type": "main",
"index": 0
}
]
]
},
"Route: Approve vs Reject": {
"main": [
[
{
"node": "Gmail: Send to Client",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack: Draft Rejected Alert",
"type": "main",
"index": 0
}
]
]
},
"Mock: Client Risk Profile": {
"main": [
[
{
"node": "Mock: Market Context",
"type": "main",
"index": 0
}
]
]
},
"Trigger: Portfolio Updated": {
"main": [
[
{
"node": "Parse Trades & Tickers",
"type": "main",
"index": 0
}
]
]
},
"Slack: Draft Rejected Alert": {
"main": [
[
{
"node": "Sheet: Mark 'Needs Review'",
"type": "main",
"index": 0
}
]
]
},
"Slack: Request Advisor Approval": {
"main": [
[
{
"node": "Wait: Advisor Action",
"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.
gmailOAuth2googlePalmApigoogleSheetsOAuth2ApigoogleSheetsTriggerOAuth2ApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n workflow automates the transition from raw financial trade data to professional client communication. It monitors a Google Sheet for portfolio changes, uses Gemini AI to draft a personalized, risk-aware explanation email and sends it to an advisor via Slack for manual…
Source: https://n8n.io/workflows/15204/ — 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.
Consultants, agencies, freelancers, and project managers who want to ensure proposals, emails, and tasks are followed up on time.
candidature. Uses agent, lmChatGoogleGemini, googleSheetsTrigger, gmail. Event-driven trigger; 18 nodes.
For software engineers, QA teams, and tech leads who want to automate intelligent code reviews with both AI-driven suggestions and rule-based linting — all managed in Google Sheets with instant Slack
Turn employee recognition into an automated system.
This n8n workflow instantly captures support issues submitted via Jotform and efficiently routes them to the appropriate team and logging system based on the severity level defined by the customer. It