AutomationFlowsAI & RAG › Hotbot — 03 Voice Pipeline

Hotbot — 03 Voice Pipeline

HotBot — 03 Voice Pipeline. Uses httpRequest, openAi. Webhook trigger; 9 nodes.

Webhook trigger★★★★☆ complexityAI-powered9 nodesHTTP RequestOpenAI
AI & RAG Trigger: Webhook Nodes: 9 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the HTTP Request → 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 →

Download .json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567803",
  "name": "HotBot \u2014 03 Voice Pipeline",
  "nodes": [
    {
      "id": "node-webhook-voice",
      "name": "Webhook \u2014 Voice",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        300
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "hotbotstudios-voice",
        "responseMode": "responseNode",
        "options": {
          "allowedOrigins": "*"
        }
      }
    },
    {
      "id": "node-validate-voice",
      "name": "Validate Audio Input",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        300
      ],
      "parameters": {
        "jsCode": "const body = $input.first().json.body || $input.first().json;\nconst audio = body.audio || '';\nconst language = body.language || 'hi-IN';\nconst sessionId = body.sessionId || ('voice-' + Date.now());\nconst meta = body._meta || {};\n\nif (!audio || audio.length < 100) throw new Error('Invalid or missing audio data');\n\n// Remove data URI prefix if present\nconst cleanAudio = audio.replace(/^data:audio\\/[^;]+;base64,/, '');\n\nreturn [{\n  json: {\n    audio: cleanAudio,\n    language,\n    sessionId,\n    timestamp: new Date().toISOString(),\n    source: meta.source || 'website-voice'\n  }\n}];"
      }
    },
    {
      "id": "node-sarvam-stt",
      "name": "Sarvam AI \u2014 Speech to Text",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        720,
        300
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.sarvam.ai/speech-to-text",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "API-Subscription-Key",
              "value": "YOUR_SARVAM_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "audio",
              "value": "={{ $json.audio }}"
            },
            {
              "name": "language_code",
              "value": "={{ $json.language }}"
            },
            {
              "name": "model",
              "value": "saarika:v2"
            }
          ]
        },
        "options": {
          "timeout": 30000
        }
      }
    },
    {
      "id": "node-extract-transcript",
      "name": "Extract Transcript",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        960,
        300
      ],
      "parameters": {
        "jsCode": "const sttResult = $input.first().json;\nconst transcript = sttResult.transcript || sttResult.text || '';\n\nif (!transcript || transcript.trim().length === 0) {\n  throw new Error('Could not transcribe audio \u2014 please try again');\n}\n\nconst sessionId = $('Validate Audio Input').first().json.sessionId;\nconst language = $('Validate Audio Input').first().json.language;\n\nreturn [{\n  json: {\n    transcript: transcript.trim(),\n    language,\n    sessionId,\n    timestamp: $('Validate Audio Input').first().json.timestamp\n  }\n}];"
      }
    },
    {
      "id": "node-llm-voice",
      "name": "OpenAI \u2014 Voice LLM",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.4,
      "position": [
        1200,
        300
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "resource": "chat",
        "operation": "message",
        "model": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "gpt-4o-mini"
        },
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are HotBot, the AI voice assistant for HotBot Studios. You're responding to a voice message, so:\n- Keep responses SHORT (2-3 sentences max)\n- Use simple, conversational language\n- No markdown, no lists, no special characters\n- Be warm, helpful, and professional\n- Guide users to services: AI Automation, Marketing, Content, Software Dev, PR, UI/UX, Consultancy\n- If they want to get started, ask for their email or direct them to the website form\nContact: hello@hotbotstudios.com | https://hotbotstudios.com"
            },
            {
              "role": "user",
              "content": "={{ $json.transcript }}"
            }
          ]
        },
        "options": {
          "temperature": 0.6,
          "maxTokens": 200
        }
      }
    },
    {
      "id": "node-extract-llm-reply",
      "name": "Extract LLM Reply",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1440,
        300
      ],
      "parameters": {
        "jsCode": "const llmResult = $input.first().json;\nconst replyText = llmResult.message?.content || llmResult.choices?.[0]?.message?.content || 'I am here to help. Please tell me what you need.';\n\nreturn [{\n  json: {\n    replyText,\n    language: $('Extract Transcript').first().json.language,\n    sessionId: $('Extract Transcript').first().json.sessionId\n  }\n}];"
      }
    },
    {
      "id": "node-sarvam-tts",
      "name": "Sarvam AI \u2014 Text to Speech",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1680,
        300
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.sarvam.ai/text-to-speech",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "API-Subscription-Key",
              "value": "YOUR_SARVAM_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "inputs",
              "value": "={{ [$json.replyText] }}"
            },
            {
              "name": "target_language_code",
              "value": "={{ $json.language }}"
            },
            {
              "name": "speaker",
              "value": "meera"
            },
            {
              "name": "model",
              "value": "bulbul:v1"
            },
            {
              "name": "enable_preprocessing",
              "value": true
            }
          ]
        },
        "options": {
          "timeout": 30000
        }
      }
    },
    {
      "id": "node-prepare-voice-response",
      "name": "Prepare Voice Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1920,
        300
      ],
      "parameters": {
        "jsCode": "const ttsResult = $input.first().json;\nconst audioBase64 = ttsResult.audios?.[0] || ttsResult.audio || '';\nconst replyText = $('Extract LLM Reply').first().json.replyText;\n\nreturn [{\n  json: {\n    message: replyText,\n    audio: audioBase64,\n    audioFormat: 'wav',\n    sessionId: $('Extract LLM Reply').first().json.sessionId\n  }\n}];"
      }
    },
    {
      "id": "node-respond-voice",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        2160,
        300
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ message: $json.message, audio: $json.audio, audioFormat: $json.audioFormat }) }}",
        "options": {
          "responseCode": 200
        }
      }
    }
  ],
  "connections": {
    "Webhook \u2014 Voice": {
      "main": [
        [
          {
            "node": "Validate Audio Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Audio Input": {
      "main": [
        [
          {
            "node": "Sarvam AI \u2014 Speech to Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sarvam AI \u2014 Speech to Text": {
      "main": [
        [
          {
            "node": "Extract Transcript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Transcript": {
      "main": [
        [
          {
            "node": "OpenAI \u2014 Voice LLM",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI \u2014 Voice LLM": {
      "main": [
        [
          {
            "node": "Extract LLM Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract LLM Reply": {
      "main": [
        [
          {
            "node": "Sarvam AI \u2014 Text to Speech",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sarvam AI \u2014 Text to Speech": {
      "main": [
        [
          {
            "node": "Prepare Voice Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Voice Response": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner"
  },
  "tags": [
    {
      "id": "tag-hotbot",
      "name": "hotbot-studios"
    },
    {
      "id": "tag-voice",
      "name": "voice-pipeline"
    }
  ]
}

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

HotBot — 03 Voice Pipeline. Uses httpRequest, openAi. Webhook trigger; 9 nodes.

Source: https://github.com/harshpreet20/hotbot26/blob/337e1599ac488651f97c911ee272fd705de8e90c/n8n-workflows/03-voice-pipeline.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

This workflow captures new leads via webhook, enriches and scores them with Apollo and Google Gemini, logs everything in Google Sheets, and automates outreach, reply handling, follow-ups, meeting prep

HTTP Request, Google Gemini, Google Sheets +3
AI & RAG

This powerful n8n automation workflow is designed to execute advanced B2B lead enrichment and hyper-personalization for cold email outreach. By orchestrating a complex chain of data scraping, AI analy

OpenAI, HTTP Request, Airtable
AI & RAG

Propulsar — Content Engine v3. Uses openAi, httpRequest, googleSheets. Webhook trigger; 73 nodes.

OpenAI, HTTP Request, Google Sheets
AI & RAG

Eu Clara – Funil Kiwify Completo. Uses postgres, openAi, httpRequest, gmail. Webhook trigger; 70 nodes.

Postgres, OpenAI, HTTP Request +1
AI & RAG

Postagem Redes — Portal: Ações. Uses openAi, googleGemini, ollama, httpRequest. Webhook trigger; 58 nodes.

OpenAI, Google Gemini, Ollama +4