*LIVE BUILD* Personalized Outreach AI Agent in n8n (No Code)

In this live‑build tutorial Nate Hurk constructs a no‑code AI agent in n8n that automatically qualifies leads from a Google Sheet and generates personalized outreach messages. The workflow begins with a Google Form feeding lead data into a Sheet, then a "Lead Call" tool workflow reads the rows, sends the relevant fields (name, company size, decision‑maker flag) to an OpenAI GPT‑4 model with a system prompt that returns a JSON object indicating qualification status and reasoning. The JSON is parsed, merged back with the original row, and the rating and reasoning columns are updated in the Sheet. A second workflow, the "Personal Message" tool, pulls qualified leads, prompts GPT‑4 (with a detailed system prompt) to produce a preferred contact method, best contact time, and a customized email script, then writes the outreach text back to the Sheet. Both tools expose a "response" field set to "done" so the agent knows the task completed. Finally, a top‑level "Demo Agent" workflow is built: it uses a chat trigger, a tools‑agent with window‑buffer memory, and two "Call n8n Workflow" nodes that invoke the lead‑qualification and message‑generation tools based on user prompts. The demo shows the agent qualifying leads, generating messages, and handling errors via n8n’s execution logs. Throughout, Nate demonstrates credential setup for Google and OpenAI, node configuration (Get Rows, Update Row, Merge, Edit Fields, JSON.parse), prompt design, and troubleshooting tips, emphasizing how quickly a functional AI‑driven outreach system can be assembled without code.
Chapters
Okay, so today I'm gonna be doing a live build of an AI agent. This agent is going to qualify leads and going to generate a personal message for each lead. So don't wanna waste any more time. Let's just get straight into building this one. The first thing that you gotta do is have a lead database set up somewhere. So for today, we'll be using Google Sheets. We've got 2 leads here for simplicity's sake and information about each lead. And this data's coming in from a Google form. Your, your potential leads would fill out this form, and then you have to make sure that it's linked to a sheet. That way it'll pop in here automatically, and then your agent can qualify them. So one thing to note is this form ends with this column right here, anything else we should know. And then before you hop into building this agent, you want to add a column called rating, a column called reasoning, and then a column called outreach. This is just so in N8N it knows to populate these three columns with the information. So if that doesn't make sense right now, don't worry. As we get into building it, you'll see exactly what I mean. So back over to N8N, this first workflow that we're going to be building is a lead call tool. So this is going to be the tool that the agent calls in order to qualify leads. So that is going to be a trigger of when called by another workflow. So the agent will call this tool in order to start the process of moving it through this logic. Second thing that we need to do here is grab a Google Sheets node. As you can see, there's 10 actions within this Google Sheets, and we're going to do Get Rows in Sheet. Now you need to set up your credentials for this node, basically just telling N8N that it has permission to access information in your Google Sheets. So if you click on Docs right here, it'll bring you to this page by N8N, and it will pretty much walk you step by step how to get this set up with your credentials. It's super simple. Um, you're basically just going to sign in and you might have to set up your OAuth consent screen, but like I said, that document will have all the information you need. So we're going to do a sheet within a document and we're going to get rows, and then we're going to choose the document we want. That's going to be Let's Work Together Responses. And then the sheet— there's only going to be one sheet in here, so it'll be Form Responses 1. Then you can go ahead and click test step. This is how we make sure that the information is actually reading into N8N. So as you can see, we've got our information about John and about David right here. So it populated in well. Now let's move on to the next step. So we're going to add another node. This one's going to be OpenAI. A ton of different actions you could take. Once again, we are going to do message a model. You're going to have to set up this credential here, so I'll show you guys exactly how. You do this one, you're going to click create new credential, and you're going to have to grab an API key. So over in OpenAI, you're going to go on the left-hand side, find API keys, and then you're just going to create a new key, name it whatever you want. And then once you do that, it'll give you this value to copy. Copy that right there, and then I'm just going to paste that into N8N, hit save, and you should be good to go there. Connection tested successfully. Okay, now you have to set up this node. So we're going to do text, message model, and then choose our model of GPT. I'm going to scroll down and choose 4.0. Okay, and now we need to prompt this node what to do. So this first message box here, we're going to change this to a system prompt because we are telling the node what it needs to do. And so I'm going to copy and paste in this information right here. So you guys don't have to see me type. So we're saying your task is to qualify incoming leads. Leads are form submissions to a closed community group. Use the following criteria. The first one is they need to be a decision maker who runs the company or at least has influence in the decision-making process. And then the second criteria is we currently only want to work with companies with around 45 or less employees, also known as company size, which is how it comes over right over here, as you can see. So if a lead is qualified, it will reply with qualified. Otherwise, it's going to say not qualified. Super simple. And then we just wanted to specify the format of JSON to go to put the output into. So you guys can just copy and paste this exactly right here. I'll throw this in the description so it's easier, but that's just how we want the output to be formatted so that we can easily move it into the next node and put it back into Google Sheets. So we're done with this one. Now we're going to add another message. This one is going to be a user message, and this is just the information that we want this OpenAI node to be using to qualify a lead or not. So we've got name, company size, and decision maker. And what we're going to do is grab in this information from Google Sheets. So on this left-hand side, for name, we're going to drag in full name. That jumped weird, but we want it right there. Name: full name. And then down here you can see how it's coming in. So name: John Richards. Same thing with company size, we'll put that right here. Company size: 15. And then last but not least, decision maker, we'll grab that one from here, and it comes in as yes, I am the primary decision maker in the result tab. So that's all we need to do for this node. You can once again hit test step. And we'll see how the data is coming in over here on the right-hand side. So the first one is coming in as qualified and the second one is coming in as not qualified. This first one has the reasoning of the lead is a primary decision maker. The company size is within the threshold, and this one says the company size is 100, which exceeds the limit of 45 employees. So these two nodes are working. That's awesome. Now we're gonna add another one onto this OpenAI node. What we want to do here is grab a data transformation and we're going to do edit fields. We're going to leave this one as manual mapping and then we're going to click here to add a field. This one, we're just going to name this field reply. We want to change this to an object. And then for the value, we just want to grab the content, basically the OpenAI node rated if it's qualified or not, and we just want to grab that response. So we're going to put that into the value here. And then one last step, we want to put in front of the dollar sign, we're going to go JSON.parse, open parentheses, and then behind content, we're going to close the parentheses. Oops. Close the parentheses and it should go green. That's how you know it worked. And then you can see the result. It should say object colon and then exactly what came out of the OpenAI node. So test that step. Make sure it's working. It should come out as a really clean 2 different fields here, qualified and reasoning. So it looks like that did its job perfectly. Okay, next step here is we need to add this information that we just got, the qualification status, back to the original data. So if we grab here, pull over, and now we want to add a merge node. This merge node is just going to combine the data, but we don't want to append it, we want to combine. And we're going to combine just by position. So that's just saying the first row of data from the Google Sheets is going to match with the first row from the OpenAI node and just keep matching it down. Um, and then you got to make sure that we drag in this right here to the merge node, and then we'll go in here and test this step. As you can see, we've got the original data from the Google Sheet Scroll all the way over, we should have our qualification status. So qualified, not qualified. Okay, so we're almost done with this tool already. Now we need to add another Sheets node so that this information actually goes back into Google Sheets. So we're going to choose Update Row. Same thing, got to set up your credential, and then we leave all this blank, or do you default. Choose the document once again, choose the sheet once again, and now it's going to fetch the columns and we're going to match the columns on timestamp. So it's going to match up the correct rows in your database and make sure that everything is sort of synced up. And now we have to update the values. So which, which fields in our database do we actually want to change? So timestamp is— we're using that to match, so we're going to drag in timestamp. And the only thing we want to change here are those last two columns right here, rating and reasoning. So you can go ahead and just delete everything else out of here just to keep everything nice and clean. So for rating, down here from the reply node, we are going to grab in qualified. It will come through as a result of qualified or not. And then for reasoning, same thing, we want to drag in reasoning so that we can see why a lead was either qualified or not qualified. Should be good to go with this node. We'll hit test step and we will see that it populated in here real quick. We'll pop over to Google Sheets and we can see if it actually worked. So yep, John got qualified and David is not qualified with their respective reasonings right here. So now we're going to move into the next— oh wait, nope, not yet. One more thing we have to do is we have to add another @EditFields, and once again we'll leave it as manual mapping. We're going to add a field, this one's going to be called response, leave it as a string, and then just say done for the value. So the reason we have to do that is because Like I said, we'll tell the agent to qualify leads. It's going to think, how do I actually qualify leads? It's going to send us off to this tool. The data is going to start moving through this logic. It'll come here, it'll come here, it'll parse through all this. And then once we hit here and the information's actually updated in our Google Sheet, the agent needs to know that it's done so that it can tell whoever prompted it, hey, we did that for you. So this node sets the field of response, which goes back to the agent, as done. It's really simple. No need to overcomplicate it. This is just how the agent knows that this tool has been executed. Okay, so we got that saved. We're going to go back and now we're going to make the, um, the personal message tool. So add new workflow. We're going to call this one Personal message tool. As you can see, this means tool basically. At least that's how I assign, assign tools and agents. Same thing with the trigger. We're going to do when called by workflow, add a Google Sheets node, and we're going to get rows. So this, um, this workflow is going to be very similar to that last one, which is super nice because it's pretty much we're getting, we're We're getting the information from the database. We're doing something to get some sort of answer to put back onto the row, and then we're actually putting it back onto the row. So these two workflows are gonna be very similar. We gotta grab the document once again. Test step. And we should see actually the rating coming back. So we've got qualified and not qualified here. Same thing. OpenAI node. Message model. Set that up with the key we just made. And then we're going to grab a connection. Okay, we should be good. I don't know what's going on here. We're going to grab 400 once again. And okay, now we need to system prompt this OpenAI node. So I'm going to copy and paste this in here again so that you guys don't have to see it. But here's what I said. Your objective is to write a personalized message to each of the leads, output the lead's preferred method of contact and when is the best time to contact them. Then provide a script that is personalized based on their company, job title, and what they're looking to automate. If the lead is qualified, then provide a message. Otherwise, don't. And then at the end, I wanted to add these messages should be sent from Nate Hurk. The company is 12345 Corp and his email is natehurk@ This message shouldn't include any variables like your name or company name. Use the information I provided. So I had to add this in here because when I was playing around with this agent, it would put the message out with, you know, hey John, this is your name, contacting you from company name. And we don't want it to be like that in case, you know, that just takes out or that makes you have to do a lot more manual work. So we just wanted to get rid of that process. Okay, so that is the system prompt. Now we need to once again add a new message. This is going to be a user prompt. And same thing as that last OpenAI node, we're just going to be giving this node the information that it needs. So it wants to qualify, or it wants to send messages based on the name, the job title, what they're looking to automate, and if they're qualified or not. So again, we're just going to drag in the information. I don't know why it always does that the first time, but we've got name. John Richards, job title, he is the owner. What is he looking to automate? He wants to automate customer support and sales. And then rating, we'll drag in over here if he is qualified or not. So let's test this step and see what we get. Okay, so this first row is for John. it outputted this message. I won't read this all right now, we can read it later, but it outputted the message because he's qualified. And then the second, um, lead over here, the lead is not qualified, therefore no output is required. So that step is working correctly. So now we need to once again grab Data Transformation and Edit Fields. We're going to Manual Map, Add a Field, same thing, Reply. Um, I think actually we can leave this one as a string. Yeah, we can leave this one as a string. And for the value, we want to grab this information that's coming from the previous node. So preferred method of contact, email, best time to contact, morning, and then the message below it. We'll test the step and it came through nice. And now once again, we need to combine this new message with the original data set. With the lead information. So drag this over here. We're gonna grab a merge. We're gonna combine based on position. That's not gonna work because we didn't drag the other input in. So now we'll go in here and test this step. Oops. Okay, we should see— we got 2 records here. And then at the end, we've got the messages back associated with each record. So next, once again, got to add a Google Sheets node to push this new information back into Sheets. So that's going to be updating a row in the sheet. We will set this up once again, hopefully not too repetitive. Um, So we're gonna match again on timestamp, so we'll drag that in. And then we only want to update the message, so we're gonna get rid of everything else here except for Outreach. That's the column where the message is gonna go, and we just grab the reply, throw it right in there, and it comes through with the information we're looking for. So test this step. Go into here, and as you can see now in Google Sheets, we've got the outreach message for these two leads. Leads not qualified, so he got nothing. This guy got a message. And then can't forget, of course, we need to add the final set node. So you can type in set, edit fields, whatever you want to call it. Manual mapping, add a field. The field is called response. Leave it as a string, and the value is going to be done. So we will save this, and now we have the two workflows that we need. We're going to go back into our project, add a new workflow, and of course it is time to build the agent. So this one's called Demo Agent, and we need to add the trigger. So you can trigger it manually. All these type of things. We were doing when called by another workflow, but this time we're gonna do on chat message because the whole point is that we can ask the agent to do something and it will do it. So we've got this trigger here. To add an agent, you can either type in agent, oops, that's not how I type agent, agent, or you can just go to Advanced AI, AI Agent. It's gonna be a tools agent. There's a couple different options. Conversational is good for like customer support. but we want to do tools because it's going to be accessing different tools to do different jobs. So we've got this, and then we're going to add a system message. This is just prompting the AI agent what to do. I don't want to get too much into prompting right now. Let's just leave this as a helpful assistant because this workflow is not too complicated. But yeah, just leave that like that for now. Chat model, I always use OpenAI. With the model of 4o. That's all we need. For memory, we're going to do window buffer memory. So if you guys don't know what this node does, it basically is just going to give the agent context of our conversation. So if you ask it to do something and then it's going to respond, and then you can ask it to do something and you may reference what just happened, the agent will be able to remember 5 chats basically. That's the context that it'll have to work off of. If you don't add this, it'll basically just be question and answer, reset, question, answer, reset. So it's super easy to just throw that in there. So pretty much I just always do that. Okay, so this is where the magic happens. We're going to add the two workflows that we just built. We're going to use this node right here, Call N8N Workflow Tool, to do that. So this first one that we're going to do is the lead call. And we'll just call this lead call up here too, just to keep everything organized. And now you have to give this note a description of when to use this tool. So super simple, call this tool to qualify leads in the database. So where is the workflow that we're calling here? You can do by ID, by, or from list. It's really nice that they let you choose just from a list here. And we want to do the Lead Qual tool. So set that up. And then this is the response field. If you remember, at the end of the tools, we set up that set field and we made the response field done. So that's what it sees. That's how it knows it's done. So there's Lead Qual. Now we're gonna do this same thing again. This one is going to be the Let's call it message. I'm gonna put that in here as well. And then same thing, call this tool to generate personalized messages for leads. And I'm actually just gonna get rid of personalized, that way it's, it's a little easier when we ask the agent, can you make messages for the leads? We don't always have to say, can you make personalized, just to keep it easier. So Same thing, from list, we're grabbing the personal message tool and it's returning response. So, oops, let's go ahead and save this agent and let's get to testing it. So we're going to chat with it. We're going to say, oh, first we need to get rid of this information to make sure it's working. So we've got the two leads here with no information in the rating, reasoning, or outreach column. Let's see if it's working. So can you please qualify the leads in the database? So it had to talk to chat to figure that out. Now it's using the lead call tool. So that's working well. Back to the agent. It's going to go back to the model and it outputted to us all leads in the database have been qualified. How can I assist you further? So as you can see here, we've got the these two leads are qualified, not qualified, with their reasonings. Now we're going to go in here and say, yeah, of course, let's, um, can you please make messages for those leads? So it's going to talk to the model. Uh-oh, it's using the lead call tool. That's not what we want. We want it to use the message tool. There we go. Okay, so I think it was just making sure They're qualified. Back to the model, back to us. Messages have been successfully generated. How can I assist you further? Okay, perfect. So let's actually read this message now. So this guy's qualified, he got a message. Let's read this message. So they said— oh no, what did I just do? Okay, he said, um, preferred method of contact is email. Contact him in the morning. The subject is Transform Your Business Process with 12345 Corp. Hi John Richards, I hope this message finds you well. My name is Nate Hurk and I'm reaching out from 12345 Corp. Given your role as the owner and your interest in automating sales and support, I believe our services can significantly enhance your business operations. At 12345 Corp, we specialize in streamlining processes to improve efficiency Customer satisfaction. By automating customer support and sales, we can help you save time, reduce errors, ultimately increase your bottom line. I'd love to discuss how we can tailor our solutions. Are you available for a quick call later this week? I'm generally available in the mornings. Okay. So it was very personalized. It sounded like I actually went in here and wrote this myself. Obviously this message can get a lot better as you prompt it differently, as you give it information about your company and the services that you offer. So you can give it access to that through, you know, a database, a vector database, whatever it may be. Um, so this is just a super simple example. I think I built this in, you know, maybe 20 minutes. So you can definitely make them better and better. And as you add more leads, one thing that I wanted to point out real quick is with this workflow, this lead call tool, I think in an actual application you would want to set this up not as a call from an agent, you would probably want to set it up as a trigger based on Google Sheets. So if we did Sheets trigger down here, on row added. So if you added in this node, what this would do is every time someone submits a response to your form, it's going to pop into here as a new row, and then this workflow will run automatically because it's triggered by a new row. So you'd set up the logic exactly the same, you just put this right here, and then you could probably get rid of this set field, but you do the logic the exact same, and then it would automatically immediately qualify them or not qualify them. And you could do the exact same thing with the outreach message, but I just wanted to show you guys sort of how easy it is to build a tool and how easy it is to build an agent that can call these tools and just sort of open up your eyes to the capabilities of agents and what they can do. So yeah, um, I hope you guys enjoyed this live style. It is good to— and actually, I'll show you guys one more thing real quick. So when you're testing the agent, you know, obviously you hope to get no errors in the workflow, but if you do, you're going to go down to executions, and then you'll see all the previous runs. They'll be red if they errored. So let's say we got an error with the personal message tool. We click on View, and this always takes way too long to load. But once we get here, this is the run that would have just executed. So you can click and see exactly what's happening. So you can see maybe you didn't prompt this tool right and something's coming out weird, or you can see maybe you messed up the parsing and this is coming out as a, as a a weird object. The point is you can get in and find exactly where things are happening and go in and troubleshoot. So yeah, I think that's going to do it for this one. Please let me know what else you guys want to see, and if you sort of like these live builds or step-by-steps, let me know too. And yeah, that's all. So thanks, guys.










