YouTube Script Generator with n8n
Automate YouTube shoutout scripts using n8n, DeepSeek, and Todoist.
Introduction
30 Second Summary
If you run a YouTube channel, you know the drill. You want to shout out your subscribers by name, but writing a personalized script every single time eats into your recording schedule.
In this project, you will build an automated workflow in n8n that pulls subscriber names from Todoist, generates a personalized shoutout script using DeepSeek AI, and loops until the script fits a strict 195-word limit.
Tools
- n8n
- Todoist
- DeepSeek
- Docker
What You'll Build
You trigger the workflow with one click, walk away, and come back to a polished 195-word shoutout script sitting in your Todoist project, ready to read on camera.
By the end of this project, you'll have:
- A one-click workflow that fetches today's video task and subscriber names from Todoist automatically.
- An AI Agent powered by DeepSeek V4 Flash that writes a personalized shoutout script mentioning each subscriber by name.
- A word-count enforcement loop that automatically shortens the script until it fits 195 words or fewer.
- Secret Mission: Add a retry limit so the shortening loop exits gracefully if DeepSeek cannot trim below 195 words within a set number of attempts.
Are there any prerequisites?
This project assumes you already have n8n running self-hosted via Docker, a Todoist account with a project containing tasks and comments, and a DeepSeek API account with an API key.
You should also be familiar with n8n basics like adding nodes, making connections, and executing workflows.
Before We Start
Before we dive in, let's lock in what you're about to build and why it matters for your YouTube workflow.
This is your moment to commit to the goal before any hands-on configuration begins.
Set Up Credentials and Create the Workflow Canvas
Your workflow talks to two external services: Todoist for pulling task data, and DeepSeek for generating scripts with AI.
Before any node can reach these services, n8n needs valid credentials stored for each one. In this step, you will configure both sets of credentials and set up a fresh workflow canvas with a Manual Trigger node as the entry point.
In this step, get ready to:
- Configure your Todoist API credential in n8n.
- Configure your DeepSeek API credential in n8n.
- Create a new workflow with a Manual Trigger node.
Configure your Todoist credential
Todoist stores your subscriber names as task comments. For n8n to read those comments, it needs an API key that proves it has permission to access your Todoist data.
- Open your browser and navigate to localhost:5678 to access your n8n instance.
- Sign in if prompted.
- Click the Create button in the upper-left corner of the side menu.
- Select Credential.
- Search for and select Todoist from the list of services.
n8n opens the credential modal with an API Key field.
- In a new browser tab, open Todoist and go to Settings.
- Select Integrations, then open the Developer tab.
- Copy your API token from that page.
- Switch back to n8n and paste your Todoist API token into the API Key field.
- Click Save.
When you save, n8n automatically tests the credential to confirm it can connect to Todoist. You should see a success confirmation.
What does the save do?
n8n sends a test request to Todoist using your API key. If the key is valid, you will see a success confirmation indicating the connection works.
Your key is encrypted and stored inside n8n's database, so you only need to set this up once.
🙋♀️ Credential test not succeeding?
Make sure you copied the full API token from the Developer tab, not a partial string. The token is a long alphanumeric value.
Check that your n8n Docker container has internet access. If you are behind a corporate firewall, Todoist's API may be blocked.
Help me troubleshoot this
Configure your DeepSeek credential
DeepSeek provides the AI model that writes and edits your shoutout scripts. n8n needs a separate API key to authenticate with DeepSeek's endpoint.
- In n8n, click the Create button again in the upper-left corner.
- Select Credential.
- Search for and select DeepSeek from the list.
n8n opens the credential modal with an API Key field.
- In a new browser tab, go to platform.deepseek.com and navigate to the API keys page.
- Copy your DeepSeek API key.
- Switch back to n8n and paste the key into the API Key field.
- Click Save.
n8n tests the connection on save. You should see a success confirmation, just like with Todoist.
DeepSeek credential failing?
Confirm your DeepSeek account has a positive API credit balance. A zero balance causes authentication to fail even with a valid key.
Double-check you copied the key from the API keys page on platform.deepseek.com, not from a different settings section.
Help me troubleshoot this
Create the workflow canvas with a Manual Trigger
With both credentials ready, you need a workflow canvas where you will build the entire automation. The first node on any manually-triggered workflow is a Manual Trigger.
- In n8n, click Create in the upper-left corner and select Workflow.
- n8n opens a blank canvas. Click Add first step.
- Search for Manual Trigger and select it.
- Close the node details panel by clicking the X or clicking the canvas background.
You now have a workflow canvas with a single Manual Trigger node. This is the entry point you will click later to run the entire automation.
Why a Manual Trigger?
A Manual Trigger lets you execute the workflow on demand by clicking a button. This is ideal for testing and for workflows you want to run at a specific moment rather than on a schedule.
Before you move on, do you think both credentials will still show a successful connection if you re-open them?
- Verify your Todoist credential: click Create then Credential, search for Todoist, and open your saved credential. Confirm it shows a success state.
- Verify your DeepSeek credential the same way: open it and confirm the success state.
- Return to your workflow canvas and confirm the Manual Trigger node is visible.
Both credentials should confirm a successful connection, and your canvas should show the Manual Trigger node as the only element.
Your environment is wired up and ready to go. Next up, you will pull today's video task and subscriber names from Todoist.
Pull Today's Task and Subscriber Names from Todoist
In the previous step, you connected n8n to both Todoist and DeepSeek and placed a Manual Trigger on the canvas.
Now you need data for the AI to work with. Your script requires two inputs: the video topic (from today's task in Todoist) and the subscriber names to shout out (stored as comments on that task). Without both pieces of information, the AI Agent has nothing to write about.
In this step, get ready to:
- Fetch today's task from your Todoist project.
- Retrieve comments on that task containing subscriber names.
- Format subscriber names into a clean list for the AI Agent.
Add a Todoist node to fetch today's task
The built-in Todoist node in n8n supports a Get All operation for tasks. You can filter results by project and due date to isolate only today's task.
- Click the + button to the right of the Manual Trigger node to add a new node.
- Search for Todoist and select the Todoist node.
- In the Resource dropdown, select Task.
- In the Operation dropdown, select Get All.
- Select your Todoist credential from the Credential to connect with dropdown.
- In the Filters section, set the Project field to your YouTube project (the one containing your video tasks).
- Add a filter for today's due date so n8n only returns the task due today.
- Make sure the Todoist node is connected to the Manual Trigger node.
What does this node do?
The Todoist node calls the Todoist API using your credentials and retrieves all tasks matching your project and due-date filter. The output includes the task's content (your video topic) and its ID, which you need to fetch the comments in the next node.
- Click Test step to execute only this node.
- In the output panel on the right, confirm you see your task for today with its content and ID.
No tasks returned?
Make sure you have a task in your Todoist project with today's date as the due date. If the filter returns nothing, double-check that you selected the correct project and that the due date filter is set to today.
help me troubleshoot why my Todoist node returns no tasks
Add an HTTP Request node to fetch task comments
The built-in Todoist node only supports task operations (Create, Get, Get All, Update, Delete, Close, Reopen). It does not have a Comments operation. To fetch comments, you need an HTTP Request node with Todoist's predefined credentials.
- Click the + button to the right of your Todoist node to add a new node.
- Search for HTTP Request and select the HTTP Request node.
- In the Authentication dropdown, select Predefined Credential Type.
- In the Credential Type dropdown, select Todoist.
- In Credential for Todoist, select the Todoist credential you configured in Step 1.
- Set the Method to GET.
- In the URL field, enter the Todoist comments endpoint with the task ID from the previous node's output:
https://api.todoist.com/api/v1/comments?task_id={{ $json.id }}
What does this URL do?
This calls the Todoist REST API /comments endpoint filtered by task_id. The expression {{ $json.id }} dynamically inserts the task ID from the previous Todoist node's output. The predefined credential handles authentication automatically.
- Click Test step to execute only this HTTP Request node.
- In the output panel, confirm you see an array of comment objects. Each comment has a content field containing a subscriber name.
Seeing a 400 or empty response?
Check that the URL expression {{ $json.id }} resolves to a valid task ID. Click on the expression editor and verify the value. Also confirm you have at least one comment on today's task in Todoist containing a subscriber name.
help me debug my HTTP Request node calling the Todoist comments API
Add a Code node to format subscriber names
The comments come back as an array of objects, each with a content field. You need to extract just the names and combine them into a clean, comma-separated list that the AI Agent can use in the script.
- Click the + button to the right of the HTTP Request node to add a new node.
- Search for Code and select the Code node.
- Set the Language to JavaScript.
- Replace the default code with the following:
// Extract subscriber names from Todoist comments
const comments = $input.all();
// Pull the content field from each comment
const subscriberNames = comments.map(item => item.json.content);
// Join into a comma-separated list
const formattedNames = subscriberNames.join(', ');
return [{
json: {
subscriberList: formattedNames,
subscriberCount: subscriberNames.length
}
}];
What does this code do?
It loops through every comment returned by the HTTP Request node and extracts the content field (where each subscriber name lives). Then it joins all names into a single string separated by commas. The output also includes a count so you can see how many subscribers will be mentioned.
- Click Test step to execute the Code node.
- In the output panel, you should see a single item with a subscriberList field containing comma-separated names and a subscriberCount showing the total.
Seeing an empty subscriber list?
Make sure the HTTP Request node executed successfully before running the Code node. If comments exist but subscriberList is empty, check that your Todoist comments use the content field (not attachments or other fields) for subscriber names.
help me fix my Code node that outputs an empty subscriber list
Before you run the full workflow end-to-end, what do you think the output of the Code node should look like if you have three subscriber names in your Todoist comments?
- Click Execute Workflow (the play button at the bottom of the canvas) to run the entire chain from the Manual Trigger through to the Code node.
- Click on the Code node to inspect its output. You should see today's task content flowing through and a formatted subscriber list ready for the AI Agent.
You should see a JSON object with subscriberList containing names like "Alice, Bob, Charlie" and subscriberCount showing 3.
Your data pipeline is complete. You have today's video task and a clean list of subscriber names ready to feed into the AI Agent. Next up, you will build the AI Agent that turns these names into a personalized shoutout script.
Generate the Shoutout Script with an AI Agent
Your workflow now knows today's video topic and has a clean list of subscriber names ready to go.
Turning that data into a polished shoutout script requires more than a basic text generation call. The AI needs to reason about tone, weave each subscriber name naturally into the script, and then save the finished result to Todoist without you lifting a finger. That combination of reasoning plus action is exactly what an AI Agent does.
In this step, get ready to:
- Connect an AI Agent node with a DeepSeek Chat Model sub-node.
- Write a system prompt that generates energetic YouTube shoutout scripts.
- Attach a Todoist tool so the agent saves the script automatically.
Add the AI Agent node and connect DeepSeek
An AI Agent in n8n combines a language model with tools. The model handles reasoning and writing. The tools let it take real actions like creating tasks in external apps.
- On your workflow canvas, click the + button after the Code/Set node that formats your subscriber names.
- Search for AI Agent and add it to the canvas.
- Connect the output of the Code/Set node to the AI Agent's input.
The AI Agent node now appears on your canvas with connectors for a model and tools.
- Click the Model connector on the AI Agent node.
- Search for DeepSeek Chat Model and select it.
- In the Model dropdown, select deepseek-v4-flash.
- Under Credential to connect with, select the DeepSeek credential you configured in Step 1.
Why DeepSeek V4 Flash?
DeepSeek V4 Flash costs $0.14 per million input tokens and $0.28 per million output tokens. For a simple creative writing task like generating a shoutout script, the cheaper Flash model is the right fit. The more expensive Pro model's extra reasoning capabilities are unnecessary here.
You should see the DeepSeek Chat Model sub-node connected beneath the AI Agent node on your canvas.
Don't see the DeepSeek Chat Model option?
Make sure you're clicking the Model connector specifically, not the Tool connector. The model connector is where chat model sub-nodes appear.
If the node still doesn't show, confirm your n8n instance has the LangChain nodes enabled. Why can't I find the DeepSeek Chat Model node?
Write the system prompt and user message
The system prompt tells the AI what role it plays and how it should behave. The user message provides the specific data for this run.
- Open the AI Agent node by double-clicking it.
- In the Prompt section, select Define below.
- In the System Message field (found under Node options), enter your system prompt. It should include these elements:
- The agent's role: a YouTube script writer that creates energetic shoutout scripts.
- A requirement to mention every subscriber name provided.
- A target of around 195 words.
- An instruction to keep the tone high-energy and conversational.
- An instruction to use the Save Transcript tool to save the final script as a new Todoist task when done.
- In the Prompt (User Message) field, use expressions to pass in today's task content and your formatted subscriber list from the previous nodes. Reference the data using n8n expressions like {{ $json.taskContent }} and {{ $json.subscribers }} (adjust the field names to match your Code/Set node's output).
What does the system prompt do?
The system prompt acts as a standing instruction that shapes every response from the agent. By specifying the energetic tone, subscriber name inclusion, and word count target, you give DeepSeek clear guardrails. The user message then provides the unique data for each execution.
The word count target of 195 words is intentionally tight. The AI will often overshoot on the first attempt. That's expected, and the next step adds a loop to enforce it.
Attach the Todoist tool and run the workflow
The AI Agent requires at least one tool sub-node. You'll give it a Todoist tool so it can save the finished script directly.
- Click the Tools connector on the AI Agent node.
- Search for Todoist and add the Todoist node as a tool.
- Set the operation to Create a task.
- Select your Todoist project from the Project dropdown.
- For the task content field, let the AI define this parameter (the agent will fill it with the generated script).
- Rename this tool node to Save Transcript by clicking the node name on the canvas so the agent knows when to call it.
Why use a Todoist tool instead of a separate node?
When the Todoist node is attached as a tool, the AI Agent decides when to call it based on your system prompt instructions. This means the agent can reason about the script, finalize it, and then save it in one autonomous step. A separate node after the agent would just pass through whatever the agent outputs without the agent controlling when or what gets saved.
You should now see the AI Agent node on your canvas with two sub-nodes connected: the DeepSeek Chat Model beneath it and the Save Transcript Todoist tool to its right.
Before you run the workflow, what do you think the script's word count will be? Will it hit exactly 195 words on the first try?
- Click Test Workflow to execute the entire workflow from the Manual Trigger through the AI Agent.
- Click the AI Agent node to open its output panel and read the generated script.
You should see a shoutout script that mentions each subscriber name from your Todoist comments. Count the words or note the length. It likely exceeds 195 words.
Why does the script exceed 195 words?
The AI was asked to aim for 195 words, but language models are notoriously imprecise at self-counting tokens and words. They tend to overshoot, especially when asked to incorporate a list of names. This is the gap the next step closes with an automated shortening loop.
🙋♀️ Agent failing or showing no output?
Check that your DeepSeek credential is valid by opening it in Credentials and testing the connection again.
Confirm the AI Agent has both the DeepSeek Chat Model and at least one tool (Save Transcript) connected. The agent will not execute without a tool sub-node attached.
If the user message expressions show empty values, verify that the previous Todoist and Code/Set nodes executed successfully and produced output. Why is my AI Agent not producing output?
Your AI Agent writes a solid shoutout script, but it overshoots the word limit. In the next step, you'll build a loop that automatically shortens the script until it fits within 195 words.
Build the Word Count Enforcement Loop
Your AI Agent generates a shoutout script, but there is no guarantee it stays under 195 words. Without enforcement, you would need to manually trim every script before recording.
In this step, you will build an automated editing loop. An IF node checks the word count, and if the script is too long, a second DeepSeek call shortens it before looping back for another check.
In this step, get ready to:
- Add an IF node that counts words in the script and branches based on whether the count exceeds 195.
- Build a Script Shortener node on the true branch that trims the script while preserving subscriber names.
- Connect the false branch to a Todoist node that saves the approved script.
Add the IF node to check word count
The IF node splits workflow execution into two branches based on a condition you define. You will use an expression that splits the script text by spaces and checks whether the resulting array length is greater than 195.
- On your n8n canvas, click the + button on the output connector of your AI Agent node.
- Search for IF and select it to add the node to your workflow.
- Open the IF node by double-clicking it.
- Click Add Condition and select the Number data type.
- In the left value field, click the Expression tab to open the expression editor.
You need an expression that counts the words in the AI Agent's output. First, check what field name your AI Agent uses.
- Look at the input panel on the left side of the IF node. Find the field that contains your generated script text (it appears in the JSON view of the incoming data from the AI Agent).
- In the expression editor, enter an expression that splits that field by spaces and returns the array length. The pattern is:
{{ $json.output.split(' ').length }}
What does this expression do?
The {{ }} delimiters tell n8n this is an expression.
The $json.output part references the script text from the AI Agent's output. The .split(' ') method breaks the string into an array of words using spaces as separators. The .length property returns how many elements are in that array, giving you the word count.
💡 Field name may differ
If the incoming data uses a different field name (check the input panel JSON view), replace output with the actual field name you see. The expression editor shows a preview of the resolved value so you can confirm it returns a number.
- Set the comparison operator to is greater than.
- In the right value field, enter 195.
Your IF node now routes scripts with more than 195 words to the true branch, and scripts at or under 195 words to the false branch.
- Close the IF node and check that it appears connected to your AI Agent node on the canvas.
Expression showing an error?
Make sure the expression starts with {{ and ends with }}. A trailing period or missing closing braces will cause a syntax error.
If the preview shows undefined, the field name does not match your AI Agent's output. Open the AI Agent node, execute it once, and check the output JSON to find the correct field name.
Help me fix my IF node expression in n8n
Build the Script Shortener on the true branch
When the word count exceeds 195, the workflow needs to shorten the script automatically. You will add a DeepSeek Chat Model node that rewrites the script to be shorter while keeping every subscriber name and the energetic tone intact.
- Click the + button on the true (top) output of the IF node.
- Search for DeepSeek Chat Model and add it to your workflow.
- Open the new node and select deepseek-v4-flash from the model dropdown.
- Set the prompt to Define below.
- In the prompt field, write an instruction telling DeepSeek to shorten the script to under 195 words while preserving all subscriber names and the energetic tone. Reference the incoming script text using an expression so the model receives the current version.
What should the shortener prompt include?
A good shortener prompt has three constraints: a word limit (under 195 words), a preservation rule (keep all subscriber names exactly as they appear), and a tone instruction (maintain the energetic, shoutout style). Including all three prevents the model from cutting names or flattening the energy.
Now you need to loop the shortener's output back to the IF node so the word count is checked again.
- Drag a connection from the output of the Script Shortener node back to the input of the IF node.
- Confirm the loop is visible on the canvas: IF (true) goes to Script Shortener, and Script Shortener loops back to IF.
Why loop back instead of saving immediately?
The shortener might still produce a script over 195 words on its first pass, especially with many subscriber names. Looping back to the IF node guarantees the word count check runs again. The loop only exits once the script passes the 195-word threshold.
🙋♀️ Can't connect back to the IF node?
In n8n, drag from the output dot of the Script Shortener node to the input dot on the left side of the IF node. A grey line should appear between them. If the canvas is crowded, zoom out or rearrange your nodes so both are visible at the same time.
Help me create a loop in my n8n workflow
Save the approved script on the false branch
When the script is 195 words or fewer, it is ready to be saved. You will add a Todoist node on the false branch that creates a task with the final script as its content.
- Click the + button on the false (bottom) output of the IF node.
- Search for Todoist and add the node.
- Open the Todoist node and set the operation to Create a task.
- Select your Todoist project from the Project dropdown.
- In the Content field, switch to Expression mode and reference the script text from the incoming data so the approved script becomes the task content.
What does this Todoist node do?
This node is the exit point of your workflow. It takes the final script (which has passed the 195-word check) and saves it as a new task in your Todoist project. You can open Todoist after execution to find the polished script ready for your recording session.
Before you run the full workflow, think about what you expect to happen. If the AI Agent produced a 230-word script, how many times do you think the loop will run before the script passes the check?
- Click Test Workflow (or click the Manual Trigger node and select Execute Workflow) to run the entire workflow from the trigger.
- Watch the execution log. If the initial script exceeded 195 words, you will see the IF node and Script Shortener node execute one or more times as the loop runs.
- Once the loop exits (word count is at or below 195), the Todoist node on the false branch executes and saves the final script.
Open your Todoist project. You should see a new task whose content is a shoutout script of 195 words or fewer.
Loop running but never exiting?
If the loop keeps running without stopping, open the Script Shortener node and check that your prompt explicitly says "under 195 words". A vague instruction like "make it shorter" may not cut enough words each pass.
Also confirm the IF node's expression references the Script Shortener's output (not the original AI Agent output). The expression should use $json which automatically picks up whichever node last fed data into the IF node.
Help me debug my word count loop in n8n
Your workflow now enforces a strict 195-word limit automatically. Next up, you will take on the Secret Mission and add a retry limit so the loop cannot run forever.
Secret mission
Add a Retry Limit to the Loop
Your shortening loop works, but what happens if DeepSeek just cannot trim the script below 195 words? Right now, the loop runs forever. Add a retry limit that exits gracefully after 3 attempts, saving whatever version it has.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs on a self-hosted n8n instance, so there are no ongoing cloud costs when the workflow is inactive. DeepSeek charges only per execution (approximately $0.01 per run).
Resources you used:
- n8n workflow (persists in your Docker volume).
- Todoist credentials stored in n8n.
- DeepSeek credentials stored in n8n.
- Test tasks created in your Todoist project.
- DeepSeek API key (at platform.deepseek.com).
Keep everything running
No action needed. Choose this if you plan to use the workflow regularly for your YouTube channel.
- Your workflow stays in n8n, ready to trigger whenever you want to generate a script.
- Credentials remain configured so no setup is needed next time.
- Each execution costs approximately $0.01 via the DeepSeek API. No cost accrues when the workflow is idle.
Pause - I'll come back to this later
Deactivate the workflow so it cannot be accidentally triggered. Your configuration and credentials remain intact for when you return.
- In n8n, open the workflow and toggle the Active switch to off.
- No costs accrue while the workflow is inactive.
- Delete any test tasks from your Todoist project if you do not want them cluttering your task list.
Delete - I don't want to use this again
Remove all project resources and revoke access. Follow each step below to clean up completely.
- Delete the workflow: In n8n, go to Workflows. Select your YouTube Script Generator workflow, click the three-dot menu, and choose Delete.
- Delete credentials in n8n: Go to Credentials. Open your Todoist credential, click Delete. Repeat for your DeepSeek credential.
- Delete test tasks in Todoist: Open your Todoist project and delete any tasks that were created during testing (both the input tasks and the generated script tasks).
- Revoke your DeepSeek API key: Go to platform.deepseek.com, navigate to API keys, and delete the key you used for this project.
Nice Work!
Nice Work!
You just built a fully automated YouTube script generator that pulls subscriber names from Todoist, writes a personalized shoutout script with DeepSeek V4 Flash, and trims it to exactly 195 words or fewer. One click, and your script is ready to record.
Here's what you learned:
- Built a chain of Todoist nodes that pull today's video task and extract subscriber names from comments.
- Configured an AI Agent with DeepSeek V4 Flash that generates personalized YouTube shoutout scripts.
- Implemented a word-count enforcement loop that iteratively shortens scripts to stay under 195 words.
- Connected the final output back to Todoist so the polished script is ready when you record.
- Secret Mission: Added a retry limit that prevents the shortening loop from running indefinitely.
Ready to quiz yourself?