AutomationFlowsWeb Scraping › Spanish Phone Survey — Web Call

Spanish Phone Survey — Web Call

Spanish Phone Survey — Web Call. Uses httpRequest. Webhook trigger; 7 nodes.

Webhook trigger★★★★☆ complexity7 nodesHTTP Request
Web Scraping Trigger: Webhook Nodes: 7 Complexity: ★★★★☆ Added:

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
{
  "name": "Spanish Phone Survey \u2014 Web Call",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "GET",
        "path": "web-survey",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "id": "b0000000-0000-4000-8000-000000000001",
      "name": "GET web-survey"
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n<title>Entrevista \u2014 Programa de Exportaci\u00f3n de Servicios Modernos</title>\n<style>\n  :root { color-scheme: light; }\n  *,*::before,*::after { box-sizing: border-box; }\n  body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; color: #1f2937; background: linear-gradient(140deg,#f8fafc 0%,#e0f2fe 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }\n  .card { background: #ffffff; max-width: 560px; width: 100%; border-radius: 18px; box-shadow: 0 20px 60px rgba(15,23,42,0.12); padding: 40px 36px; }\n  h1 { margin: 0 0 8px; font-size: 22px; font-weight: 600; }\n  p.lead { margin: 0 0 22px; color: #475569; line-height: 1.55; }\n  ul.notes { margin: 0 0 24px; padding-left: 20px; color: #475569; line-height: 1.65; font-size: 14px; }\n  ul.notes li { margin-bottom: 4px; }\n  label { display: block; font-size: 13px; font-weight: 600; color: #334155; margin: 14px 0 6px; }\n  .row { display: flex; gap: 10px; }\n  .row > .country { flex: 0 0 175px; }\n  .row > .phone { flex: 1; }\n  select, input[type=\"tel\"] { width: 100%; padding: 12px 14px; border-radius: 10px; border: 1px solid #cbd5e1; font-size: 16px; font-family: inherit; background: #ffffff; color: #0f172a; }\n  select:focus, input:focus { outline: 2px solid #0f172a; outline-offset: 1px; border-color: #0f172a; }\n  button { width: 100%; margin-top: 22px; padding: 16px 20px; border-radius: 12px; border: 0; background: #0f172a; color: #ffffff; font-size: 16px; font-weight: 600; cursor: pointer; transition: transform 0.05s, background 0.15s; }\n  button:hover:not(:disabled) { background: #1e293b; }\n  button:active:not(:disabled) { transform: scale(0.99); }\n  button:disabled { opacity: 0.55; cursor: not-allowed; }\n  .status { margin-top: 18px; padding: 14px 16px; border-radius: 10px; font-size: 14px; line-height: 1.5; display: none; }\n  .status.show { display: block; }\n  .status.connecting { background: #fef3c7; color: #92400e; }\n  .status.ok { background: #dcfce7; color: #166534; }\n  .status.error { background: #fee2e2; color: #991b1b; }\n  .footer { margin-top: 26px; padding-top: 18px; border-top: 1px solid #e2e8f0; font-size: 12px; color: #94a3b8; line-height: 1.5; }\n</style>\n</head>\n<body>\n<div class=\"card\">\n  <h1>Entrevista de evaluaci\u00f3n</h1>\n  <p class=\"lead\">Programa de Exportaci\u00f3n de Servicios Modernos. Indique su n\u00famero y nuestra asistente <strong>Sof\u00eda</strong> lo llamar\u00e1 en menos de un minuto. La conversaci\u00f3n dura unos quince minutos.</p>\n  <ul class=\"notes\">\n    <li>Use aud\u00edfonos o un lugar tranquilo.</li>\n    <li>Conteste cuando reciba la llamada entrante.</li>\n    <li>Puede colgar en cualquier momento.</li>\n  </ul>\n  <form id=\"callForm\">\n    <label for=\"country\">Pa\u00eds</label>\n    <div class=\"row\">\n      <div class=\"country\">\n        <select id=\"country\" name=\"country\">\n          <option value=\"+1\" data-placeholder=\"809 123 4567\" selected>\ud83c\udde9\ud83c\uddf4 R. Dominicana (+1)</option>\n          <option value=\"+57\" data-placeholder=\"300 123 4567\">\ud83c\udde8\ud83c\uddf4 Colombia (+57)</option>\n        </select>\n      </div>\n      <div class=\"phone\">\n        <input id=\"phone\" name=\"phone\" type=\"tel\" inputmode=\"tel\" autocomplete=\"tel-national\" placeholder=\"809 123 4567\" required />\n      </div>\n    </div>\n    <button id=\"submitBtn\" type=\"submit\">\ud83d\udcde Ll\u00e1mame ahora</button>\n  </form>\n  <div id=\"status\" class=\"status\"></div>\n  <div class=\"footer\">Powered by Retell AI \u00b7 DataSmarts \u00b7 Sus respuestas ser\u00e1n revisadas por un humano del programa.</div>\n</div>\n<script>\n(function(){\n  const form = document.getElementById('callForm');\n  const country = document.getElementById('country');\n  const phone = document.getElementById('phone');\n  const btn = document.getElementById('submitBtn');\n  const statusEl = document.getElementById('status');\n\n  const updatePlaceholder = () => {\n    const opt = country.options[country.selectedIndex];\n    phone.placeholder = opt.dataset.placeholder || '';\n  };\n  country.addEventListener('change', updatePlaceholder);\n  updatePlaceholder();\n\n  const setStatus = (msg, kind) => {\n    statusEl.textContent = msg;\n    statusEl.className = 'status show ' + (kind || '');\n  };\n\n  form.addEventListener('submit', async (ev) => {\n    ev.preventDefault();\n    const digits = (phone.value || '').replace(/\\D/g, '');\n    if (digits.length < 7) {\n      setStatus('Por favor ingrese un n\u00famero v\u00e1lido.', 'error');\n      phone.focus();\n      return;\n    }\n    btn.disabled = true;\n    setStatus('Solicitando llamada\u2026', 'connecting');\n    try {\n      const resp = await fetch('/webhook/web-survey-call', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ country_code: country.value, phone: digits })\n      });\n      const data = await resp.json().catch(() => ({}));\n      if (!resp.ok || !data.call_id) {\n        const reason = (data && (data.error || data.message)) || ('Error ' + resp.status);\n        throw new Error(reason);\n      }\n      setStatus('\u2705 Llamada en camino. Su tel\u00e9fono sonar\u00e1 en unos segundos. Puede cerrar esta p\u00e1gina.', 'ok');\n    } catch (e) {\n      console.error(e);\n      setStatus('No se pudo iniciar la llamada: ' + e.message, 'error');\n      btn.disabled = false;\n    }\n  });\n})();\n</script>\n</body>\n</html>",
        "options": {
          "responseCode": 200,
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              },
              {
                "name": "Cache-Control",
                "value": "no-store"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        240,
        0
      ],
      "id": "b0000000-0000-4000-8000-000000000002",
      "name": "Respond HTML"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "web-survey-call",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        240
      ],
      "id": "b0000000-0000-4000-8000-000000000003",
      "name": "POST web-survey-call"
    },
    {
      "parameters": {
        "jsCode": "const body = $input.first().json.body || {};\nconst country = String(body.country_code || '').trim();\nconst rawPhone = String(body.phone || '');\nconst digits = rawPhone.replace(/\\D/g, '');\nconst allowed = ['+1', '+57'];\nif (!allowed.includes(country)) {\n  throw new Error('country_code must be +1 or +57');\n}\nif (digits.length < 7 || digits.length > 15) {\n  throw new Error('phone must be 7-15 digits');\n}\nreturn [{ json: {\n  from_number: '+18737375073',\n  to_number: country + digits,\n  override_agent_id: 'agent_c08a58dd2fc26d6bbb62911625'\n} }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        240,
        240
      ],
      "id": "b0000000-0000-4000-8000-000000000006",
      "name": "Validate Input"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.retellai.com/v2/create-phone-call",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"from_number\": \"{{ $json.from_number }}\",\n  \"to_number\": \"{{ $json.to_number }}\",\n  \"override_agent_id\": \"{{ $json.override_agent_id }}\"\n}",
        "options": {
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        480,
        240
      ],
      "id": "b0000000-0000-4000-8000-000000000004",
      "name": "Create Phone Call",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const item = $input.first().json;\nconst statusCode = item.statusCode || 0;\nconst body = item.body || {};\nif (statusCode >= 200 && statusCode < 300 && body.call_id) {\n  return [{ json: { ok: true, status: 200, payload: { call_id: body.call_id, call_status: body.call_status || 'registered' } } }];\n}\nconst errMsg = body.message || body.error || ('Retell returned status ' + statusCode);\nreturn [{ json: { ok: false, status: statusCode >= 400 ? statusCode : 502, payload: { error: errMsg } } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        240
      ],
      "id": "b0000000-0000-4000-8000-000000000007",
      "name": "Format Response"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json.payload }}",
        "options": {
          "responseCode": "={{ $json.status }}",
          "responseHeaders": {
            "entries": [
              {
                "name": "Cache-Control",
                "value": "no-store"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        960,
        240
      ],
      "id": "b0000000-0000-4000-8000-000000000005",
      "name": "Respond Call Result"
    }
  ],
  "connections": {
    "GET web-survey": {
      "main": [
        [
          {
            "node": "Respond HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST web-survey-call": {
      "main": [
        [
          {
            "node": "Validate Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Input": {
      "main": [
        [
          {
            "node": "Create Phone Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Phone Call": {
      "main": [
        [
          {
            "node": "Format Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Response": {
      "main": [
        [
          {
            "node": "Respond Call Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  }
}

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

Spanish Phone Survey — Web Call. Uses httpRequest. Webhook trigger; 7 nodes.

Source: https://github.com/jesus-a-martinez-v/spanish-phone-survey/blob/4a96d756d669f613debcffb842bfbcb1bdd04f54/n8n/web-survey-workflow.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di

n8n, Execute Workflow Trigger, HTTP Request +1
Web Scraping

This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .

HTTP Request, Ssh
Web Scraping

This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c

HTTP Request
Web Scraping

Sign PDF documents with legally-compliant digital signatures using X.509 certificates. Supports multiple PAdES signature levels (B, T, LT, LTA) with optional visible stamps.

Execute Command, HTTP Request, Read Write File +1
Web Scraping

📡 This workflow serves as the central Alpha Vantage API fetcher for Tesla trading indicators, delivering cleaned 20-point JSON outputs for three timeframes: , , and . It is required by the following a

HTTP Request