How to Create an AI Email Agent with n8n (No Code, Step-by-Step Tutorial)

Build an AI email agent in n8n without coding. The workflow uses three pipelines: one pulls contacts from Google Docs into Pinecone, another sends emails via Gmail, and the main agent decides which tool to use. See a working example and how to debug execution logs.
Chapters
All right, so today I'm gonna be walking through step by step how to build a super simple email AI agent. If you know anything about agents, you know that they can get super complex as you give them access to more tools and expose them to different scenarios. So I just wanted to keep this first one super simple just to give everyone a good understanding of what agents are capable of and how you connect them to tools in order to do what you want them to do to automate workflows, basically. So let's get straight into this one. We just wanted to start off here with a quick demo of what the agent actually looks like and what it's going to do. We got the agent. Don't worry, a lot of this stuff probably won't make sense, but by the end of the video, it all will. We've got the tools it's going to use here, email, the Pinecone vector database, and then you can see all of the embeddings of a large language model in here. We're using OpenAI, and that is basically just how it's going to know what to make the email say, how to find the information, the contact information, that sort of stuff. So Let's go in here and say, send an email to Phil Dunphy asking him what's up. Hopefully this doesn't take too long to execute. Email has been sent to Phil Dunphy asking what's up. If you need anything else, feel free to ask. Perfect. All right, so let's just go in here. Hey Phil, just checking in to see what's up. Best, Nate. Super simple email, but just wanted to give you guys a quick demo of that. Okay, let's get into actually building this now. So the resources needed for this video: N8N, that is the software we're going to be using to build this agent. We got Pinecone, that's just a vector database tool where we'll be putting our contact information. We've got Google Docs, which is actually where we have our contact information. We'll be pushing it from Google Docs into the vector database. And then we've got OpenAI API. Obviously that is how we're going to use the large language model in this agent. And then 5 years of coding experience. Yeah, obviously that's a joke because that's kind of the whole point of this video and these low-code, no-code tools. So we're going to be building 3 separate workflows today. The first one is going to be to push contact data from Google Docs to the Pinecone vector store. And if you've never heard of a vector database right now, um, or if you've never heard of it before, don't worry about that right now. It's basically just where we're gonna be pushing the data so that the agent can pull it. There's a lot of resources on what vector databases actually are and why they're important for agents, but let's just keep it simple for now. Um, we're gonna be building the tool also in N8N. That's gonna be the send email tool. And then finally, the actual agent itself. And all three of these workflows are gonna be in N8N. Which is really awesome to keep everything together. So yeah, that's basically it. Let's just get straight into this. First, let me just show you what my contact data looks like. So these are all of my best friends pretty much. I've got their email addresses here, obviously fake email addresses besides this one is one of mine. So we're gonna be sending it to Phil Dunphy and that's how it knows to send it to this email address here. Then this is Pinecone. You wanna go in here, make an account. It's super, super cheap. It's actually— I don't even know if I paid for it yet. It's based on usage. So yeah, super cheap. You're going to basically just go into Pinecone here. You're going to create an index, can name it whatever you want. The only thing that really matters to set up here is right here, the configuration. You need to set it up by model 3 small. You're going to set that configuration and create that index. So I'm not going to make one because I've already got one, as you can see right here. It's called sample. And actually, let me just get rid of this data in here so I can show exactly how we're going to push this data in here. So, all right, back to any of them. So we're going to add workflow to project, and this first one is going to be the workflow that's going to push the data into Pinecone. So I'm just going to call this one Pinecone. Um, all right, so the first step is we need to add a trigger. As you can see, there's a lot of different options for triggering this workflow, but we are going to start off with trigger manually. We'll get into a few of these other ones later, but we're going to trigger manually, which basically just means that when we click test workflow, that's when the scenario is going to run. So we've got this trigger here, we're going to click on this plus to add a node. The node that we're going to grab here is Google Docs. So as you can see, there's tons of integrations in N8N. We're going to grab Google Docs, and then we have to choose a specific action within Google Doc. So what we're going to do here is, um, get a document. Okay, so here's something that I got really confused about when I was trying to learn about how to build agents and stuff, and that was being able to call all these different nodes. So Google Docs, OpenAPI, Google Drive, Gmail, Pinecone, pretty much all of those you have to call them through n8n. And it has to know that you have permission to access this information. So you have to set up these credentials, API keys, whatever they're called, whatever you want to call them. So you're going to go in here, you won't have this, you'll have to create a new credential. Kind of seems confusing. You need client ID, client secret, but if you click on open docs, it's super, super intuitive to just follow exactly what they say here. So you'll have the instructions here, just follow it step by step, but I'll kind of show you what you need to do here. You're going to go into Google Cloud Services. I think it's right here, Google Cloud account. Yeah, you're going to go in here, make an account, set up a project, and then once you're in that project, you need to find what you need to enable. So You've got like Drive, Gmail, and Docs is pretty much what I have here. So like, let's say for Google Docs, I search it, the Google Docs API, and then all you have to do really is just enable it right here. There'll be a button maybe here that says enable. So you'll enable it, and then you will need to go down to credentials. You're going to create credentials, OAuth client ID. And then it'll be right here. Basically, it'll have your client ID and your secret. I'm not going to open mine up because it'll expose me, but that's all you need to do pretty much. And then you're going to put those into here— ID, secret— copy and paste. Then you need to set up OAuth 2.0. Going to be in the same exact place— OAuth consent screen. Pretty much just giving permission. What I did was I added my email here as a test user so it knows that I have permission or that n8n has permission to access my Google Docs, my Gmail, anything like that. You could also just publish the app, but if you're running into issues on n8n where it's saying that your account is blocked or you don't have permission, it's probably because you didn't set up that OAuth 2 screen correctly. And then finally, while you're setting all that up, there will be a prompt that tells you to enter this redirect URL. So you're just going to copy that, paste right into there, and If I didn't explain that well enough, like I said, just go to docs and it's super simple. Okay, so I'm going to connect to my Google Docs account. We're getting a document, we're getting it, and then you need the doc ID or URL. The ID is basically this part of the URL, so I copy this here. You just want to make sure you don't get the /edit, everything after right here. You're going to put that ID into there, and then you want to test it because then you know if it actually is working or not. We're testing it. We see this is the information, the contact information that we wanted to pull. So that step is working here. Okay, so now we know that that's pulling correctly. Now we need to add a node that's going to push this into Pinecone. So Pinecone Vector Store. Credentials. Once again, you're going to have to set up the credentials, so you're going to create a new one. All this one needs is an API key. Back into Pinecone, super simple, right on this left-hand side, API keys. Copy that, paste it in, and, and you're good to go. So I think we'll go with this one here. I think that's the right one. We don't want to retrieve documents. As you can see, this is the operation for this node. We want to insert documents. We'll be retrieving them later, but right now just inserting. And then the index is sample. As you can see, that is what my index is called right here. So we want to make sure that we're choosing sample because that's the one that we're pushing our contact database into. And then finally, you want to add a namespace. We're going to call this one contacts, and this is basically just to organize your data. Basically, if you've got different client information, you want to split that into different namespaces, that sort of thing. It makes the agent more efficient at being able to find what you're looking for, basically. Okay, so we've got that set up here. Now we need to add a data loader. Can leave this as it is. And then a token splitter. And we've got chunk size and we've got chunk overlap. So the chunk size is basically just the number of characters that's going to be in each chunk. Your agent's going to call this tool, go search in the vector database, and it's going to grab chunks and look through them. So the bigger your chunk size, the more data at a time. But like I said, the database wasn't that big for contact database. So I'm just going to go 200 here. And overlap is how much overlap is going to be between chunks. So we can just leave that at 0. Doesn't really apply too much right now. And then the last thing we need to do is add the embedding. I always pretty much just do OpenAI, or OpenAI. And then again, another credential. This one, again, you're going to need your API key. So another simple one, you're going to go to OpenAI. If you haven't made an account, you have to make this so that you can call the large language model. OpenAI API keys. And then right here, just copy that value. Once again, I can't show you guys because I'll be exposed. But important step here, make sure that the model is 3 small, because if you remember in our Pinecone vector store, we made the model 3 small. So you're going to make sure you do that again here too. Okay, now we're just going to want to go ahead and save that and test this workflow. So that's going to run everything. It grabbed the Google Doc. Oh, you see here it's not connected to this node, so connect that. Save it. Let's run it again. It's going to pull that. Now it's going into here, loaded our data. And now let's go back into the namespace and check if it worked. Oh yeah, I just refreshed as it came in, but I just wasted like 10 seconds of everyone's time. Okay, contacts. There we go, it's in there. We're good to go. So that is this workflow, our Pinecone pushing it into Pinecone. Now we're going to do the the send email tool. So we've got send email trigger. So this workflow is going to be called by the agent when we tell the agent, hey, can you send an email to blank? Then it knows, okay, I've got to use the tool that says to send an email. So the trigger here is when called by another workflow. We haven't made that workflow yet of the AI agent that's going to call this, but that's how this one will be triggered. We'll configure this in a sec. We just wanted to start that off here. The next thing that we need to do here is grab Gmail. And a lot of integrations again, a lot of actions here. Obviously we just want to send a message, so we're going to click send a message. I think this is the last credential you need to connect, I hope, because it's super annoying, but once you do, then they're all there. So Gmail, you're gonna have to get client ID and client secret, but I'm pretty sure, um, that should be easy now that you already have all this other stuff set up and you've got your credential screen right here. So super simple. All right, so we've got all that set up. We were going to be sending a message, and all of this stuff is going to be variable, right? So You want to change to, to an expression because that's going to change. Subject expression, email type, I'm going to do text. The message is definitely going to be variable. And then we've got some options here. Append NNN, you want to turn that off, otherwise at the bottom it's going to say like, this message was generated by, you know, or sent by NNN. Turn that off. BCC also variable. CCC also variable. And if you— if these things are left blank, it'll just be left blank. It won't really— it won't mess with or it won't break the automation. And then sender name, this can actually be fixed because likely this email will be a personal agent, or, or sorry, this agent will be a personal agent or for a specific client, and they'll always be sending from the same address. So you can leave that as fixed. And just leave it blank for now because we have to get the script to read into these specific fields. So come out of here, copy this node, just, you know, Command+C, and then we're going to use ChatGPT. So if you paste that in here, it's going to show you basically like the JSON script that is behind this node. All we need here is we're looking at the parameters because that's what's going to fill in. So I'll try to explain that better in a sec, but let's just grab these parameters real quick. I'm going to copy those parameters, paste them back in here, and ask chat to, um, list these parameters in a query field as a stringified list. Okay, we also want to exclude options. I hope it understands that we're talking about the— this parameter. Okay, that is not what we wanted. Let's try that again. Chat, list these parameters in a query field as a stringified list. Let's just try that. Okay. Not cooperating. Okay, this looks more like it. There's lots of ways to do it. I wanted to show you guys how to use chat to do it because it's easier for, you know, low-code, no-code. So this looks more right. It didn't exclude options, so we're going to ask it to do that. Okay. Yeah, that looks a lot more right. So you can go ahead and copy this here. But I'm also going to show you guys the way that I usually do it because it's easier to read and easier to troubleshoot. And that's— you're going to put it right in here basically. So I'm not going to use the one that chat just gave us, I'm going to use this. I just think this one's a lot easier to read because basically all you're saying is the agent has to figure out who's it going to send to, and the next one is going to be subject, the next one is going to be email type— is it already text? Message is what? So if that makes sense, it's a lot easier for— it's a lot easier to read that in my opinion than seeing all these slashes and closed brackets, square brackets, all that kind of stuff. So that's why I use sort of this, um, what do you want to call it, taxonomy. But you got to make sure it's in a query field and in quotes like this. So probably doesn't make a ton of sense right now, but let's just take a step back. So when the agent is understanding that you need to send an email, it's going to take your message. So if it says, can you send an email to Phil Dunphy asking what's up, it's going to understand, okay, so we need to send it to Phil Dunphy. We're gonna make a subject based on what they prompted me. So the subject here is gonna be what's up. The message is gonna be, hey, how's it going? Was wondering how you're doing, you know, what's up with you, that sort of thing. And then it will leave these other ones blank because we didn't mention a BCC, CCC, that kind of thing. And then before we push it into Gmail, we need to grab OpenAI, and we're going to do message model. Connect that. You should be good on that already. We've got text message model. We're going to choose 4.0. Just seems to work the best. And then in this message, we are basically going to say parse the query, the one that we just put into the previous tool. And output the parameters separately. I like to do system prompt because then it knows, um, it's sort of its role. We've got simplify output. We want to output the content as JSON. And then we also need to add this message here because it doesn't know exactly what the query is that it's parsing. So that's where we drag from here This query is going to go right into here. Make that fixed— or sorry, make that an expression. And this, we should be good to go with this node. You want to go ahead and test this step here, and you can see that it came through correctly. So it knows these are our parameters. We're going to send it to someone, subject, message, all this kind of stuff. So that's how we know that this node is working correctly. But one thing that's super important here that I forget, and I pretty much just forgot again, is in front of this jQuery, you need to add JSON.stringify and then open parentheses and close it off. If you don't do that, it's going to read in your values over here as objects rather than a string, and that's not good because it's going to give you an error and say expected string but received an object, that sort of thing. And really frustrating because, well, I just hate when things don't work, right? So, okay, we've got that set up. Now we need to come into here and actually set up Gmail so it knows what to send and who to send it to. It's really simple. We've got our content over here from that JSON query, and we're just going to drag stuff in. So send to is the to for the Gmail node. Subject, subject. Super easy, right? Got message, BCC, CCC, and then here we're just going to go ahead and sender name, it's going to be from Nate. Okay, save that. And now we just need to do one more thing. We're going to grab set to edit fields, set. So this is manually making a field, manual mapping. Add one here, we're going to call that response. Make sure it's a string, and then we're going to say sent. That's all we need to do here. Save that, and our email tool should be done. So the reason why we have to do this is because the agent sends the query over here, it's going to go through here, go through here, and then we need to go back to the agent. We need to communicate back to the agent that we did this task, that it's done, so then it can communicate back to the human that prompted it Okay, we did it. So this sets the variable, the field as of response to set sent. So then the human knows, right? Okay, so we've got Pinecone, we've got the send email. Now we're going to actually make the agent. So first step again, we have to build it, we have to put a trigger. We're going to use on chat message this time because we want to trigger the agent or trigger the workflow by talking to it. So We're going to leave that as is for now. The next thing to do is add the agent. We can also just go down here to Advanced AI. You see the different— there's the templates. There are different things here with, you know, text classifier, question and answer chain. We're just going to grab the agent. It's going to be a tools agent. And we're not going to take from previous node automatically. We're going to define that. And this is going to be, um, it's going to be this variable right here, json.chat_input. It's not working yet because we haven't actually ran anything, but that is what's going to fill in over here, basically saying like, this is what the human just asked us to do. So we're going to go to require specific output formula and then system message. This is where you're actually going to prompt the agent. So we're not going to do that yet, but just wanted to add in these options real quick here so we don't forget. And then I want to return immediate steps so that when things error and don't work, we can see what the agent did exactly. So this is what we need to do for now. We need to come back here and prompt this later, but that's a good start. So you can see we've got different things we can add to the agent, output parser tool, memory. Chat model. We're just going to touch tool and chat model for today. So chat model, same thing, OpenAI, connect it. We're going to grab 4.0, especially for one that's going to be talking to us and thinking. Tool, we're going to call an N8N workflow. This is obviously the one that we just made, the tool that's a send email. Just want to keep everything organized here, especially once you start to have multiple tools given to an agent. And then you need to give it a description of when is the agent going to use this tool. So call this tool when you want— when you need to send an email. There we go. It's simple as that. Source database, the workflow we can define from a list. You can also do it by ID, but you'd have to grab that URL thing. So the The list is easier because we have the send email right here. Field to return response. So that's when we set the response field earlier to sent. And let's see, is there anything else that we need to do on this one? Specify input schema. Yeah, that's what we need to do. We want to define below, and this is like the schema that this tool is going to be using. So what we need to do, save that real quick. We need to go back to our Send Email tool. We need to make sure that the schema is the same from right here because this is what we gave this tool. So copy that, head back over to our agent, which is this one. I should name this real quick so I don't get confused. Okay, and then we're gonna put that— we're gonna paste that right back into here. There we go. So this tool should be set up now. Save that. Okay, I think we just need to add the one more tool, which is going to be the Pinecone vector database. And as you can see, we can't just straight up add Pinecone, we have to add the vector store. So we've got this, um, this is just going to be contacts data. Again, we need to give it a description, so call this to retrieve information about contacts like email address. What's wrong with this? Ah, can't put a space in that for some reason. So good to go here. We got to add a model. We're going to again go OpenAI. 40. That's good to go. I'm just going to move this stuff over here. And then the actual vector store, what's it pulling the data from? Pinecone. Got to connect this again here. This time we're going to do retrieve, obviously. Get the right index. And then again, you got to make sure you're pulling the right namespace. Contacts, I'm pretty sure that's what we called it, right? Contacts sample Okay, perfect. Got that here. So let's save that. Oh, can't forget to do the embedding. Otherwise it wouldn't know how to figure out what's a name, what's an email address, that sort of thing. So again, make sure it's 3 small because that's how we set up our vector store. And then we're just going to save that. Okay. So, got We're gonna test this out now. Hopefully it doesn't error, but if it does, we can sort of go into how you can find out where it's erroring and how to fix that. So let's try this. So again, send an email to Bill Dunphy asking if he wants to get lunch. Seems there's an issue with sending the email. Would you like to try again later? Okay, so let's see what happened. We can see it errored at the send email tool. We're going to go to all executions to figure out what happened. So we can see this here. We're going to view it. This is basically showing us what sort of data was running through at the time. So we've got— oh, okay. I think I know exactly what happened. We didn't go back and prompt the agent. So look, it's got like it's got the right email. It's got the right subject, all this kind of stuff. The issue, I believe, is just that we didn't prompt the agent because we always just forget to do that. So that should be the issue. So, okay, something cool that you can do is grab a screenshot of this workflow. Copy that. We're going to go back into chat. We're going to give it this picture and say, please prompt this agent. Include the parameters for the email tool as well as overall context, background, and instructions. Okay, so prompting is super, super important. This definitely is not the way you'd want to do it when you're really building out a complicated agent, but for now this should work. But prompting is super, super important as far as getting the email or getting the agent to consistently work the way you want it to. So let's see if this works. We're just going to grab from here up. Whoa. Okay, so it's got context, background, instructions. It included the parameters here for the email tool. So let's try this again. Right now I just thought it was a helpful assistant, which it is, but it didn't have all of this instructions. And also one thing I like to do at the end is, um, sign off the email from Nate because it knows The sender name is usually just for when it pops up right here to say like it's from Nate, but sometimes down here it would say in brackets like sender name or something. So it's nice to sort of specify that. So we got that saved in here. Let's try that again. And then email to Phil Dunphy asking if he wants to get lunch. And we just hope that he says yes. Send an email to Phil Dunphy inviting him to lunch. Is there anything else I can assist you with? Okay, perfect. Inbox, lunch invitation. Hey Phil, would you like to get lunch sometime? Best, Nate. Perfect. Super simple. Yeah, so that is just a very, very basic one. It's got one tool. We didn't even give it a Windows memory buffer, which is just how you can continuously chat. It'll, it'll keep history of past messages that you've sent, and it's going to be able to know to work off those. But that's just a very basic one, and it's, it's really good to get in here and play around with N8N. It's going to give you a great idea of, like I said, the triggers, different nodes. As you can see, there's so many integrations. Like if we just go to, you know, Gmail, You've got all these different things, and you can build an agent that strictly can do everything for you that you might need to do in Gmail, like an inbox management agent. So yeah, super simple one, great one to start off with building. I'm gonna be making more videos where we'll probably add on different tools to this agent, so it'll be a complete personal one where it can do stuff with your calendar, do stuff with your Google Drive, just cool things like that. So Like I said, if you enjoyed this video, I'm going to try to tailor stuff towards people that are new to the space. I'm trying to learn as much as I can, so trying to help as many people learn as much as they can. But yeah, that's all I've got for today. So thanks, guys.










