// Helper function: Convert ArrayBuffer to Base64 (for web environments)
function arrayBufferToBase64(buffer) {
let binary = ‘’;
const bytes = new Uint8Array(buffer);
const len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
async function generateVoice() {
const apiKey = ai.config.elevenlabs_api_key;
const voiceId = ai.config.voice_id;
const text = ai.vars.text_to_speak;
const outputVariable = ai.config.outputVariable || ‘voiceAudioUrl’;
if (!apiKey || !voiceId || !text) {
throw new Error(‘Missing required parameters: elevenlabs_api_key, voice_id, or text_to_speak’);
}
// move output_format to URL
const url = https://api.elevenlabs.io/v1/text-to-speech/${voiceId}?output_format=mp3_44100_128
;
const payload = {
text: text,
model_id: ‘eleven_turbo_v2_5’,
voice_settings: {
stability: 0.5,
similarity_boost: 0.75
}
};
try {
const response = await fetch(url, {
method: ‘POST’,
headers: {
‘xi-api-key’: apiKey,
‘Content-Type’: ‘application/json’,
‘Accept’: ‘audio/mpeg’
},
body: JSON.stringify(payload)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`ElevenLabs API error: ${response.status} - ${errorText}`);
}
const audioBuffer = await response.arrayBuffer();
const base64Audio = arrayBufferToBase64(audioBuffer);
const audioUrl = `data:audio/mpeg;base64,${base64Audio}`;
ai.vars[outputVariable] = audioUrl;
console.log(`✅ Audio generated and saved to variable: ${outputVariable}`);
} catch (error) {
console.error(‘ Error generating voice:’, error);
throw new Error(Failed to generate voice: ${error.message}
);
}
}
await generateVoice();