{ "name": "Brainiall - Review an authorized PT-BR support call", "nodes": [ {"parameters": {}, "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [-620, 160], "id": "a1570002-0001-4000-8000-000000000001", "name": "Run manually"}, { "parameters": {"assignments": {"assignments": [ {"id": "a1570002-0002-4000-8000-000000000001", "name": "mediaUrl", "value": "https://www.brainiall.com/assets/brainiall-ptbr-multispeaker-demo.mp3", "type": "string"}, {"id": "a1570002-0003-4000-8000-000000000001", "name": "language", "value": "pt", "type": "string"}, {"id": "a1570002-0004-4000-8000-000000000001", "name": "diarization", "value": true, "type": "boolean"}, {"id": "a1570002-0005-4000-8000-000000000001", "name": "maxDurationMinutes", "value": 20, "type": "number"}, {"id": "a1570002-0006-4000-8000-000000000001", "name": "confirmRightsAndConsent", "value": false, "type": "boolean"} ]}, "options": {}}, "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [-400, 160], "id": "a1570002-0007-4000-8000-000000000001", "name": "Set authorized support call" }, { "parameters": {"jsCode": "const cfg = $json;\nif (cfg.confirmRightsAndConsent !== true) throw new Error('Confirm processing rights and any required speaker consent before running');\nlet parsed;\ntry { parsed = new URL(String(cfg.mediaUrl || '')); } catch { throw new Error('Use one valid public HTTPS media URL'); }\nconst host = parsed.hostname.toLowerCase();\nif (parsed.protocol !== 'https:' || parsed.username || parsed.password || !host.includes('.') || host === 'localhost' || host.endsWith('.local') || host.endsWith('.internal') || /^10\\.|^127\\.|^169\\.254\\.|^192\\.168\\.|^172\\.(1[6-9]|2[0-9]|3[01])\\./.test(host)) throw new Error('Use one public HTTPS media URL without embedded credentials');\nconst language = String(cfg.language || 'pt').toLowerCase();\nif (!/^[a-z]{2,3}$/.test(language)) throw new Error('Language must be a two-to-three-letter ISO code');\nconst maxDurationMinutes = Number(cfg.maxDurationMinutes);\nif (!Number.isInteger(maxDurationMinutes) || maxDurationMinutes < 1 || maxDurationMinutes > 20) throw new Error('Duration must be between 1 and 20 minutes');\nreturn [{json:{sources:[parsed.toString()],language,diarization:true,output_formats:['json','srt','vtt','txt'],maxDurationMinutes,integrationSource:'n8n-c157-support-call-review'}}];"}, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [-160, 160], "id": "a1570002-0008-4000-8000-000000000001", "name": "Validate consent URL and limits" }, { "parameters": {"method": "POST", "url": "https://api.apify.com/v2/acts/vivid_astronaut~audio-video-transcription-diarization/run-sync-get-dataset-items", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendQuery": true, "queryParameters": {"parameters": [{"name": "maxItems", "value": "1"}, {"name": "maxTotalChargeUsd", "value": "0.05"}, {"name": "timeout", "value": "300"}]}, "sendBody": true, "contentType": "raw", "rawContentType": "application/json", "body": "={{ JSON.stringify($json) }}", "options": {"timeout": 295000}}, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [80, 160], "id": "a1570002-0009-4000-8000-000000000001", "name": "Transcribe support call on Apify" }, { "parameters": {"jsCode": "const expected = $('Validate consent URL and limits').first().json;\nconst rows = $input.all().flatMap((item) => Array.isArray(item.json) ? item.json : [item.json]);\nif (rows.length !== 1) throw new Error('Expected exactly one transcription result');\nconst row = rows[0];\nif (row.url !== expected.sources[0] || row.integrationSource !== expected.integrationSource || typeof row.text !== 'string' || !Array.isArray(row.segments) || !row.files || typeof row.files !== 'object' || !Number.isInteger(row.charged_minutes) || row.charged_minutes < 1 || row.charged_minutes > expected.maxDurationMinutes) throw new Error('The Actor response failed semantic validation');\nreturn [{json:row}];"}, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [320, 160], "id": "a1570002-0010-4000-8000-000000000001", "name": "Validate speaker-labelled result" }, { "parameters": {"content": "## Configure before the first run\n\nUse only a support-call recording you are authorized to process and review applicable notice, consent, retention, and privacy requirements. Set **confirmRightsAndConsent** to true only after that review. Select an n8n Header Auth credential on **Transcribe support call on Apify**: `Authorization` = `Bearer YOUR_SCOPED_APIFY_TOKEN`.\n\nThe request is capped at USD 0.05 and 20 minutes. Speaker labels are model-generated placeholders for human renaming, not biometric identity or compliance evidence.", "height": 380, "width": 540, "color": 5}, "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-620, -330], "id": "a1570002-0011-4000-8000-000000000001", "name": "Setup privacy and review boundary" } ], "connections": { "Run manually": {"main": [[{"node": "Set authorized support call", "type": "main", "index": 0}]]}, "Set authorized support call": {"main": [[{"node": "Validate consent URL and limits", "type": "main", "index": 0}]]}, "Validate consent URL and limits": {"main": [[{"node": "Transcribe support call on Apify", "type": "main", "index": 0}]]}, "Transcribe support call on Apify": {"main": [[{"node": "Validate speaker-labelled result", "type": "main", "index": 0}]]} }, "pinData": {}, "settings": {"executionOrder": "v1"}, "meta": {"templateCredsSetupCompleted": false}, "tags": [], "active": false }