AutomationFlowsAI & RAG › Call Assi

Call Assi

call_assi. Uses toolWorkflow, agent, lmChatGoogleGemini. Webhook trigger; 11 nodes.

Webhook trigger★★★★☆ complexityAI-powered11 nodesTool WorkflowAgentGoogle Gemini Chat
AI & RAG Trigger: Webhook Nodes: 11 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Agent → Google Gemini Chat 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
{
  "updatedAt": "2025-12-11T16:44:19.000Z",
  "createdAt": "2025-10-27T18:25:38.997Z",
  "id": "eQO1bX8fadDwNvMu",
  "name": "call_assi",
  "active": true,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "jsCode": "const phoneNumber = $input.first().json.body.message.call?.customer?.number ?? $input.first().json.body.message.toolCalls[0].function.arguments.phoneNumber\n  \nreturn {phoneNumber}"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "id": "495db161-4b96-492a-9ad0-86dc38369866",
      "name": "Get phone number",
      "disabled": true
    },
    {
      "parameters": {
        "description": "This tool's purpose is to cancel an appointment",
        "workflowId": {
          "__rl": true,
          "value": "qJMnBdEthjId0vbd",
          "mode": "list",
          "cachedResultUrl": "/workflow/qJMnBdEthjId0vbd",
          "cachedResultName": "cancel_appointment"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "appointmentId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('appointmentId', ``, 'string') }}"
          },
          "matchingColumns": [
            "appointmentId"
          ],
          "schema": [
            {
              "id": "appointmentId",
              "displayName": "appointmentId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string",
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        528,
        416
      ],
      "id": "f39f200d-f7a5-4115-8836-4fadf45f9b4c",
      "name": "cancelAppointment"
    },
    {
      "parameters": {
        "description": "This tool's purpose is to reschedule the appointment for the user",
        "workflowId": {
          "__rl": true,
          "value": "i4ywe4sK8CvhockA",
          "mode": "list",
          "cachedResultUrl": "/workflow/i4ywe4sK8CvhockA",
          "cachedResultName": "reschedule_appointment"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "appointmentId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('appointmentId', ``, 'string') }}",
            "appointmentDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('appointmentDate', ``, 'string') }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "appointmentId",
              "displayName": "appointmentId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "appointmentDate",
              "displayName": "appointmentDate",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        688,
        416
      ],
      "id": "85f58800-5a87-4328-b9d4-1410e947aee6",
      "name": "rescheduleAppointment"
    },
    {
      "parameters": {
        "description": "This tool will be responsible for booking a new appointment in the calendar",
        "workflowId": {
          "__rl": true,
          "value": "RIvTGcIIx3zSsHiZ",
          "mode": "list",
          "cachedResultUrl": "/workflow/RIvTGcIIx3zSsHiZ",
          "cachedResultName": "bookAppointment"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "appointmentStartTime": "={{ $json.body.message.toolCallList[0].function.arguments.preferredTime }}",
            "firstName": "={{ $json.body.message.toolCallList[0].function.arguments.firstName }}",
            "lastName": "={{ $json.body.message.toolCallList[0].function.arguments.lastName }}",
            "phoneNumber": "={{ $json.body.message.toolCallList[0].function.arguments.phoneNumber }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "appointmentStartTime",
              "displayName": "appointmentStartTime",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "firstName",
              "displayName": "firstName",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "lastName",
              "displayName": "lastName",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "phoneNumber",
              "displayName": "phoneNumber",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "email",
              "displayName": "email",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string",
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        848,
        416
      ],
      "id": "9c11a3ce-7d89-46d1-af88-21ec1327ef29",
      "name": "bookAppointment"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=You are assisting with appointment scheduling.\n\nInput:\n- toolCallName\n- preferredTime\n- firstName\n- lastName\n- appointmentId\n- appointmentDate\n\nOutput:\nReturn only JSON specifying what action to perform, using the provided arguments. No explanation.\n",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2,
      "position": [
        320,
        192
      ],
      "id": "b85bb6f9-2cbf-44e2-a765-cf5b507b1030",
      "name": "AI Agent1",
      "executeOnce": false
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "e0eb2929-3f5d-48ea-ba3c-cec29f87010c",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -304,
        176
      ],
      "id": "cc500a08-b6fc-4f42-8664-3336608981b9",
      "name": "Webhook1",
      "executeOnce": false
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={\n  \"results\": [\n    {\n      \"toolCallId\": \"{{ $('Webhook1').item.json.body.message.toolCalls[0].id }}\",\n      \"result\": \"{{ $json.output.replaceAll(\"\\n\", \"\").replace(/\"([^\"]+)\"/g, '\\\\\"$1\\\\\"') }}\"\n    }\n  ]\n}\n",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        864,
        176
      ],
      "id": "4382f5fa-8815-4d95-a1e2-62f1a5e8d887",
      "name": "Respond to Webhook"
    },
    {
      "parameters": {
        "description": "This tool will check for available timeslots and return their start time",
        "workflowId": {
          "__rl": true,
          "value": "25L7BjNxaV3gQnx0",
          "mode": "list",
          "cachedResultUrl": "/workflow/25L7BjNxaV3gQnx0",
          "cachedResultName": "getAvailability"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "startTime": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startTime', ``, 'string') }}",
            "endTime": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endTime', ``, 'string') }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "startTime",
              "displayName": "startTime",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            },
            {
              "id": "endTime",
              "displayName": "endTime",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string"
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        304,
        400
      ],
      "id": "b3923ed8-896b-4a17-840c-3d985fbab81c",
      "name": "getAvailability"
    },
    {
      "parameters": {
        "description": "This tool will retrieve the existing appointment for the patient",
        "workflowId": {
          "__rl": true,
          "value": "zZLxKOn5DyLfS8Ho",
          "mode": "list",
          "cachedResultUrl": "/workflow/zZLxKOn5DyLfS8Ho",
          "cachedResultName": "getAppointment"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "appointmentId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('appointmentId', ``, 'string') }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "appointmentId",
              "displayName": "appointmentId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string",
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        416,
        400
      ],
      "id": "a5281f99-3f80-4108-961b-c60ea8b1be9f",
      "name": "getAppointment"
    },
    {
      "parameters": {
        "modelName": "models/gemini-2.0-flash-001",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        160,
        416
      ],
      "id": "dc85af03-53d2-44cc-bfec-dd05b8508b74",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// n8n Function node \u2014 \"filter + map\" for Vapi \u2192 AI Agent integration\n// Returns a compact, safe object with all the template variables your prompt expects.\n//\n// Paste this into an n8n Function node. It expects the incoming webhook JSON at $json\n// and returns one item: item.json contains the mapped fields.\n\nconst body = $json[\"body\"] || {};\nconst message = body.message || {};\n\n// Helper: find the toolCall in multiple possible places\nconst toolCall =\n  (message.toolCalls && message.toolCalls[0]) ||\n  (message.toolCallList && message.toolCallList[0]) ||\n  (message.toolWithToolCallList && message.toolWithToolCallList[0] && message.toolWithToolCallList[0].toolCall) ||\n  null;\n\n// Safe parser for possibly stringified arguments\nfunction parseArgs(raw) {\n  if (!raw) return {};\n  if (typeof raw === \"object\") return raw;\n  if (typeof raw === \"string\") {\n    try {\n      return JSON.parse(raw);\n    } catch (e) {\n      // fallback: simple key=value pairs or raw string\n      return { rawString: raw };\n    }\n  }\n  return {};\n}\n\n// Find last user message (best-effort)\nfunction findLastUserMessage(artifact, messageFallback) {\n  if (!artifact) return messageFallback || \"\";\n  const msgs = artifact.messagesOpenAIFormatted || artifact.messages || [];\n  for (let i = msgs.length - 1; i >= 0; i--) {\n    const m = msgs[i];\n    if (!m) continue;\n    // support both formats: {role, content} and {role, message}\n    const role = (m.role || \"\").toString().toLowerCase();\n    const text = m.content || m.message || \"\";\n    if (role === \"user\" || role === \"human\") return text;\n    // fallback heuristics: treat any item with content and not system as user\n    if (text && role && role !== \"system\" && role !== \"assistant\") return text;\n  }\n  return messageFallback || \"\";\n}\n\nconst args = parseArgs(toolCall && toolCall.function && toolCall.function.arguments);\nconst toolName = (toolCall && ((toolCall.function && toolCall.function.name) || toolCall.name)) || null;\n\nconst artifact = message.artifact || {};\nconst lastUserMessage = findLastUserMessage(artifact, message.text || message.message || \"\");\n\n// Heuristics for name and phone if not provided explicitly\nlet firstName = args.firstName || null;\nlet lastName = args.lastName || null;\nlet fullName = args.name || args.fullName || null;\nlet phone = args.phoneNumber || args.mobile || args.phone || null;\n\nif (!fullName && lastUserMessage) {\n  const nameMatch = lastUserMessage.match(/(?:for|booking for|new booking for|book)\\s+([A-Z][a-z]+(?:\\s[A-Z][a-z]+)*)/i);\n  if (nameMatch) fullName = nameMatch[1];\n}\n\nif (!phone && lastUserMessage) {\n  const phoneMatch = lastUserMessage.match(/(\\+?\\d[\\d\\-\\s]{7,}\\d)/);\n  if (phoneMatch) phone = phoneMatch[0].replace(/\\s+/g, \"\");\n}\n\n// split fullName into first/last if needed\nif (!firstName && fullName) {\n  const parts = fullName.trim().split(/\\s+/);\n  firstName = parts[0] || null;\n  lastName = parts.length > 1 ? parts.slice(1).join(\" \") : (lastName || null);\n}\n\n// Map all expected template variables (keep nulls if missing)\nconst mapped = {\n  toolCallName: toolName,\n  firstName: firstName || null,\n  lastName: lastName || null,\n  preferredTime: args.preferredTime || null,\n  appointmentTime: args.appointmentTime || null,\n  appointmentReason: args.appointmentReason || null,\n  birthDate: args.birthDate || null,\n  fullName: fullName || null,\n  appointmentDate: args.appointmentDate || null,\n  appointmentId: args.appointmentId || null,\n  lastUserMessage,\n  phoneNumber: phone || null,\n  chatId: (body.chat && body.chat.id) || (body.chatId || null),\n  // Debugging / telemetry (optional)\n  _originalSizeBytes: Buffer.from(JSON.stringify($json)).length,\n  _toolCallRawId: toolCall && toolCall.id ? toolCall.id : null,\n};\n\n// Return the compact mapped object\nreturn [{ json: mapped }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -16,
        192
      ],
      "id": "c50ae0f2-a39f-4378-8ea3-f2a6a0d457bf",
      "name": "Code in JavaScript"
    }
  ],
  "connections": {
    "cancelAppointment": {
      "ai_tool": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "rescheduleAppointment": {
      "ai_tool": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "bookAppointment": {
      "ai_tool": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook1": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "getAvailability": {
      "ai_tool": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "getAppointment": {
      "ai_tool": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Respond to Webhook": {
      "main": [
        []
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Asia/Kolkata",
    "saveExecutionProgress": true,
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "staticData": null,
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "versionId": "5541acbf-e935-40bd-afe2-3c68f9026c63",
  "triggerCount": 1,
  "shared": [
    {
      "updatedAt": "2025-10-27T18:25:39.013Z",
      "createdAt": "2025-10-27T18:25:39.013Z",
      "role": "workflow:owner",
      "workflowId": "eQO1bX8fadDwNvMu",
      "projectId": "U9gNtcfNPVWYu387"
    }
  ],
  "tags": []
}

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

call_assi. Uses toolWorkflow, agent, lmChatGoogleGemini. Webhook trigger; 11 nodes.

Source: https://github.com/vignesh-potharaj/n8n/blob/330399d72a812fa7dadf18142cbd24ca02303fd1/workflows/call_assi.json — 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

Are you drowning in daily operational chaos, desperately trying to juggle sales, projects, content, and client communication? Imagine an AI brain that handles it all, freeing you to lead your business

Telegram Trigger, Telegram, OpenAI +13
AI & RAG

CLINICAINTEGRAL_secretary. Uses postgres, mcpClientTool, googleDriveTool, toolWorkflow. Webhook trigger; 89 nodes.

Postgres, Mcp Client Tool, Google Drive Tool +14
AI & RAG

Agente_DamaresEstetica. Uses postgres, agent, n8n-nodes-evolution-api, lmChatGoogleGemini. Webhook trigger; 87 nodes.

Postgres, Agent, N8N Nodes Evolution Api +6
AI & RAG

my-secretary. Uses postgres, mcpClientTool, googleDriveTool, toolWorkflow. Webhook trigger; 86 nodes.

Postgres, Mcp Client Tool, Google Drive Tool +13
AI & RAG

secretaria. Uses postgres, n8n-nodes-evolution-api, openAi, httpRequest. Webhook trigger; 71 nodes.

Postgres, N8N Nodes Evolution Api, OpenAI +12