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 →
{
"nodes": [
{
"parameters": {
"url": "https://cluster.dentalautomation.ai/v2/iv/transactions/getByPatient",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "clientId",
"value": "60198b19bb70666ce6a6a37c"
},
{
"name": "practiceld",
"value": "6019946277c6020112360b92"
},
{
"name": "appointmentDateStart",
"value": "2025-01-01"
},
{
"name": "appointmentDateEnd",
"value": "2025-01-02"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apiKey",
"value": "dcy1cbUi4lbbmUT9JQ7PFtRju4xY3w4g"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-32,
32
],
"id": "13e351cc-6499-4fcd-80b1-94c9b4cdeca7",
"name": "HTTP Request1",
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"fieldToSplitOut": "data",
"options": {}
},
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [
176,
32
],
"id": "38923b27-88db-4658-870f-4bb5ea477600",
"name": "Split Out"
},
{
"parameters": {
"jsCode": "const crypto = require('crypto');\n\n// 1. Configuraci\u00f3n (Usa tu variable de entorno)\n// Aseg\u00farate de que $env.ENCRYPTION_KEY tenga 32 caracteres para AES-256\nconst algorithm = 'aes-256-cbc';\nconst key = $env.ENCRYPTION_KEY; \nconst ivLength = 16; // AES standard\n\n// Iteramos sobre cada paciente (item)\nreturn items.map(item => {\n const data = item.json;\n \n // A. Generar HASH (Huella digital para b\u00fasquedas)\n // Usamos SHA-256 nativo\n const hash = crypto.createHash('sha256').update(JSON.stringify(data)).digest('hex');\n\n // B. ENCRIPTAR (La B\u00f3veda)\n const iv = crypto.randomBytes(ivLength);\n // Agregamos 'hex' como segundo par\u00e1metro\nconst cipher = crypto.createCipheriv(algorithm, Buffer.from(key, 'hex'), iv);\n \n let encrypted = cipher.update(JSON.stringify(data), 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n // Guardamos el IV junto con la data (necesario para desencriptar)\n // Formato: IV:DATA\n const encryptedPayload = iv.toString('hex') + ':' + encrypted;\n\n // C. Retornar el objeto listo para MySQL\n return {\n json: {\n payload_hash: hash,\n encrypted_payload: encryptedPayload,\n original_data_preview: data._id // Opcional, solo para que veas cu\u00e1l es\n }\n };\n});"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
384,
32
],
"id": "43e90f1d-f14b-4869-ab7f-ff999f6632ee",
"name": "Code in JavaScript"
},
{
"parameters": {
"table": {
"__rl": true,
"value": "raw_api_ingest",
"mode": "list",
"cachedResultName": "raw_api_ingest"
},
"dataMode": "defineBelow",
"valuesToSend": {
"values": [
{
"column": "payload_hash",
"value": "={{ $json.payload_hash }}"
},
{
"column": "raw_payload",
"value": "={{ $json.encrypted_payload }}"
},
{
"column": "is_processed",
"value": "0"
},
{
"column": "endpoint_source",
"value": "API_DENTAL"
}
]
},
"options": {
"skipOnConflict": true
}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
592,
32
],
"id": "0c9a2d16-fb1f-4a6c-801d-eecf740e8eed",
"name": "Insert rows in a table",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const crypto = require('crypto');\nconst algorithm = 'aes-256-cbc';\nconst key = $env.ENCRYPTION_KEY;\n\nreturn items.map(item => {\n // 1. Intentamos tomar la data encriptada. \n // OJO: Como venimos del nodo MySQL, a veces la data original viaja en 'json.raw_payload' \n // o 'json.encrypted_payload' dependiendo de si el nodo anterior pas\u00f3 la entrada.\n const encryptedText = item.json.raw_payload || item.json.encrypted_payload; \n\n if (!encryptedText || !encryptedText.includes(':')) {\n return { \n json: { \n ERROR: \"No se recibi\u00f3 la data encriptada del nodo anterior.\",\n HINT: \"Aseg\u00farate de que el nodo MySQL tenga activada la opci\u00f3n 'Pass Through' o conecta este nodo directo al de encriptaci\u00f3n.\"\n } \n };\n }\n\n try {\n // 2. Proceso de Desencriptado (El mismo de siempre)\n const textParts = encryptedText.split(':');\n const iv = Buffer.from(textParts.shift(), 'hex');\n const encryptedData = textParts.join(':');\n\n const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv);\n let decrypted = decipher.update(encryptedData, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n // 3. RESULTADO PARA EL JEFE\n return {\n json: {\n \"TEST_RESULT\": \"\u2705 PRUEBA EXITOSA\",\n \"1_LO_QUE_HAY_EN_DB\": encryptedText.substring(0, 30) + \"...\", // Mostramos solo un pedacito de la basura\n \"2_LO_QUE_VE_EL_BOT\": JSON.parse(decrypted) // El paciente recuperado\n }\n };\n } catch (error) {\n return { json: { STATUS: \"FALL\u00d3\", error: error.message } };\n }\n});"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1104,
96
],
"id": "c6e83f0a-f663-4590-80e3-1b679259f353",
"name": "Code in JavaScript1"
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT raw_payload FROM raw_api_ingest ORDER BY ingest_id DESC LIMIT 1;",
"options": {}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
800,
32
],
"id": "eeb4c3d8-6d65-4462-b48c-48fe3d580b91",
"name": "Execute a SQL query",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"triggerAtMinute": 1
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-352,
320
],
"id": "1e77ecb8-213e-4391-a083-347df124d1b2",
"name": "Schedule Trigger"
},
{
"parameters": {
"operation": "executeQuery",
"query": "START TRANSACTION;\n\n-- 1. COPIAR (Con protecci\u00f3n anti-duplicados)\n-- Usamos INSERT IGNORE: Si el hash ya existe en el archivo, \n-- simplemente no lo copia y sigue adelante sin dar error.\nINSERT IGNORE INTO raw_api_ingest_archive (\n endpoint_source, \n raw_payload, \n payload_hash, \n ingested_at, \n is_processed\n)\nSELECT \n endpoint_source, \n raw_payload, \n payload_hash, \n ingested_at, \n is_processed\nFROM raw_api_ingest\nWHERE ingested_at < NOW() - INTERVAL 5 MINUTE; \n-- (Recuerda cambiar '0 MINUTE' por '7 DAY' cuando pases a producci\u00f3n)\n\n-- 2. BORRAR (Limpiar la mesa)\n-- Borramos de la ingesta todo lo que ya cumpli\u00f3 el tiempo.\n-- No importa si se copi\u00f3 o si se ignor\u00f3 (porque ya exist\u00eda),\n-- el objetivo es que salga de la tabla principal.\nDELETE FROM raw_api_ingest\nWHERE ingested_at < NOW() - INTERVAL 5 MINUTE;\n\nCOMMIT;",
"options": {}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
32,
448
],
"id": "ebbaadab-6870-4520-b6ea-11e231729aaf",
"name": "Vault Archiving",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
}
],
"connections": {
"HTTP Request1": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Insert rows in a table",
"type": "main",
"index": 0
}
]
]
},
"Insert rows in a table": {
"main": [
[
{
"node": "Execute a SQL query",
"type": "main",
"index": 0
}
]
]
},
"Execute a SQL query": {
"main": [
[
{
"node": "Code in JavaScript1",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Vault Archiving",
"type": "main",
"index": 0
},
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
]
]
}
},
"meta": {
"templateCredsSetupCompleted": true
}
}
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.
httpHeaderAuthmySql
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Ingest Api. Uses httpRequest, mySql. Scheduled trigger; 8 nodes.
Source: https://github.com/Chrisan2i/VoiceCall/blob/1d8fec7371ca29a6362823b8ac180a8246b91af7/workflows/01_Ingest_API.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
[eliminado] HS Factura. Uses httpRequest, itemLists, mySql. Scheduled trigger; 15 nodes.
[Oscar] GetInvoicesFromFapro. Uses httpRequest, mySql. Scheduled trigger; 14 nodes.
[Oscar] addNewBusinessLogged. Uses httpRequest, mySql. Scheduled trigger; 8 nodes.
MainWorkflow. Uses httpRequest, mySql, emailSend. Scheduled trigger; 8 nodes.
Sincronização entre Bancos de Dados. Uses mySql, httpRequest. Scheduled trigger; 5 nodes.