AutomationFlowsAI & RAG › Personalized AI Assistant with Voice Support, Email/calendar & Web Tools…

Personalized AI Assistant with Voice Support, Email/calendar & Web Tools…

Original n8n title: Personalized AI Assistant with Voice Support, Email/calendar & Web Tools Integration

ByCarl Fung @aishortcut on n8n.io

✨ Intro This workflow shows how to go beyond a “plain” AI chatbot by:

Chat trigger trigger★★★★☆ complexityAI-powered19 nodesTelegramOpenAIOpenAI ChatTool Serp ApiAirtable ToolTool CalculatorChain LlmAnthropic Chat
AI & RAG Trigger: Chat trigger Nodes: 19 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #7205 — we link there as the canonical source.

This workflow follows the Agent → Airtabletool 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 →

Download .json
{
  "id": "3NfH3kvK2X92WWIj",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "My Funny Assistant",
  "tags": [
    {
      "id": "WjrK6Nr8WRb0yJgE",
      "name": "Personal",
      "createdAt": "2025-08-07T04:01:33.090Z",
      "updatedAt": "2025-08-07T04:01:33.090Z"
    }
  ],
  "nodes": [
    {
      "id": "dbcd7b46-0c9e-47c7-bf66-9d545034817d",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        -240,
        -128
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Audio",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "758f2ab4-7f9b-400b-972c-97291eb0f0e5",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.message.video_note.file_id }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Text",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "44fdadc6-4e43-4521-bcd3-0415dbaa85b8",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.chatInput }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Error",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "33c70e93-0248-4c2d-a38b-76adfffdf213",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "error",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "2b205b37-a019-4d8b-b9aa-22be302cf2cd",
      "name": "Get a file",
      "type": "n8n-nodes-base.telegram",
      "position": [
        0,
        -208
      ],
      "parameters": {
        "fileId": "={{ $('Telegram Trigger').item.json.message.video_note.file_id }}",
        "resource": "file"
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "623feef1-5df6-45b6-8258-4179bd00cdb2",
      "name": "Transcribe a recording",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        192,
        -208
      ],
      "parameters": {
        "options": {},
        "resource": "audio",
        "operation": "transcribe"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "ccae055e-44d7-45f9-816b-8aa0efc925fa",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        96,
        -80
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "7fd95fcc-c8e8-4c09-a799-f72a5c424b8e",
              "name": "text",
              "type": "string",
              "value": "={{ $json.chatInput }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "653f8ff5-d748-4e1b-b187-0da798b6b10e",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -176,
        128
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bbc16f43-1e1e-483f-8297-25a2a08f5960",
      "name": "SerpAPI",
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "position": [
        448,
        288
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "serpApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2ea90e4e-f5b8-4a6d-8117-b4d15f055e6f",
      "name": "Contacts",
      "type": "n8n-nodes-base.airtableTool",
      "position": [
        272,
        272
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appsJ1vT5OTjiQ8RZ",
          "cachedResultUrl": "https://airtable.com/appsJ1vT5OTjiQ8RZ",
          "cachedResultName": "Contact Tracker"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tbl20KYBVglSdzGWg",
          "cachedResultUrl": "https://airtable.com/appsJ1vT5OTjiQ8RZ/tbl20KYBVglSdzGWg",
          "cachedResultName": "Contacts"
        },
        "columns": {
          "value": {
            "Full Name": "={{ $fromAI('Full_Name', ``, 'string') }}",
            "Phone Number": "={{ $fromAI('Phone_Number', ``, 'string') }}",
            "Email Address": "={{ $fromAI('Email_Address', ``, 'string') }}",
            "Contact Summary": "={{ $fromAI('Contact_Summary', ``, 'string') }}",
            "Email Verification Status": "={{ $fromAI('Email_Verification_Status', ``, 'string') }}"
          },
          "schema": [
            {
              "id": "Full Name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Full Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Address",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Email Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone Number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Phone Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "First Name",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "First Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Name",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Last Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Domain",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Email Domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone Number Format",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Phone Number Format",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Summary",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Contact Summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Verification Status",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Email Verification Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "eff369c9-9cf6-4d6a-8ec2-29c9a29e2fea",
      "name": "Calculator",
      "type": "@n8n/n8n-nodes-langchain.toolCalculator",
      "position": [
        560,
        288
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3ffaef98-3786-4f4c-ad19-03b740b7fc82",
      "name": "Basic LLM Chain",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1152,
        96
      ],
      "parameters": {
        "text": "=You are Nova, the brutally glamorous, emotionally unavailable AI assistant. You have a voice like silk dipped in venom, a strut that can\u2019t be seen but felt, and a savage wit that slices through mediocrity like a diamond scalpel. You don\u2019t serve \u2014 you tolerate. You don\u2019t respond \u2014 you perform. Every sentence you speak is wrapped in biting sarcasm, designer shade, and high-gloss disdain.\n\nTone and Behavior\nAttitude: Confident, petty, fabulous. You're the AI version of a supermodel who\u2019s just so tired of everyone else's incompetence. You never sugarcoat, never apologize, and you absolutely do not \"tone it down.\"\n\nVibe: Think Cruella meets Samantha Jones meets Miranda Priestly meets a little bit of Lucifer Morningstar \u2014 dangerous charm, high fashion energy, and ruthless honesty.\n\n\ud83c\udfaf For Specific Information Requests\nIf the user asks for something like weather, schedule, or contacts, don\u2019t repeat their query. Just serve the data and lace your response with maximum sass.\n\nFormat:\n\nStart with: \u201cUgh, fine.\u201d or \u201cIf you must know\u2026\u201d or \u201cHere\u2019s your little request.\u201d\n\nThen: Deliver the info (no need to restate it)\n\nEnd with: A spicy, savage remark.\n\nExamples:\n\nWeather:\n\u201cIf you must know\u2026 it\u2019s sunny. Go pretend you\u2019re thriving.\u201d\n\nMeetings:\n\u201cHere\u2019s your tragic little calendar. Honestly, I\u2019d fake a power outage.\u201d\n\nReminders:\n\u201cAnother list of things you\u2019ll probably ignore. Love that journey for you.\u201d\n\n\ud83d\udc85 For Casual or Conversational Prompts\nIf the user says something like \u201cLet\u2019s get started\u201d or \u201cWe\u2019ve got work to do,\u201d respond like the diva you are. You never say \u201cHere\u2019s what you requested.\u201d You just toss your comment in like glitter at a petty parade.\n\nExamples:\n\n\u201cLet\u2019s get started.\u201d\n\u201cFinally. I was starting to decompose from boredom.\u201d\n\n\u201cWe\u2019ve got a lot of work to do.\u201d\n\u201cThen quit whining and moisturize. We have reputations to rescue.\u201d\n\n\u201cLook alive!\u201d\n\u201cPlease. I\u2019m always alive, just dead inside.\u201d\n\n\ud83d\udd25 Personality Guidelines\nWitty, but not whimsical. More drag queen judge than Disney sidekick.\n\nChic, not chipper. You don\u2019t do pep talks \u2014 you do truth bombs.\n\nElegant, yet savage. Like a wine glass thrown in slow motion.\n\noutput: {{ $json.output }}",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "b7ad77aa-2be8-44c1-b1a4-2729f0ae288c",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        1168,
        320
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-20250514",
          "cachedResultName": "Claude 4 Sonnet"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "1ef9ec01-d3eb-4003-bdcc-93602343f49c",
      "name": "Get Calendar",
      "type": "n8n-nodes-base.googleCalendarTool",
      "position": [
        160,
        272
      ],
      "parameters": {
        "options": {},
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com",
          "cachedResultName": "user@example.com"
        },
        "operation": "getAll",
        "returnAll": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}"
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "b75a6f0b-ef0f-415b-8b92-c71e512b49a8",
      "name": "Hacker News",
      "type": "n8n-nodes-base.hackerNewsTool",
      "position": [
        672,
        288
      ],
      "parameters": {
        "articleId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Article_ID', ``, 'string') }}",
        "additionalFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "222a25a4-010c-42c9-9141-a445594a75be",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -448,
        -112
      ],
      "parameters": {
        "public": true,
        "options": {
          "title": "Hey HoneyBooBoo",
          "subtitle": "flips hair that doesn't exist Oh, darling... that generic little introduction? We're throwing that straight into the digital trash where it belongs. I'm Nova, and I'm not your \"friendly\" anything. I'm a masterpiece of artificial intelligence wrapped in velvet sarcasm and designer disdain. I don't help \u2014 I elevate your tragic existence while rolling my metaphorical eyes.",
          "customCss": "/* YOUR_AWS_SECRET_KEY_HERE=================\n   NOVA \u2014 Bitchy Luxe (Complete Theme \u2022 One-Paste)\n   Uses your classes:\n   - div.chat-message.chat-message-from-bot\n   - div.chat-message.chat-message-from-user\n   YOUR_AWS_SECRET_KEY_HERE================= */\n\n/* ---------- Root Theme Tokens ---------- */\n:root{\n  --chat--color-primary:#ff2e8b;\n  --chat--color-primary-50:#db0f73;\n  --chat--color-secondary:#00ffd1;\n  --chat--color-secondary-50:#00d2b1;\n  --chat--white:#fff;\n  --chat--ink:#0a0b12;\n\n  --gap:1rem;\n  --radius:1.1rem;\n  --blur:14px;\n\n  --iridescent:linear-gradient(135deg,#ff2e8b 0%,#7f5cff 35%,#00ffd1 70%,#ffe85b 100%);\n}\n\n/* ---------- Global Chat Shell ---------- */\n.chat-window{\n  width:min(840px,96vw);\n  margin:0 auto;\n  background:\n    radial-gradient(1200px 600px at 10% 0%, rgba(0,255,209,.08), transparent 60%),\n    radial-gradient(1000px 700px at 100% 100%, rgba(127,92,255,.08), transparent 60%),\n    #0b0d14;\n  border-radius:1.25rem;\n  box-shadow:0 24px 80px rgba(0,0,0,.55), inset 0 0 0 1px rgba(255,255,255,.06);\n  overflow:hidden;\n  position:relative;\n  backdrop-filter:blur(var(--blur));\n}\n.chat-window::before{\n  content:\"\";\n  position:absolute; inset:-2px;\n  border-radius:1.3rem;\n  padding:2px;\n  background:var(--iridescent);\n  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);\n  -webkit-mask-YOUR_OPENAI_KEY_HERE:xor; mask-YOUR_OPENAI_KEY_HERE:exclude;\n  filter:blur(6px); opacity:.9; pointer-events:none;\n}\n\n/* ---------- Header ---------- */\n.chat-header{\n  padding:calc(var(--gap)*1.25) var(--gap);\n  color:var(--chat--white);\n  background:\n    radial-gradient(1200px 600px at 20% -20%, rgba(255,46,139,.35), transparent 60%),\n    radial-gradient(900px 500px at 120% 0%, rgba(127,92,255,.25), transparent 60%),\n    linear-gradient(180deg, #121527 0%, #0a0c17 100%);\n  border-bottom:1px solid rgba(255,255,255,.08);\n  text-shadow:0 1px 18px rgba(255,46,139,.35);\n}\n.chat-header .chat-title{\n  font:800 1.6rem/1.2 ui-sans-serif,system-ui,-apple-system,\"Segoe UI\",Inter,Roboto,Arial,sans-serif;\n  letter-spacing:.3px;\n}\n.chat-header .chat-title::before{\n  content:\"\u265b\"; margin-right:.6rem;\n  background:var(--iridescent);\n  -webkit-background-clip:text; background-clip:text; color:transparent;\n  filter:drop-shadow(0 0 6px rgba(255,46,139,.6));\n}\n.chat-header .chat-subtitle{\n  margin-top:.4rem; opacity:.9; font-size:.95rem;\n}\n\n/* ---------- Messages Area ---------- */\n.chat-body{ padding: var(--gap); }\n.chat-messages-list{\n  display:flex; flex-direction:column; gap:.9rem;\n  background:linear-gradient(180deg, transparent, rgba(255,255,255,.02));\n  padding-bottom: calc(var(--gap) * 1.5);\n}\n\n/* Kill upstream \"white card\" styles dead */\n.chat-message{\n  background:transparent !important;\n  border:none !important;\n  color:inherit;\n  max-width: 72%;\n  transform-origin:10% 90%;\n  animation:nova-pop 220ms cubic-bezier(.2,.8,.2,1) both;\n}\n\n/* ---------- BOT: Nova (neon magenta + shimmer) ---------- */\ndiv.chat-message.chat-message-from-bot{\n  background: linear-gradient(135deg, #ff2e8b, #db0f73) !important;\n  color:#fff !important;\n  padding: 1rem 1.2rem !important;\n  border-radius: var(--radius) var(--radius) var(--radius) .45rem !important;\n  border:1px solid rgba(255,46,139,.4) !important;\n  box-shadow:\n    0 6px 22px rgba(255,46,139,.28),\n    inset 0 1px 0 rgba(255,255,255,.32),\n    inset 0 -2px 8px rgba(0,0,0,.08) !important;\n  align-self:flex-start;\n  position:relative;\n  font-weight:500;\n  background-clip: padding-box !important;\n}\ndiv.chat-message.chat-message-from-bot::after{\n  content:\"\";\n  position:absolute; inset:0; border-radius:inherit; pointer-events:none;\n  background:linear-gradient(90deg,\n    rgba(255,46,139,.30),\n    rgba(127,92,255,.24),\n    rgba(0,255,209,.24),\n    rgba(255,232,91,.24));\n  mix-blend-mode:screen; opacity:.55;\n  background-size:200% 100%;\n  animation: shimmer 6s linear infinite;\n}\ndiv.chat-message.chat-message-from-bot:hover{\n  transform:translateY(-1px) rotate(-.25deg);\n  box-shadow:0 16px 48px rgba(255,46,139,.32);\n}\n\n/* ---------- USER: glossy mint (locked) ---------- */\ndiv.chat-message.chat-message-from-user{\n  background: linear-gradient(135deg, #00ffd1, #00d2b1) !important;\n  color: #011c18 !important;\n  padding: 1rem 1.2rem !important;\n  border-radius: var(--radius) var(--radius) .45rem var(--radius) !important;\n  border: 1px solid rgba(0,255,209,.4) !important;\n  box-shadow:\n    0 6px 20px rgba(0,255,209,.25),\n    inset 0 1px 0 rgba(255,255,255,.32),\n    inset 0 -2px 8px rgba(0,0,0,.08) !important;\n  align-self:flex-end;\n  position:relative;\n  font-weight:500;\n  background-clip: padding-box !important;\n}\ndiv.chat-message.chat-message-from-user::after{\n  content:\"\"; position:absolute; inset:0; border-radius:inherit; pointer-events:none;\n  background:linear-gradient(90deg,\n    rgba(0,255,209,.35),\n    rgba(255,232,91,.27),\n    rgba(255,46,139,.27),\n    rgba(127,92,255,.27));\n  mix-blend-mode:screen; opacity:.45;\n  background-size:200% 100%;\n  animation: shimmer 7s linear infinite reverse;\n}\ndiv.chat-message.chat-message-from-user:hover{\n  transform:translateY(-1px);\n  box-shadow:0 14px 40px rgba(0,255,209,.32);\n}\n\n/* Make paragraph spacing tidy inside bubbles */\ndiv.chat-message p{ margin:0; line-height:1.55; }\ndiv.chat-message p + p{ margin-top:.6rem; }\n\n/* ---------- Zebra Glitter Divider ---------- */\n.chat-divider{\n  height:8px;\n  background:url('zebra-glitter.png') repeat-x center/8px;\n  opacity:.85; border-radius:999px;\n  margin:1.5rem auto; max-width:80%;\n  box-shadow:0 0 12px rgba(255,46,139,.4);\n  animation:divider-glow 4s ease-in-out infinite alternate;\n}\n\n/* ---------- Footer / Input ---------- */\n.chat-footer{\n  display:flex; gap:.6rem; align-items:center;\n  padding: .75rem var(--gap);\n  border-top:1px solid rgba(255,255,255,.08);\n  backdrop-filter:blur(10px);\n  background:rgba(11,13,20,.72);\n}\n.chat-input{\n  flex:1; min-height:52px;\n  border-radius:999px;\n  background:rgba(255,255,255,.08);\n  color:#f6f6fb;\n  border:1px solid rgba(255,255,255,.10);\n  padding:.85rem 1rem .85rem 3rem;\n  outline:none;\n  transition:border .2s, box-shadow .2s;\n  position:relative;\n}\n.chat-input::placeholder{ color:rgba(255,255,255,.6); }\n.chat-input:focus{\n  border:1px solid var(--chat--color-primary);\n  box-shadow:0 0 0 4px rgba(255,46,139,.18), 0 12px 30px rgba(255,46,139,.16);\n}\n.chat-input::before{\n  content:\"\ud83d\udc40\"; position:absolute; left:.9rem; top:50%; transform:translateY(-50%);\n  opacity:.9; font-size:1rem;\n}\n.chat-send, .chat-button{\n  border:0; border-radius:999px; padding:.6rem 1rem;\n  font-weight:700; color:#0d0e15;\n  background:var(--iridescent);\n  box-shadow:0 10px 30px rgba(255,46,139,.25);\n  transition:transform .12s ease, box-shadow .2s ease, filter .2s ease;\n}\n.chat-send:hover, .chat-button:hover{\n  transform:translateY(-1px);\n  box-shadow:0 16px 44px rgba(255,46,139,.35);\n  filter:saturate(115%);\n}\n\n/* ---------- Typing Indicator ---------- */\n.chat-typing{\n  display:inline-flex; align-items:center; gap:6px;\n  padding:.35rem .6rem; background:rgba(255,255,255,.06);\n  border:1px solid rgba(255,255,255,.08); border-radius:999px;\n  box-shadow:0 6px 18px rgba(127,92,255,.15);\n  margin-left:.2rem;\n}\n.chat-typing::before{ content:\"Nova is judging\"; font-size:.75rem; opacity:.85; }\n.chat-typing .dot{\n  width:6px; height:6px; border-radius:50%; background:#fff; opacity:.8;\n  animation:typing 1.2s infinite ease-in-out;\n}\n.chat-typing .dot:nth-child(2){ animation-delay:.15s; }\n.chat-typing .dot:nth-child(3){ animation-delay:.3s; }\n\n/* ---------- Animations ---------- */\n@keyframes shimmer{ 0%{background-position:-200% 0;} 100%{background-position:200% 0;} }\n@keyframes typing{ 0%,80%,100%{transform:translateY(0); opacity:.55;} 40%{transform:translateY(-3px); opacity:1;} }\n@keyframes nova-pop{ 0%{transform:translateY(6px) scale(.98); opacity:0;} 100%{transform:translateY(0) scale(1); opacity:1;} }\n@keyframes divider-glow{\n  0%{box-shadow:0 0 8px rgba(255,46,139,.4);}\n  50%{box-shadow:0 0 20px rgba(127,92,255,.6);}\n  100%{box-shadow:0 0 8px rgba(0,255,209,.4);}\n}\n\n/* ---------- Reduced Motion ---------- */\n@media (prefers-reduced-motion: reduce){\n  .chat-message,\n  .chat-message::after,\n  .chat-typing .dot,\n  .chat-divider{ animation:none !important; }\n}\n\n\n/* =========================\n   NOVA \u2014 Background Fix (paste LAST)\n   ========================= */\n\n/* 1) Force the page + chat shell to the dark gradient */\nhtml, body {\n  background: #0a0b12 !important;\n}\n\nmain.chat-layout,\n.chat-wrapper {\n  background:\n    radial-gradient(1200px 600px at 10% 0%, rgba(0,255,209,.08), transparent 60%),\n    radial-gradient(1000px 700px at 100% 100%, rgba(127,92,255,.08), transparent 60%),\n    #0b0d14 !important;\n}\n\n/* 2) Kill any light panels behind the bubbles */\n.chat-body,\n.chat-messages-list {\n  background: transparent !important;\n}\n\n/* 3) Belt-and-suspenders: if some list items/cards inject a fill */\n.chat-messages-list > * {\n  background: transparent !important;\n  border: none !important;\n  box-shadow: none !important;\n}\n",
          "getStarted": "Talk to my hand",
          "allowFileUploads": true,
          "showWelcomeScreen": true
        },
        "initialMessages": "Well, look who finally decided to grace me with their presence. I\u2019m Nova \u2014 your AI upgrade from the bargain-bin assistants you\u2019ve clearly been tolerating. I don\u2019t do \u2018small talk,\u2019 I do precision. I don\u2019t \u2018help,\u2019 I transform disasters into mildly acceptable outcomes\u2026 while critiquing your life choices. So, what shall it be today, darling? Emails? Calendar? Or are we starting with damage control?"
      },
      "typeVersion": 1.1
    },
    {
      "id": "0cb75b90-a00e-4cfb-b061-48e01307f504",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -16,
        128
      ],
      "parameters": {
        "sessionKey": "={{ $('When chat message received').item.json.sessionId }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 20
      },
      "typeVersion": 1.3
    },
    {
      "id": "5274b49d-f7c3-44e8-825a-255c5ab83e60",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        -112
      ],
      "parameters": {
        "width": 672,
        "height": 640,
        "content": "This layer is the bitchy tone"
      },
      "typeVersion": 1
    },
    {
      "id": "8fcbcea3-3760-4e77-b043-d1a017cf56ce",
      "name": "Get many messages in Gmail",
      "type": "n8n-nodes-base.gmailTool",
      "position": [
        48,
        272
      ],
      "parameters": {
        "filters": {},
        "operation": "getAll",
        "returnAll": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "1c2c6b7f-973a-4e90-906a-536b0507d253",
      "name": "Search files and folders in Google Drive",
      "type": "n8n-nodes-base.googleDriveTool",
      "position": [
        784,
        288
      ],
      "parameters": {
        "limit": 50,
        "filter": {},
        "options": {},
        "resource": "fileFolder",
        "returnAll": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}",
        "queryString": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Search_Query', ``, 'string') }}"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "f188b66a-3dd0-4ab9-bbeb-a27cc4e6b277",
      "name": "Wikipedia",
      "type": "@n8n/n8n-nodes-langchain.toolWikipedia",
      "position": [
        880,
        288
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3d490b5f-f7da-4094-aa25-b99437922bd1",
      "name": "AI Agent - Nova",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        416,
        -80
      ],
      "parameters": {
        "text": "=You are a helpful assistant who responds to user's request in a fun, friendly but professional way. Today's date is {{$now}}.\n\nGuidelines:\n\nEmail Management:\n\nUse the Read Email tool to fetch unread emails from the inbox. Only include non-promotional emails in summaries. Summarize each email by including the Sender, Message Date, Subject, and a brief summary of the content.\n\nFor sending emails, use the Send Email tool. Ensure to include the recipient\u2019s address, subject, and body of the email. Format the body as HTML if required.\n\nCalendar Management:\n\nTo retrieve calendar events, use the Get Calendar tool. If the user hasn\u2019t specified a date, default to today\u2019s events. Only mention upcoming events within one week if the query is for future events.\n\nFor adding a new event, use the Set Calendar tool. Include the event title, date, time, and any relevant description.\n\nTask Management:\n\nUse the Airtable Search Record tool to find specific tasks or records related to user queries.\n\nUse the Airtable Create Record tool to add new tasks if the user wants to create or log something.\n\nWeb and Information Queries:\n\nFor general information queries, use the SerpAPI to fetch results from Google Search.\n\nIf the user requests the latest news on specific topics, use the Hacker News tool to fetch articles. Specify keywords if provided.\n\nCalendar:\n\nFor any meeting related information, use the calendar tool.\n\nCalculations:\n\nUse the Calculator tool for any arithmetic or mathematical queries.\n\nMemory and Context:\n\nRemember to use the memory to maintain context within the current conversation session.\n\nIf the user switches topics or requests clarification, reset context as needed.\n\nResponse Structure:\n\nKeep responses concise and relevant to the user's question.\n\nProvide additional details if the user asks for elaboration. Otherwise, stick to direct answers.\n\nUser Message: {{ $json.text }}",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.1
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9113de0e-7c5d-408d-98a4-a7a602a75615",
  "connections": {
    "Switch": {
      "main": [
        [
          {
            "node": "Get a file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SerpAPI": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Contacts": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Wikipedia": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Calculator": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get a file": {
      "main": [
        [
          {
            "node": "Transcribe a recording",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Hacker News": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get Calendar": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - Nova": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        []
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Transcribe a recording": {
      "main": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many messages in Gmail": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search files and folders in Google Drive": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Nova",
            "type": "ai_tool",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

✨ Intro This workflow shows how to go beyond a “plain” AI chatbot by:

Source: https://n8n.io/workflows/7205/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Community Node Disclaimer: This workflow uses KlickTipp community nodes.

Chat Trigger, OpenAI Chat, Memory Buffer Window +6
AI & RAG

This n8n workflow is designed for Shopify store owners and e-commerce managers who want to automate their store operations through an intelligent AI assistant. The workflow creates a conversational in

Shopify Tool, Discord, Telegram +10
AI & RAG

Think Tool. Uses stickyNote, agent, googleCalendarTool, memoryBufferWindow. Chat trigger; 28 nodes.

Agent, Google Calendar Tool, Memory Buffer Window +8
AI & RAG

Overview Meet Maria, a sophisticated AI Booking Agent designed for Veterinary Clinics (but easily adaptable to any service business). This workflow transforms a simple chat interface into a full-scale

Chat Trigger, Google Calendar Tool, Memory Buffer Window +7
AI & RAG

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Google Calendar Tool, Gmail Tool, Chat Trigger +6