How I Built an AI Agent to Automate my Emails in n8n (Step by Step, No Code)

Dr. Violet Howard builds a no-code email automation workflow in n8n that uses OpenAI to classify incoming messages, retrieves policies from Pinecone for support emails, and drafts replies automatically. The system routes support and non-support emails differently, sending drafts to Gmail and summaries to Telegram.
Chapters
Hey guys, today we're going to be going over this framework that's going to help you create different AI agents in order to automate your inbox. In this workflow that we're going to be walking through step by step today, it starts by watching for your emails and then it evaluates them to see if they're customer support related or not. If they are, it's going to hit the customer support agent that has access to your internal policies, your FAQs, stuff like that, so that it can craft you an accurate draft in that same thread of the original email. And then you can go in there and approve it before you send it off. And finally, it's going to notify you on Slack or Telegram, whatever you want it to be. And it's just going to say, hey, we got this email, this is what it's talking about, we created a draft if you want to go in there, check it out, and then send it. Let's do a quick demo, see this thing in action. We'll hit test workflow. We will see that the Gmail trigger pulls in an email. We're now checking if it's customer support. It is, so it's hitting the agent. The agent's looking in our vector database for information on the policies. Um, it's creating an email right now. It just hit it, the Gmail tool, it made a draft, and And as you can see, we just got a message back in Telegram. So we got a little summary about what just happened. And then if we go into our email, we can see that we got this email. And then we also have a draft, which was, you know, replying to this email and it has information about what the customer asked about. So, um, that's how this workflow works. And, you know, let's not waste any time and hop straight into the step-by-step tutorial. Okay, here we are within N8N. As always, the first step when you're creating a workflow is to set up the trigger. So in here we have the options of we can trigger this workflow manually, we can do it on an app event, we can schedule it. But here what we're going to do is actually none of these. We're going to do a trigger of Gmail. So what we want to do is when an email comes through, that's when this workflow is going to execute, and the agent's going to look at this email and understand if it's for customer support or not customer support. So as always, the first thing you need to do is set up your credentials. So I already have mine connected here, but you need to create a new credential. You need to sign in with Google, and if you don't understand how to set up your OAuth consent screen and all that, you can go into the N8N docs, super simple. Or I also made a video about it, which I will tag right up here. So anyways, once we have that connected, we need to set up how this is going to work. So as you can see, our event is on message received. That's what's going to trigger this workflow. And then we also have a couple other options here which we can simplify or not simplify the email coming back. So let me show you what the difference is there. I'm going to come up here and hit fetch test event. This is going to pull the most recent email that we got. And as you can see, we got a snippet which is, hey, I was wondering how I can track my order. Also, what is your refund policy? Thanks, James. And in this case, it's fine. As you can see, we didn't get a ton of information back. This information just got simplified. And like I said, in this case it's fine, but we're gonna turn it off because if you had a longer email, the email would get cut off short. So now you can see we have a lot more information coming back. It may be a little more confusing to look at, but it's important so the agent's gonna be able to get full context of the email that is coming through. Also, one quick tip: we just triggered this, this email trigger, and we want to be able to play with this data for the rest of the workflow while we're testing. So if you come up to the top right and hit Pin Data, This data is now pinned. Once we refresh everything, we don't have to reload this trigger. We're just going to have this email to play with for the rest of our workflow. So fun tip. From here, we just want to grab a Set Field so we can clean up some of the data that's coming through, make it easier to look at, and also make it easier to reference. So I'm going to grab a Set Field. We can just call this, um, Set Content. That's going to be good enough for us to understand what we're looking at. And the first thing that we want to set is the email body. So we will have that be the subject, and then we're gonna scroll down to try to find the actual content that's coming through in the email. Right here we have HTML, we have text as HTML, but we're looking for the actual text, which is right here. So we're gonna grab this field, drag that into the value section, and now we have JSON.Text, but what's actually coming through as JSON.Text is the email. So, hey, I was wondering how I can track my order. Also, what's your refund policy? Thanks, James. So now we have the email coming through. You could also go through here, and if you wanted to, you could set other fields like the subject, like the ID, like, you know, the, the who it's from, that kind of thing. But actually what I'm gonna do is I want to set the thread ID. So we're gonna grab the thread ID, and this is gonna be important. So later when we want to create that draft and we want to associate it with this email that's coming through, we can plug in this thread ID so that it knows what to respond to. So in thread ID, we're just gonna drag in right there that ID. And this isn't necessary, we could always reference it later from the Gmail trigger, but but sometimes it's easier just to have some information set, and that way you know where it is. So we'll actually just go ahead and test the step real quick so we can see that what comes through is the email body as well as the thread ID. Real quick, I wanted to introduce you guys to a super cool platform called Mind Studio. It's an integrated development environment to develop AI features and workflows without coding, making it accessible to developers and non-technical users alike. With Mind Studio, you can access over 50 AI models across text, image, audio generation, and soon even video. It's not just about having access to models, it's about flexibility that MindStudio can auto-generate workflows using AI, train on your data sources, scrape the web, and execute JavaScript or Python code. You can mix and match these models to find the perfect balance between cost and performance, and you can even deploy AI workers as apps or APIs and integrate them with tools like Zapier, Make, or virtually any platform that supports HTTP requests. If you're intrigued, join the free introductory webinar to learn how MindStudio can bring your ideas to life. Sign up now at the link below in the description. Got the email, we've got the content set. Now what we want to do is we want to add a large language model to be able to look at the email content and determine if it's customer support related or not. So we're going to come into here, we're going to add an OpenAI node, we're going to grab a message model node, which is— oh, I passed it right here. And now from here, you need to just obviously connect your credential. We need to choose the type of model, so I'm going to go with a 4o Mini in this case. And then we're going to set the system prompt right here, which is going to be— let me pull this up in expression mode. We're saying prompt: analyze the content of the email and determine whether it's related to customer support. If the email pertains to any of the following topics, mark customer support as true, otherwise mark it as false. So we wanted to output a field called customer support with either true or false, and then we just gave it some topics that would be customer support, like order status, issues with damaged products, returns, refunds, subscriptions, all that kind of stuff. And then we just told it to output the following, um, in a JSON format, JSON format, with a field called customer support and set it as true or false. So we've got that, um, that's our system prompt. This is telling this node how to act. Now we want to add a user, which is just going to be— we're dragging in the email body. But first, before we do that, we want to say, here is the incoming email, add a little colon and a space, and then we'll drag in the incoming email. So now it's going to be looking at that email We're gonna output the content as JSON, so it actually comes out in a field called customer support, and we'll hit test step, see if it worked. So in this case, customer support came back true. Um, why we wanted to output it as JSON, because if we didn't do this, I will just show you real quick. It's going to output as content and then customer support true. So it's doing what we want it to, but we want the field to actually be called customer support so that we can call it in later. So that's why we want to output it as JSON. I'm just going to come in here and call this customer support eval. So now this node is just evaluating if this email is customer support related or not. All right, now that we have that saying true or false, what we're going to do in here is grab a switch node. So we want two different things to take place. If customer support is true, then it's going to go off and it's going to create that draft for us in response to that email. And if it's false, then we want it to go down a different path, which will either notify us that we got an email that's not customer support related, or, you know, any other logic. So first, let's just set up the switch. So we're just going to say, oops, customer support. That's what's going on within this node. The first value is going to be, we're saying, is customer support right here. Is this— and this is a Boolean, as you can see, it's not a string. So over here, the letter A means that this field is a string. This block means that content is an object. This little hashtag, or what's it called, a pound sign, shows that index is a digit field or a number field. And then finally, this check mark just shows that customer support is a Boolean. So we're going to go to Boolean and we're going to say it's true. So if this is true, we're going to rename this output and call it customer support. I'm going to type that a lot in this video. And then anyways, we're going to, we're going to drag another one It's going to be Boolean is false, and this output is going to be not customer support. Okay, so we'll hit test step. We can see because customer support is true, it's going to come out the branch of customer support. So that's what's going on right here. So let's continue down the path of assuming that this is a customer support email. We'll drag some logic out this way, and in this case, what we want to do is now we're going to add our AI agent. So in here, we are going to call this guy the customer support agent. Okay, so we have a customer support agent. This is going to be a— we could do a conversational because we want it to, you know, respond with very human-like answers. So actually, we'll try conversational. We're not going to take from previous note automatically, we're going to define below. And the text that we're getting is going to be— we're feeding it in the original customer support email that's coming through. So we're going to go back to the Set Content node and we're going to drag in the email body. This is what we want this customer support agent to look at, evaluate, grab our information in order to respond to it accurately, and then respond to it accurately. So, um, from here we will need to add a system prompt. So we'll add this in for now, but we will obviously change this up. What we want to do next is we want to obviously give the agent a brain. So I'm going to come in here and give it a 4L mini. We're going to leave the memory as blank for now, but what we want to do is add a tool. So we need to give the agent understanding of customer support policies and guidelines for our company. So I'm going to grab a vector store tool. We're going to call this one customer support docs. We're saying that this tool retrieves data about our— or no, not data, we'll do retrieves information about our customer support policies and FAQs. Okay, so Vector Store tool, we need to connect our model to this as well. We'll leave this one as 4M Mini. We need to add the vector store, which is going to be Pinecone. We're adding our index, which is sample, our namespace, which will be called customer support. And we haven't done this. We'll do this in a sec, but that's what we're going to be loading it into. And then finally, we need to choose the actual embedding for our agent or for our vector store, which we're going to do embedding-3-small. So we have this configured. Now what we're going to do next is actually add our document to our Pinecone vector store. So here's the customer support document that I have right here. Customer support policies and FAQs. We've got policies, FAQs. Of course, this was just generated for me by ChatGPT. So anyways, we have this document. We're going to load it into our Pinecone. So I have this one already in here as pulling customer support policies and FAQs. We'll hit test workflow. We're downloading the file here as binary. We're uploading it to Pinecone. We have everything set up in here so that it should be splitting out correctly. So now we have all this information within that document embedded up into 4 different vectors and then put into our, what's it called, our Pinecone. And as you can see, we're loading it into a namespace called customer support. So now back in this agent tool, that's why we referenced right here, it's looking, not right here, right here, it's looking for a namespace called customer support. So it should be able to grab accurate information for us. Real quick guys, I just wanted to say if you wanna download these templates that are shown in this video, go to my free school community linked in the description. You'll go to YouTube resources, click on the post associated with this video, and then you'll have the workflow right here to download. Also, if you're looking to take your N8N and your AI automation skills a little deeper, check out my paid community. We've got a great classroom that goes over deep dive topics, real project insights with client builds. We've got a great community and we've also got live calls. We're doing about 5 a week right now. So hop in here. I'd love to see you guys. Finally, if you're looking for me to help you build out this sort of stuff within your business or you're looking for some AI consulting, then book in a call using the link from my website down below and let's talk. So in here, what we're doing is the resource is going to be a draft. The operation is obviously that we're creating a draft. And now we just need to set up the subject, the text of the email, the message, and then any other properties, which we want to do a thread ID. So, um, first things first, we need to configure this node. We're going to call this one Create Draft, and we need to set up the subject and the message. So what we're going to do is use that super cool From AI expression. So we're going to change the subject to an expression. We're going to come in here, grab two curly braces, and we're going to type in dollar sign from, we'll grab from AI, and then in the key, in quotes, we're going to say subject. And so this is going to, um, the agent's going to understand, okay, I have this email that I just got. I'm going to hit the vector database to get information to answer the email, and then I'm going to make an email. And then I know that here needs to go a subject, and then down here needs to go a message. So it's just a really cool way to give your agents tools much quicker. If you want to see a video about it, I made one. I'll tag it up here, but I kind of go in depth a little more on how these functions work and the value in them. Anyways, down here in quotes we're going to put— actually, we're going to put email body. Okay, so we've got that. And then finally, we need to reference the thread ID. So this is also going to be an expression, and we need to pull this dynamically from the email that we got in the first place. So if you remember, we set that earlier with set content. So we're going to grab set content, we're going to type a.item.json, and then finally.thread_id. So now this is dynamically pulling in the thread ID that's associated with the email that triggered this workflow in the first place. And I think we should be good to go here with, um, this node. So we've got our vector store tool. We have our create draft tool. And now we just need to make sure that this agent has a prompt. So I went ahead and grabbed one already. We're going to change this to an expression. We're going to open this up and we're going to delete this and paste in this prompt. So basically what I said in here was, you're a highly skilled and empathetic customer support agent specializing in drafting professional and helpful responses to incoming emails. Your tasks are to take the email, use the customer support docs tool to look up relevant policies, create a draft using the create draft tool, and then after drafting the email, provide a concise summary of the email content as the output. And then I went through specifics, context, some examples, and all that boring stuff. Um, but anyways, let's see how— we'll see what happens. So we're going to test this step. We obviously are hoping that, um, the selected tools are not supported by conversational agent. Okay, well anyways, we'll change this to a Tools Agent and see what happens. Let me just copy again this prompt because when you change this, it's going to, um, get rid of your prompt. So we'll grab that in there and let's see, did that? Okay. Now we'll test this step. So it's reading the email. It's going to understand to hit the Vector Store tool to get that policy information. Now it is going to go back. It's going to hit the Create Draft tool and then create that draft for us. So all that finished up. Let's just see the output that we got, which was a quick summary of the email, which is perfect. In the draft, we can see that the subject was Order Tracking and Refund Policy. The message was, Dear James, thank you for reaching out. To track your order, you can log in, blah blah blah. Regarding our refund policy, digital products are non-refundable, blah blah blah. And then, best regards, Kelly, Customer Support, ABC Corp. So if we were to check in here, we would see that it answered correctly. I don't really want to— actually, yeah, sure, let's go through it. Okay. What was the first thing we asked? Um, it said to track your order, you can log into the account. So let's look at how you track your order. Track order. You can log in your account and visit the order history section, or you can use the tracking link. Okay, perfect. Um, and then for refund policy, digital products are non-refundable. Let's look at digital. Digital products are non-refundable unless there's a technical issue. Okay, so it got the information right. Perfect. And we can go into our Gmail and see if it actually created a draft for us. Right here we created a draft and it's in response to that earlier email that we sent. So now if we like it, we can hit send. Please specify at least one recipient. Okay, so we would have to configure the to, which is interesting. Um, is that not something that— ah, to email. Okay, interesting. So what we're going to do is now we're going to grab the to email. So that's actually something that, you know, you learn something new every day. So for to email, we want to grab that from the Gmail trigger. We're going to be looking at item.json.from.value. This is me pretty much just guessing. Okay, actually, let's, let's do this the easier way. Okay, what we're going to do instead is we're going to set the content over here, the to email as well. So this is just going to be who it's from. And then what we want to do is we want to go all the way down to see who the email is from. Right here, it's from natehirk88. And now we've got that information. We'll test this step. We have that going through. We're going to do this whole process again. Customer support. It is indeed customer support. And then right here, we want to fill in who this is actually going back to. We want to grab, um, from the set content, we're grabbing item.json.from. Okay, so sorry about that. Now we have the to and the thread ID and all this information. So let's try that one more time. It's going to do the same exact thing. It's going to answer pretty much the same exact way. It's going to create that draft for us. So it just created the draft. Now we got the output. And now if we come into here, we'll go back into our drafts. We can see we have— actually, where is it? There we go. So there's the new one, Dear James, and then it actually has the email which we could send off. So you would pretty much just be able to check if you like the way that it looks. If not, you can make a quick change and then you can send it off. So, um, that's that. Now what's next? So two other things that we want to do here. The first one is we want to add an option out here, which is going to be, um, let's just do Telegram. So what we're going to do is we want to just basically be notified that, okay, we got this email and then we were able to respond to it automatically. So in Telegram, what we want to do is send a text message. I can never find it. There it is. And, um, let's connect your account. And then we want to be sending a message. Obviously, we're going to have to configure our text ID and our Sorry, our chat ID and our text. So real quick, let me show off how you get your chat ID in Telegram. So if you go to the trigger, we'll do on message. Okay, so I'll hit test step in Telegram. I will bring in my Telegram trigger and just say hi. And now we can come through in here and we can see the chat ID. So we got our chat ID right here. I'm now going to paste that into our chat ID field, and now we're good to go with this. We can get rid of this trigger. And then finally, what we need is we need the response from our agent. So this is going to be an expression. It's going to be json.output because that's what's coming out from the agent. And then finally, we're just going to turn off the append entity and attribution. We'll just call this response. Okay, so now once that happens and the agent responds to a customer support email, it's going to let us know that that happened. And we can configure that later and say like, okay, we got an email from blank and it said blank and we sent it at this time. But for now, we'll keep it simple. Okay, now to set up what happens if we get an email that's not customer support. I'm gonna copy this Telegram, we're gonna paste it down here, and we're going to configure this. So the chat ID is gonna be the same, the text is not. We're gonna say, you received an email at, we can do $now.format. So we've got the, that information, we can do, um, minute, minute. Okay, so at 4:29, um, on, you know, we can change this too. So let's say we just wanted to do, um, actually no, we'll just do time. So you just received an email at 4:30, um, saying, and then we can grab the actual content of the email. So we'll do the same thing, set content .item.json. I don't know, it just hasn't been executed. So what do we set that as? Um, email body, is that what it was? Uh, let's see, email body. Okay, so that should work now. Um, go ahead and save that. And so this is pretty much where we're at. So let's real quick, let me send off an email that's not customer support related and we'll see what the response is. Okay, so yeah, thank you for meeting last week discussing our quarter 4 marketing strategy. I'm pretty sure this should be evaluated as not customer support, so we'll run this through. We'll see. There we go, not customer support. And then if we hit this, we got the Telegram notification of we received an email at 4:32 saying, dear Alex, blah blah blah. So this obviously needs to be formatted differently. We would just come in here and we would change the way that this is coming through. But this is just to show you, you know, what you can do as far as how you can set up different logic. So maybe we'd set it up like that. Put a colon right here, and then we'd get this answer instead. Um, so that's, you know, if it's not customer support, it'll go this way. If it is customer support, it'll go this way, create a draft, and then it will actually send you a response. So what we should do real quick is let's make this workflow active. Got it. And let me fire off an email, and then we will see, um, you know, the live execution of this happening without us having to test anything. Okay, so I pretty much just sent off an email. I've got my Telegram pulled up. The workflow's active. We will be watching to see when this happens as far as when the draft gets created and when the Telegram message comes back. Okay, so I just got that Telegram message back. It said that it drafted an email response addressing David's concerns about a defective product. The response includes instructions on how to report the defect. It gives us a summary where David informs about blah, blah, blah and wants to speak to a live rep. So we got that message and now we can go into our email. If we go to the thread, we will see that there's a draft created right here for us. It has a to field already, and it pretty much tells him how to handle talking to a live rep and what he should do with his defective product. So we can approve that, we like it, we'll send it off, and yeah, that's gonna be how that works. If we go into here, we can see this was the live execution that just took place because the workflow was active now, and it went through the branch of customer support, it went through the agent, it hit the vector database, it hit the draft, and then it finally sent us that Telegram message. So that's going to be it for this one. I know that it was a, a pretty simple walkthrough of a build. It uses some conditional logic, it uses an agent and, um, aspects of RAG, as well as creating a draft using an email tool. And if you guys appreciated this one, I would really appreciate if you could drop a like. It really helps me out. Subscribe for more N8N and AI agent tutorials, and I will see you guys in the next one. Thanks.










