This workflow corresponds to n8n.io template #14557 — 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 →
{
"nodes": [
{
"id": "c4bc0a6a-6330-458f-a785-e6640da45af8",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
4784,
3232
],
"parameters": {
"path": "YOUR_N8N_WEBHOOK_ID",
"options": {}
},
"typeVersion": 2.1
},
{
"id": "0b55dd8e-532a-4206-8b6d-072269df3c6e",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"position": [
5008,
3232
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a9cff018-da54-45c7-82fd-0576d754cf7b",
"name": "user_id",
"type": "string",
"value": "={{ $json.body.user_id }}"
},
{
"id": "ccf16cef-71f7-444b-b995-9251b8705ef3",
"name": "name",
"type": "string",
"value": "={{ $json.body.name }}"
},
{
"id": "f0d3ec24-8bf4-4f6f-abf7-3232d131a192",
"name": "email",
"type": "string",
"value": "={{ $json.body.email }}"
},
{
"id": "c85af0ff-e27f-4b69-af6e-753c33fee463",
"name": "plan",
"type": "string",
"value": "={{ $json.body.plan }}"
},
{
"id": "cba8c49c-bb7a-4a09-a860-5d56fce44d30",
"name": "usage_limit",
"type": "number",
"value": "={{ $json.body.usage_limit }}"
},
{
"id": "71755007-e7c9-4d25-8adb-7900e200cb3a",
"name": "usage",
"type": "number",
"value": "={{ $json.body.usage }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "3ec59816-3336-45c2-9246-3bcd810efebb",
"name": "Groq Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
5296,
3424
],
"parameters": {
"model": "llama-3.3-70b-versatile",
"options": {}
},
"typeVersion": 1
},
{
"id": "2ff0b8b7-ffed-4476-9a78-acc67e0839bf",
"name": "Search contacts",
"type": "n8n-nodes-base.hubspot",
"position": [
5856,
3232
],
"parameters": {
"operation": "search",
"authentication": "appToken",
"filterGroupsUi": {
"filterGroupsValues": [
{
"filtersUi": {
"filterValues": [
{
"value": "={{ $('Edit Fields').item.json.email }}",
"propertyName": "email|string"
}
]
}
}
]
},
"additionalFields": {}
},
"typeVersion": 2.2
},
{
"id": "f4a16693-94e7-47c4-94e0-5b6efcfbdc1a",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
6080,
3232
],
"parameters": {
"url": "https://api.hubapi.com/crm/v3/objects/notes",
"method": "POST",
"options": {},
"jsonBody": "={\n \"properties\": {\n \"hs_timestamp\": \"2026-11-12T15:48:22Z\",\n \"hs_note_body\": \"Upsell Opportunity. User have exceeded the limit.\"\n },\n \"associations\": [\n {\n \"to\": {\n \"id\": \"{{ $json.id }}\"\n },\n \"types\": [\n {\n \"associationCategory\": \"HUBSPOT_DEFINED\",\n \"associationTypeId\": 202\n }\n ]\n }\n ]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "YOUR_HUBSPOT_ACCESS_TOKEN"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "3e0e2687-dfa8-43fa-babb-374039db031e",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
5264,
3232
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "cb4dc3f5-33c4-4d86-a73b-bd96200d0805",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
5216,
2816
],
"parameters": {
"color": 7,
"width": 544,
"height": 768,
"content": "## Step 2: AI Email Generation\n\nGenerates a personalized upsell email and sends it via Gmail."
},
"typeVersion": 1
},
{
"id": "6b40fa23-7e2a-40b3-825c-9ca293e073eb",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
5792,
2816
],
"parameters": {
"color": 7,
"width": 464,
"height": 768,
"content": "## Step 3: CRM Update\n\nFinds the contact in HubSpot and logs the upsell activity."
},
"typeVersion": 1
},
{
"id": "5ee3aaf9-2cc7-4197-bdbc-025d30ea4061",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
6288,
2816
],
"parameters": {
"color": 7,
"width": 368,
"height": 768,
"content": "## Step 4: Team Notification\n\nSends a Slack alert to notify the team for follow-up."
},
"typeVersion": 1
},
{
"id": "b45b0731-542d-4449-ba9e-57042615d47b",
"name": "Send a message5",
"type": "n8n-nodes-base.gmail",
"position": [
5616,
3232
],
"parameters": {
"sendTo": "={{ $('Edit Fields').item.json.email }}",
"message": "=<!DOCTYPE html>\n<html>\n<body style=\"margin:0; padding:20px; font-family: Arial, sans-serif; background-color:#f4f6f8;\">\n\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n <tr>\n <td align=\"center\">\n\n <table width=\"600\" cellpadding=\"20\" cellspacing=\"0\" style=\"background:#ffffff; border-radius:8px;\">\n \n <!-- Header -->\n <tr>\n <td style=\"background:#4f46e5; color:#ffffff; text-align:center; font-size:20px; font-weight:bold; border-radius:8px 8px 0 0;\">\n Important Notification\n </td>\n </tr>\n\n <!-- Body -->\n <tr>\n <td style=\"color:#333; font-size:14px; line-height:1.6;\">\n \n {{$json[\"output\"].replace(/\\n/g, \"<br>\")}}\n\n </td>\n </tr>\n\n <!-- Footer -->\n <tr>\n <td style=\"font-size:12px; color:#888; text-align:center;\">\n \u00a9 2026 Your Company\n </td>\n </tr>\n\n </table>\n\n </td>\n </tr>\n </table>\n\n</body>\n</html>",
"options": {},
"subject": "You\u2019ve exceeded your plan limit \u2014 upgrade to stay uninterrupted"
},
"typeVersion": 2.2
},
{
"id": "f021497d-6f15-43bd-a346-052c25821784",
"name": "Send a message6",
"type": "n8n-nodes-base.slack",
"position": [
6400,
3232
],
"parameters": {
"text": "=\ud83d\udea8 Upsell Opportunity Triggered\n\n\ud83d\udc64 User: {{ $('Webhook').item.json.body.name }}\n\ud83d\udce7 Email: {{ $('Webhook').item.json.body.email }}\n\n\ud83d\udcca Usage: {{ $('Webhook').item.json.body.usage }} / {{ $('Webhook').item.json.body.usage_limit }}\n\ud83d\udce6 Plan: {{ $('Webhook').item.json.body.plan }}\n\n\ud83d\udce2 Action Taken:\n\u2022 Upsell email sent\n\n\ud83d\udc49 Next Step:\nFollow up within 24 hours if no upgrade.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.4
},
{
"id": "c5fca99f-0382-43f1-92d0-4f519ad90481",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
4096,
2816
],
"parameters": {
"width": 576,
"height": 784,
"content": "# Automated Upsell Trigger Based on Usage Data\n\nThis workflow automatically detects when a customer exceeds their usage limits and triggers a personalized upsell process. It helps teams act at the right moment, improving upgrade conversions and customer experience without manual monitoring.\n\n### How it works\n- A webhook receives real-time usage data\n- Data is structured and prepared for processing\n- AI generates a personalized upsell message\n- Email is sent automatically to the customer\n- Activity is logged inside HubSpot CRM\n- The team is notified via Slack for follow-up\n\n### Setup steps\n- Configure the webhook to receive usage data\n- Ensure payload includes email, usage, and limit fields\n- Connect your AI model (Groq/OpenAI)\n- Authenticate Gmail, HubSpot, and Slack nodes\n- Add your HubSpot API token and Slack credentials\n- Test the workflow using sample webhook data\n\n### Customization tips\n- Adjust usage thresholds based on your pricing model\n- Modify AI prompts for different tones or offers\n- Add segmentation logic for different customer tiers"
},
"typeVersion": 1
},
{
"id": "84458d02-085a-4887-bdf9-e57a360d1380",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
4704,
2816
],
"parameters": {
"color": 7,
"width": 480,
"height": 768,
"content": "## Step 1: Trigger & Data Prep\n\nReceives webhook data and formats key fields for processing."
},
"typeVersion": 1
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send a message5",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Send a message6",
"type": "main",
"index": 0
}
]
]
},
"Groq Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Search contacts": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Send a message5": {
"main": [
[
{
"node": "Search contacts",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow monitors user usage via a webhook and automatically triggers an upsell process when limits are exceeded. It formats incoming data, generates a personalized email using AI, and sends it to the user. The workflow then logs the activity in HubSpot and notifies the…
Source: https://n8n.io/workflows/14557/ — 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 receives free-signup events via webhook, enriches the contact with Twain research (and optional Findymail LinkedIn lookup), uses Anthropic Claude to score ICP fit, then routes outcomes t
This template uses the Apify LinkedIn Profile Scraper, which is a community node only available in self-hosted n8n installations. The LinkedIn scraping step is optional and can be removed for n8n Clou
COMPLEXITY-004: Multiple unrelated concerns in one workflow. Uses gmail, slack, postgres, googleDrive. Webhook trigger; 15 nodes.
Airtable Operations System: Leads, AI Agent, Outreach, Sync, Canva, Make/Zapier Bridge. Uses airtable, anthropic, slack, agent. Webhook trigger; 82 nodes.
Marketing, growth, and automation teams that need to ship polished bilingual newsletters—complete with images, optional video, and multi-channel distribution—without writing a line of code. A Webhook