@vocantai/n8n-nodes-translation-vocantai
Version:
Audio file transcription services. Your speech. Private.
196 lines • 8.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.VocantAIOrchestrator = void 0;
class VocantAIOrchestrator {
constructor() {
this.description = {
displayName: 'VocantAI Speech-to-Text',
name: 'vocantAIOrchestrator',
icon: 'file:vocant.svg',
group: ['transform'],
version: 1,
description: 'Upload and download transcription in one node',
defaults: {
name: 'VocantAI Speech-to-Text',
},
inputs: ["main"],
outputs: ["main"],
credentials: [
{
name: 'vocantApi',
required: true,
},
],
properties: [
{
displayName: 'Audio File (binary)',
name: 'file',
type: 'string',
default: 'data',
required: true,
hint: 'The name of the input binary field containing the audio file to process',
},
{
displayName: 'Use Original Filename',
name: 'useOriginalFilename',
type: 'boolean',
default: false,
description: 'Whether to use the original filename for the transcription file',
},
{
displayName: 'Polling Interval (seconds)',
name: 'pollInterval',
type: 'number',
default: 5,
description: 'How often to check job status',
},
{
displayName: 'Max Wait Time (seconds)',
name: 'maxWait',
type: 'number',
default: 900,
description: 'Maximum time to wait for transcription',
},
],
};
}
async execute() {
var _a;
const items = this.getInputData();
const returnData = [];
const credentials = await this.getCredentials('vocantApi');
for (let i = 0; i < items.length; i++) {
try {
const binaryPropertyName = this.getNodeParameter('file', i);
const useOriginalFilename = this.getNodeParameter('useOriginalFilename', i);
const pollInterval = this.getNodeParameter('pollInterval', i);
const maxWait = this.getNodeParameter('maxWait', i);
console.log(JSON.stringify(items[i], null, 2));
if (!((_a = items[i].binary) === null || _a === void 0 ? void 0 : _a[binaryPropertyName])) {
throw new Error(`No binary data found for property "${binaryPropertyName}": ${JSON.stringify(items[i], null, 2)}`);
}
const binaryData = items[i].binary[binaryPropertyName];
const buffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
console.log('Item', i, 'binary:', items[i].binary);
console.log('binaryPropertyName:', binaryPropertyName);
console.log('Requesting presigned URL...');
const presignedOptions = {
method: 'POST',
url: 'https://app.vocant.ai/api/webhook/presigned',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': credentials.apiKey,
},
body: {
fileName: binaryData.fileName,
fileSize: buffer.length,
contentType: binaryData.mimeType,
options: {
useOriginalFilename,
},
},
json: true,
};
const presignedResponse = await this.helpers.httpRequest(presignedOptions);
const { jobId, uploadUrl } = presignedResponse;
console.log('Presigned response success for jobId:', jobId);
console.log('Uploading file to presigned URL...');
const uploadOptions = {
method: 'PUT',
url: uploadUrl,
headers: {
'Content-Type': binaryData.mimeType || 'audio/mpeg',
},
body: buffer,
};
await this.helpers.httpRequest(uploadOptions);
console.log('Check for transcription status...');
let status = 'pending';
let waited = 0;
let transcriptionUrl = '';
while (waited < maxWait) {
await new Promise((resolve) => setTimeout(resolve, pollInterval * 1000));
waited += pollInterval;
const statusOptions = {
method: 'GET',
url: `https://app.vocant.ai/api/webhook/status/${jobId}`,
headers: {
Accept: 'application/json',
'x-api-key': credentials.apiKey,
},
json: true,
};
const statusResponse = await this.helpers.httpRequest(statusOptions);
const state = statusResponse.state;
const downloadUrl = statusResponse.downloadUrl;
console.log(`State for jobId ${jobId}: ${state}`);
console.log('Full status response:', JSON.stringify(statusResponse, null, 2));
if (state === 'completed' && typeof downloadUrl === 'string' && downloadUrl) {
transcriptionUrl = downloadUrl;
break;
}
if (state === 'failed') {
throw new Error(`Transcription failed: ${jobId}: ${statusResponse.message || 'Unknown error'}`);
}
}
if (!transcriptionUrl) {
returnData.push({
json: {
success: false,
jobId,
error: `Transcription jobId ${jobId} did not complete in time`,
status,
waited,
},
pairedItem: { item: i },
});
continue;
}
const downloadOptions = {
method: 'GET',
url: `https://app.vocant.ai${transcriptionUrl}`,
headers: {
'x-api-key': credentials.apiKey,
},
encoding: 'text',
};
const response = await this.helpers.httpRequest(downloadOptions);
const fileName = useOriginalFilename && binaryData.fileName
? binaryData.fileName.replace(/\.[^/.]+$/, '') + '_transcription.txt'
: `transcription_${jobId}.txt`;
const binaryResponse = {
data: Buffer.from(response).toString('base64'),
mimeType: 'text/plain',
fileName,
};
returnData.push({
json: {
success: true,
jobId,
status,
waited,
},
binary: {
data: binaryResponse,
},
pairedItem: { item: i },
});
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
},
pairedItem: { item: i },
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.VocantAIOrchestrator = VocantAIOrchestrator;
//# sourceMappingURL=VocantAIOrchestrator.node.js.map