AutomationFlowsData & Sheets › Schedule Voice AI Analytics to Postgres

Schedule Voice AI Analytics to Postgres

Original n8n title: Real-time Voice AI Analytics

Real-time Voice AI Analytics. Uses postgres, httpRequest. Scheduled trigger; 7 nodes.

Cron / scheduled trigger★★★★☆ complexity7 nodesPostgresHTTP Request
Data & Sheets Trigger: Cron / scheduled Nodes: 7 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Postgres 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
{
  "name": "Real-time Voice AI Analytics",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "seconds",
              "secondsInterval": 30
            }
          ]
        }
      },
      "id": "analytics-trigger-001",
      "name": "Analytics Collection Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT * FROM voice_interactions_v2 WHERE created_at > NOW() - INTERVAL '30 seconds' LIMIT 1000;",
        "options": {}
      },
      "id": "recent-interactions-002",
      "name": "Get Recent Interactions",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        460,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Calculate real-time metrics\nconst interactions = $input.all().map(item => item.json);\nconst now = new Date();\nconst thirtySecondsAgo = new Date(now.getTime() - 30000);\n\n// Performance metrics\nconst totalInteractions = interactions.length;\nconst avgProcessingTime = interactions.reduce((sum, i) => sum + (i.processing_metrics?.total_time || 0), 0) / Math.max(totalInteractions, 1);\nconst avgConfidence = interactions.reduce((sum, i) => sum + (i.processing_metrics?.stt_confidence || 0), 0) / Math.max(totalInteractions, 1);\n\n// Language distribution\nconst languageStats = {};\ninteractions.forEach(i => {\n  const lang = i.processing_metrics?.language || 'unknown';\n  languageStats[lang] = (languageStats[lang] || 0) + 1;\n});\n\n// Model usage statistics\nconst modelStats = {};\ninteractions.forEach(i => {\n  const model = i.processing_metrics?.llm_model || 'unknown';\n  modelStats[model] = (modelStats[model] || 0) + 1;\n});\n\n// Quality metrics\nconst qualityMetrics = {\n  high_confidence: interactions.filter(i => (i.processing_metrics?.stt_confidence || 0) > 0.9).length,\n  medium_confidence: interactions.filter(i => {\n    const conf = i.processing_metrics?.stt_confidence || 0;\n    return conf >= 0.7 && conf <= 0.9;\n  }).length,\n  low_confidence: interactions.filter(i => (i.processing_metrics?.stt_confidence || 0) < 0.7).length\n};\n\n// Error tracking\nconst errors = interactions.filter(i => i.processing_metrics?.errors || i.status === 'error').length;\nconst errorRate = totalInteractions > 0 ? (errors / totalInteractions) * 100 : 0;\n\n// User satisfaction (if available)\nconst ratingsData = interactions.filter(i => i.user_feedback?.rating);\nconst avgRating = ratingsData.length > 0 ? \n  ratingsData.reduce((sum, i) => sum + i.user_feedback.rating, 0) / ratingsData.length : null;\n\n// Response time distribution\nconst responseTimeBuckets = {\n  fast: interactions.filter(i => (i.processing_metrics?.total_time || 0) < 1000).length,    // < 1s\n  medium: interactions.filter(i => {\n    const time = i.processing_metrics?.total_time || 0;\n    return time >= 1000 && time < 3000;\n  }).length,  // 1-3s\n  slow: interactions.filter(i => (i.processing_metrics?.total_time || 0) >= 3000).length     // > 3s\n};\n\n// Feature usage\nconst featureUsage = {\n  rag_used: interactions.filter(i => i.processing_metrics?.rag_used).length,\n  voice_activity_detected: interactions.filter(i => i.processing_metrics?.vad_confidence > 0.5).length,\n  multi_language: Object.keys(languageStats).length\n};\n\nconst analytics = {\n  timestamp: now.toISOString(),\n  timeWindow: '30s',\n  performance: {\n    totalInteractions,\n    avgProcessingTime: Math.round(avgProcessingTime),\n    avgConfidence: Math.round(avgConfidence * 100) / 100,\n    errorRate: Math.round(errorRate * 100) / 100,\n    throughput: Math.round((totalInteractions / 30) * 100) / 100 // interactions per second\n  },\n  quality: {\n    ...qualityMetrics,\n    avgRating,\n    ratingsCount: ratingsData.length\n  },\n  distribution: {\n    languages: languageStats,\n    models: modelStats,\n    responseTimes: responseTimeBuckets\n  },\n  features: featureUsage\n};\n\nreturn { json: analytics };"
      },
      "id": "calculate-metrics-003",
      "name": "Calculate Real-time Metrics",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://prometheus:9090/api/v1/write",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "text/plain"
            }
          ]
        },
        "sendBody": true,
        "bodyContentType": "raw",
        "body": "=# Voice AI Metrics\n# Performance\nvoice_ai_interactions_total {{ $json.performance.totalInteractions }} {{ Date.now() }}\nvoice_ai_avg_processing_time_ms {{ $json.performance.avgProcessingTime }} {{ Date.now() }}\nvoice_ai_avg_confidence {{ $json.performance.avgConfidence }} {{ Date.now() }}\nvoice_ai_error_rate_percent {{ $json.performance.errorRate }} {{ Date.now() }}\nvoice_ai_throughput_per_second {{ $json.performance.throughput }} {{ Date.now() }}\n\n# Quality\nvoice_ai_high_confidence_interactions {{ $json.quality.high_confidence }} {{ Date.now() }}\nvoice_ai_medium_confidence_interactions {{ $json.quality.medium_confidence }} {{ Date.now() }}\nvoice_ai_low_confidence_interactions {{ $json.quality.low_confidence }} {{ Date.now() }}\n{{ $json.quality.avgRating ? `voice_ai_avg_rating ${$json.quality.avgRating} ${Date.now()}` : '' }}\n\n# Features\nvoice_ai_rag_usage {{ $json.features.rag_used }} {{ Date.now() }}\nvoice_ai_vad_detections {{ $json.features.voice_activity_detected }} {{ Date.now() }}\nvoice_ai_languages_used {{ $json.features.multi_language }} {{ Date.now() }}\n\n# Response Times\nvoice_ai_fast_responses {{ $json.distribution.responseTimes.fast }} {{ Date.now() }}\nvoice_ai_medium_responses {{ $json.distribution.responseTimes.medium }} {{ Date.now() }}\nvoice_ai_slow_responses {{ $json.distribution.responseTimes.slow }} {{ Date.now() }}",
        "options": {
          "timeout": 5000
        }
      },
      "id": "push-to-prometheus-004",
      "name": "Push Metrics to Prometheus",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        900,
        300
      ],
      "continueOnFail": true
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO analytics_snapshots (timestamp, time_window, metrics_data, total_interactions, avg_processing_time, error_rate, avg_confidence) VALUES ($1, $2, $3, $4, $5, $6, $7)",
        "options": {
          "queryParameters": "={{ $json.timestamp }},{{ $json.timeWindow }},{{ JSON.stringify($json) }},{{ $json.performance.totalInteractions }},{{ $json.performance.avgProcessingTime }},{{ $json.performance.errorRate }},{{ $json.performance.avgConfidence }}"
        }
      },
      "id": "store-analytics-005",
      "name": "Store Analytics Snapshot",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        1120,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "continueOnFail": true
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.performance.errorRate > 5.0 || $json.performance.avgConfidence < 0.8 || $json.performance.avgProcessingTime > 3000 }}",
              "operation": "equal",
              "value2": "true"
            }
          ]
        }
      },
      "id": "check-alerts-006",
      "name": "Check Alert Conditions",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1340,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $vars.SLACK_WEBHOOK_URL }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={\n  \"text\": \"\ud83d\udea8 Voice AI Alert Triggered\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": {\n        \"type\": \"plain_text\",\n        \"text\": \"Voice AI Performance Alert\"\n      }\n    },\n    {\n      \"type\": \"section\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*Performance Issues Detected*\\n\\n\u2022 Error Rate: {{ $('Calculate Real-time Metrics').item.json.performance.errorRate }}%\\n\u2022 Avg Confidence: {{ $('Calculate Real-time Metrics').item.json.performance.avgConfidence }}\\n\u2022 Avg Processing Time: {{ $('Calculate Real-time Metrics').item.json.performance.avgProcessingTime }}ms\\n\u2022 Total Interactions: {{ $('Calculate Real-time Metrics').item.json.performance.totalInteractions }}\\n\\n*Time:* {{ $('Calculate Real-time Metrics').item.json.timestamp }}\"\n      }\n    },\n    {\n      \"type\": \"actions\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"View Dashboard\"\n          },\n          \"url\": \"http://grafana:3000/d/voice-ai-overview\"\n        }\n      ]\n    }\n  ]\n}"
      },
      "id": "send-alert-007",
      "name": "Send Alert Notification",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1560,
        240
      ],
      "continueOnFail": true
    }
  ],
  "connections": {
    "Analytics Collection Trigger": {
      "main": [
        [
          {
            "node": "Get Recent Interactions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Recent Interactions": {
      "main": [
        [
          {
            "node": "Calculate Real-time Metrics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Real-time Metrics": {
      "main": [
        [
          {
            "node": "Push Metrics to Prometheus",
            "type": "main",
            "index": 0
          },
          {
            "node": "Store Analytics Snapshot",
            "type": "main",
            "index": 0
          },
          {
            "node": "Check Alert Conditions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Alert Conditions": {
      "main": [
        [
          {
            "node": "Send Alert Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": false
  },
  "staticData": null,
  "tags": [
    "analytics",
    "monitoring",
    "real-time"
  ],
  "triggerCount": 1,
  "updatedAt": "2025-06-27T00:00:00.000Z",
  "versionId": "1.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

Real-time Voice AI Analytics. Uses postgres, httpRequest. Scheduled trigger; 7 nodes.

Source: https://github.com/161sam/n8n-voice-ai/blob/main/workflows/Real-time-Voice-AI-Analytics.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

Disparador 1.8. Uses itemLists, postgres, emailSend, httpRequest. Scheduled trigger; 85 nodes.

Item Lists, Postgres, Email Send +1
Data & Sheets

공유회_알림톡_크론. Uses postgres, httpRequest, n8n-nodes-solapi. Scheduled trigger; 39 nodes.

Postgres, HTTP Request, N8N Nodes Solapi
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request