Help needed for a node/code

I have a text that I would like to send to eleven labs, but I would like to do divisions.

“n1 xxxxxxx n2 xxxxxxx n3 xxxxxxx” the text follow’s this order, how could I turn this info into many other ‘blocks’ to make it possible the use of loop over items to turn each nNUMBER into a different archive?

Thanks in advance

Hey @lonacunn

// Get the text from the incoming item(s). // This assumes the text is in a property called “text”. // Adjust the path if your field is named differently. const rawText = $input.first().json.text;

// Regex to match each block: “n” followed by a number, then everything until the next “n” or end. // The “s” flag makes dot match newlines as well. const regex = /(n\d+)(.*?)(?=n\d+|$)/gs; const blocks = ;

let match; while ((match = regex.exec(rawText)) !== null) { const number = match[1]; // e.g., “n1” const content = match[2]; // the text after the number blocks.push({ number: number, content: content.trim() // optional: trim whitespace }); }

// Return each block as a separate item return blocks.map(block => ({ json: block }));

What it does:

· $input.first().json.text – accesses the text from the first incoming item (adapt if your field is different). · The regex /(n\d+)(.*?)(?=n\d+|$)/gs finds each n1, n2, etc., captures the number and the content, and stops right before the next nX or the end. · Each matched block becomes an object with number and content. · Finally, we map these objects into n8n items (each with a json property).


3. Loop over the items

After the Code node, you can use a Loop node (or a Split In Batches node with batch size 1) to iterate over each generated item.

· Add a Loop node. · In its settings, set Mode to “Loop over items”. · Inside the loop, connect an ElevenLabs node.


4. Configure the ElevenLabs node inside the loop

In the ElevenLabs node, you’ll reference the current item’s content. Use expressions like:

· Text: {{ $json.content }} (or {{ $json.text }} if you used a different property name) · Voice ID: whatever you set · Output format: mp3, etc.

Make sure to check Attach Binary Data if you want the audio as a binary file for later use.


5. Save each audio file (optional)

If you want to save each file separately, you can add a Write File node after ElevenLabs, also inside the loop. Use an expression for the file name, e.g.:

· File Path: /tmp/audio_{{ $json.number }}.mp3

Now, when the loop runs, it will generate one audio file per block.


6. Example output of the Code node

For input text:

n1 Hello world, this is first part. n2 Second part here. n3 Final part.

The Code node will produce three items:

Item json 1 { “number”: “n1”, “content”: “Hello world, this is first part.” } 2 { “number”: “n2”, “content”: “Second part here.” } 3 { “number”: “n3”, “content”: “Final part.” }


7. Customising for your text format

If your text uses newlines or different separators, the regex will still work because the s flag makes dot match newlines. If the numbers are not exactly like n1, n2 (e.g., n1., n1:), you can adjust the regex accordingly. For example, to allow punctuation after the number: /(n\d+[.:]?)(.*?)(?=n\d+|$)/gs.


8. Important notes

Make sure the text property in the incoming data is correctly named. If it comes from a Manual Trigger with a text field, the above code works. · If the text is very large, the regex might be slower, but it’s fine for typical TTS use cases. · The Code node runs once and creates all items; the loop then processes each item sequentially. If you need parallel processing, you could use Split In Batches with batch size >1, but ElevenLabs may have rate limits.

Hope this helps!

2 Likes

You can do a recursive text split

Use code node to implement it

const CHUNK_SIZE = 1900; // Your block size
const SEPARATORS = [‘\n\n’, ‘\n’, '. ', ’ '];

const inputText = $input.first().json.output || ‘’; //Your text

function splitText(text, separators, chunkSize) {
if (text.length <= chunkSize) return [text];
const results = ;
let remaining = text;
while (remaining.length > chunkSize) {
let splitAt = -1;
for (const sep of separators) {
const idx = remaining.lastIndexOf(sep, chunkSize);
if (idx > 0) { splitAt = idx + sep.length; break; }
}
if (splitAt <= 0) splitAt = chunkSize;
results.push(remaining.slice(0, splitAt));
remaining = remaining.slice(splitAt);
}
if (remaining.length > 0) results.push(remaining);
return results;
}

const chunks = splitText(inputText, SEPARATORS, CHUNK_SIZE);
return chunks.map((chunk, index) => ({
json: {
chunkIndex: index + 1,
totalChunks: chunks.length,
text: chunk.trim(),
firstBlock: index === 0
}
}));

Modify your code accordingly

The approach in post #2 is solid but there’s a way to simplify — you can skip the regex and just use the split in batches node directly if you’re splitting on newlines or specific delimiters. that’s what we use for long content when sending to elevenlabs, way less code to maintain. also one heads up, elevenlabs has pretty strict rate limiting so batching with maybe 2-3 second delays between calls helps avoid hitting it.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.