{
  "name": "Polyglot STT - Telegram voice",
  "active": false,
  "nodes": [
    {
      "id": "5179cae2-8dfa-58de-ae34-f1102830b6a5",
      "name": "Telegram message",
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      }
    },
    {
      "id": "04d17511-a2b3-5d6e-89c5-b324725677af",
      "name": "Configure",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        260,
        0
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "actor",
              "name": "actorId",
              "value": "andronixmd~speech-to-text-transcriber",
              "type": "string"
            },
            {
              "id": "budget",
              "name": "maxTotalChargeUsd",
              "value": 1,
              "type": "number"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      }
    },
    {
      "id": "dc0b7d4b-3248-5e25-aa80-b1b405464ced",
      "name": "Download voice",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        520,
        0
      ],
      "parameters": {
        "resource": "file",
        "operation": "get",
        "fileId": "={{ $('Telegram message').first().json.message.voice.file_id }}",
        "download": true,
        "additionalFields": {}
      }
    },
    {
      "id": "c2b2e160-eb26-5e19-90f0-f2dfc9c6826b",
      "name": "Create temp store",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        780,
        0
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/key-value-stores",
        "method": "POST",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={}"
      },
      "retryOnFail": false
    },
    {
      "id": "bed8ec09-94e7-5609-b836-446177ec8400",
      "name": "Attach voice binary",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1040,
        0
      ],
      "parameters": {
        "jsCode": "const binary = $('Download voice').first().binary; if (!binary?.data) throw new Error('Telegram voice download did not return binary data'); return [{json:{},binary}];"
      }
    },
    {
      "id": "a02b575b-792f-5c5a-b3f4-f699d74f9b67",
      "name": "Upload voice",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1300,
        0
      ],
      "parameters": {
        "url": "={{ 'https://api.apify.com/v2/key-value-stores/' + $('Create temp store').first().json.data.id + '/records/voice.ogg' }}",
        "method": "PUT",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000,
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        },
        "sendBody": true,
        "contentType": "binaryData",
        "inputDataFieldName": "data",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "audio/ogg"
            }
          ]
        }
      },
      "retryOnFail": false
    },
    {
      "id": "9da15799-4cd5-5d35-a2ea-9276fefc499f",
      "name": "Get temp store",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        0,
        220
      ],
      "parameters": {
        "url": "={{ 'https://api.apify.com/v2/key-value-stores/' + $('Create temp store').first().json.data.id }}",
        "method": "GET",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        }
      },
      "retryOnFail": false
    },
    {
      "id": "12da2ea5-96c6-59f2-986d-94d197606268",
      "name": "Prepare media URL",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        260,
        220
      ],
      "parameters": {
        "jsCode": "const store = $('Get temp store').first().json.data;\nif (!store?.id || !store.urlSigningSecretKey) throw new Error('Temporary store signing key unavailable');\nconst crypto = require('crypto');\nlet value = BigInt('0x' + crypto.createHmac('sha256', store.urlSigningSecretKey).update('voice.ogg').digest('hex').slice(0,30));\nconst alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\nlet signature = '';\ndo { signature = alphabet[Number(value % 62n)] + signature; value /= 62n; } while (value > 0n);\nreturn [{json:{mediaUrl:'https://api.apify.com/v2/key-value-stores/' + store.id + '/records/voice.ogg?signature=' + signature,storeId:store.id}}];"
      }
    },
    {
      "id": "efe37ab4-5810-5dfd-92ad-970f1273f532",
      "name": "Start Actor",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        520,
        220
      ],
      "parameters": {
        "url": "={{ 'https://api.apify.com/v2/acts/' + $('Configure').first().json.actorId + '/runs' }}",
        "method": "POST",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ {urls:[$('Prepare media URL').first().json.mediaUrl], timestamps:'segment'} }}",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "maxTotalChargeUsd",
              "value": "={{ $('Configure').first().json.maxTotalChargeUsd }}"
            }
          ]
        }
      },
      "retryOnFail": false
    },
    {
      "id": "69f3fa28-fd86-5fdb-88c4-045298db6820",
      "name": "Wait ten seconds",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        780,
        220
      ],
      "parameters": {
        "amount": 10,
        "unit": "seconds"
      }
    },
    {
      "id": "4bca4af0-976d-5b42-89a1-397c65c3c1f7",
      "name": "Get run",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1040,
        220
      ],
      "parameters": {
        "url": "={{ 'https://api.apify.com/v2/actor-runs/' + $('Start Actor').first().json.data.id }}",
        "method": "GET",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        }
      },
      "retryOnFail": false
    },
    {
      "id": "a94b6c8f-1cc9-59ac-999b-c63e9f223b6d",
      "name": "Check run",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1300,
        220
      ],
      "parameters": {
        "jsCode": "const run = $input.first().json.data;\nconst statuses = ['READY','RUNNING','SUCCEEDED','FAILED','ABORTING','ABORTED','TIMING-OUT','TIMED-OUT'];\nif (!run || !statuses.includes(run.status)) throw new Error('Unexpected Apify run status');\nconst terminal = ['SUCCEEDED','FAILED','ABORTED','TIMED-OUT'].includes(run.status);\nif (!terminal && $runIndex >= 360) throw new Error('Polling limit reached. Inspect the existing run; do not create another run blindly. Telegram temporary storage may require manual cleanup.');\nreturn [{json:{...run,terminal,succeeded:run.status === 'SUCCEEDED'}}];"
      }
    },
    {
      "id": "ccb45db4-b3ed-5000-ae8b-1db24f4d54c7",
      "name": "Run finished",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        0,
        440
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "Run finished",
              "leftValue": "={{ $json.terminal }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "2e41cef3-776a-5cd6-a77f-5d365cd9cabc",
      "name": "Run succeeded",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        260,
        440
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "Run succeeded",
              "leftValue": "={{ $json.succeeded }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "ec63cf35-c291-5d7f-91a9-751648818d03",
      "name": "Run failed",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        520,
        440
      ],
      "parameters": {
        "errorMessage": "Actor did not complete successfully. Inspect the existing run and saved JSON before retrying."
      }
    },
    {
      "id": "86113463-66c5-5ec6-8fbe-3e46794d44f9",
      "name": "Delete temp store after failed run",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        780,
        440
      ],
      "parameters": {
        "url": "={{ 'https://api.apify.com/v2/key-value-stores/' + $('Create temp store').first().json.data.id }}",
        "method": "DELETE",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        }
      },
      "retryOnFail": false
    },
    {
      "id": "51f9bafc-cd30-5bf3-b29e-183fd6b08fa5",
      "name": "Get full result",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1040,
        440
      ],
      "parameters": {
        "url": "={{ 'https://api.apify.com/v2/key-value-stores/' + $('Check run').first().json.defaultKeyValueStoreId + '/records/item-000-result' }}",
        "method": "GET",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        }
      },
      "retryOnFail": false
    },
    {
      "id": "f5eaf74c-dbe3-5c08-a126-3078d547abcb",
      "name": "Delete temp store",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1300,
        440
      ],
      "parameters": {
        "url": "={{ 'https://api.apify.com/v2/key-value-stores/' + $('Create temp store').first().json.data.id }}",
        "method": "DELETE",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        }
      },
      "retryOnFail": false
    },
    {
      "id": "f5d16b77-fe20-59b6-83c2-1eec20d16f2e",
      "name": "Reply with transcript",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        0,
        660
      ],
      "parameters": {
        "resource": "message",
        "operation": "sendMessage",
        "chatId": "={{ $('Telegram message').first().json.message.chat.id }}",
        "text": "={{ (() => { const row = $('Get full result').first().json.value; if (!row || (typeof row.text !== 'string' && typeof row.error !== 'string')) throw new Error('Saved transcription unavailable; inspect the existing run'); return ('Transcript (first 3800 characters):\\n' + (row.text || row.error || 'Inspect saved result')).slice(0,4000); })() }}",
        "additionalFields": {
          "appendAttribution": false
        }
      }
    }
  ],
  "connections": {
    "Telegram message": {
      "main": [
        [
          {
            "node": "Configure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure": {
      "main": [
        [
          {
            "node": "Download voice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download voice": {
      "main": [
        [
          {
            "node": "Create temp store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create temp store": {
      "main": [
        [
          {
            "node": "Attach voice binary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Attach voice binary": {
      "main": [
        [
          {
            "node": "Upload voice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload voice": {
      "main": [
        [
          {
            "node": "Get temp store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get temp store": {
      "main": [
        [
          {
            "node": "Prepare media URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare media URL": {
      "main": [
        [
          {
            "node": "Start Actor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Actor": {
      "main": [
        [
          {
            "node": "Wait ten seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait ten seconds": {
      "main": [
        [
          {
            "node": "Get run",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get run": {
      "main": [
        [
          {
            "node": "Check run",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check run": {
      "main": [
        [
          {
            "node": "Run finished",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run finished": {
      "main": [
        [
          {
            "node": "Run succeeded",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait ten seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run succeeded": {
      "main": [
        [
          {
            "node": "Get full result",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Delete temp store after failed run",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete temp store after failed run": {
      "main": [
        [
          {
            "node": "Run failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get full result": {
      "main": [
        [
          {
            "node": "Delete temp store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete temp store": {
      "main": [
        [
          {
            "node": "Reply with transcript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "executionTimeout": 3900,
    "saveDataErrorExecution": "none",
    "saveDataSuccessExecution": "none",
    "saveExecutionProgress": false
  },
  "pinData": {},
  "tags": []
}
