How to Build Your Own AI Assistant for Email Writing Without Coding

Headshot of Matt the Planet No Code Bubble Coach

Need 1 to 1 help?

Your no-code consultant & Bubble tutor.

Learn how to build your own email assistant powered by AI using the no-code platforms and Plum. This blog post will guide you step by step on how to create structured data prompts to write emails without a single line of code. Dive into the world of no-code development with ease.


This is how you can build your own email assistant powered by AI without writing a single line of code. And I'm going to be using two of my favorite no code tools. We'll be using plum and we'll be using So let's dive right into the Bubble app. So here's a blank Bubble app.

Set Up Your Bubble App

I literally just created it. I'm going to say skip application assistant, and here is my blank page. Now, there are tons of other things that would go into a production ready Bubble app, but right now I'm just going to focus on the AI calls, writing the prompt and having structured data in JSON sent back. Now, if that's a little bit confusing, don't worry, this video is going to explain every single step. So what do we need for our AI powered email assistant?

Build the Input Form

Well, if I change this into a column, I'm just going to start putting inputs on here. So I'm going to write in recipient name and if I right click on it and then say group in a, in a column, I'm going to give this a max width of say 660. Going to center it so that everything's a little bit clear, more clear. I'm going to just give the page background a nice gray, make this background white, add in some padding.

Create a Series of Inputs

This is going to be the form that we use in order to build our prompt in order to get our email written. So basically I'm going to create a series of inputs. We're going to send those inputs over to plum and plum is going to send some structured data back as part of the AI response so that we can save some time in replying to our email else. Right. So got recipient name.

Add Multi-line Inputs

I'm just going to copy and paste this. And we'll also have sender name. We'll have a multi line input where we can say, let's move that down to the bottom, describe the email you want written. Okay, yeah, we could be neater than that, but it's going to get the job done. And then I'm also going to copy and paste this and have one that says background information because I want to be able to provide the AI prompt with a bit of business background.

Provide Background Information

And we'll be using no code as an example here so that the email that is written understands the context from which it's coming from. So let's add in our button and you'll notice, well, let's neatness up a little bit neater. Say twelve.

Generate the Email

Okay, now say generate email. Okay, so I've got four inputs. Let's now move over into plum and I have a fresh plumb pipeline ready to go. So I'm going to add in my input. So we'll say recipient name.

Input Fields in Plum

Okay, now plum has got a number of fields and actually I'll use them as we go through. Basically everything that you put here is going to be behind the scenes and plumb is going to make the prompt that goes off to OpenAI and that will be how you fine tune the kind of reliability or the preciseness of the data that you get back. So I think recipient name is quite an adequate description. So I'm not going to add a description in here. I'll put sender name, also make it required.

Define Content and Background Info

And then I'll have content and I'll say a. So I will expand on what content is a description of what, what the email should include.

And then I'm going to say background info.

I say background information about the individual or business writing the email.

Add LLMs and Join Nodes

Okay, now I add in my LLM.

So let's join that up. Now in plum you have to have a direct link between nodes in order to pass data between them. So let's rename this, I'll say generate email. And now this is where I write my prompt. And you'll see very quickly how using plum is much.

Writing Prompts in Plum

Basically it's great for working with AI, especially if you're beginning to develop those complex workflows because it just allows you to really quickly test what you're doing. And I just noticed I haven't clicked save. So we'll say, right, perfect. Okay, so we'll say you are an AI email writing assistant. Use the data provided below to write an email.

Adding Tone Options in Bubble

I'm going to add in another field because it demonstrates something else we can do in bubble, which is we're going to add in a field for tone. So I'll say tone. Okay, and I'm going to just use static choices here because it's quick. But you could of course use an option set if you wanted to have a set list of tones and have them appear elsewhere in your app. So we'll say friendly, friendly, professional and pirate.

Activate Tone Choice

Okay. And we'll make that should not be empty. Okay, so let's add that in as well into our triggers. This is just how easy it is to navigate through different nodes in the pipeline in plum and just change things so we can say tone.

Write Email in Desired Tone

Write the email in this tone. It's required. Okay, so now let's continue building our prompt. So we'll say recipient name and we just click to add in the variable or the merge fields. We'll say sender name.

Add Merge Fields

Okay. And we'll say content, we'll say tone and we'll say background info. So background information.

Testing the Pipeline

Okay, let's just test that. So we can say test pipeline. And so I'll say recipient name is Bob, sender name is Matt, content is welcome, email for no code community background is that planet. No code is a no code education platform.

And the tone will say friendly. Okay, so now I can test the whole pipeline and so plumb is going to do just that. And now I can play this one. I didn't actually set up any parameters for the AI, so let's just see what we get back and I can expand this out to make it easier to see. So we get back a response, but it's all kind of smushed into one.

Structuring the Output

And part of what I promised at the top of this video is we're going to structure it. And this is something which isn't so easy to do in bubble. And plum can be an immense help here is we actually have different parts of the output that we want to separate out into clear labels and know that it's going to happen and do that reliably. So let's go back into here and we'll say return response if you're interested. Look, we can also do webhooks.

Using Webhooks

I think that's going to be my next video with using Plum. Because when you send this request, bubble is going to wait until it gets a response back from plum and that will time out after a minute or two. So if you were to create some massive pipeline in plum and it took ten minutes, maybe you were doing some transcription, you can do that in plum too. You wouldn't want your bubble app to be waiting because it would time out. So let's say return response.

Returning the Response

We don't just want to send back an empty 200 status, we want to send back a step and we want to send back the right email step.

Setting Parameters and Output Properties

Okay. Right. So let's change a few things here. This is how we structure. I'm just going to make the temperature to 0.7.

I find that to be a good mix of creative but prescriptive and we're just getting raw text back. Let's structure it. So we're going to get back a record and we'll say suggested email content. Now just say suggested email. Okay.

Add Additional Properties

And now I'm going to add in some properties. So what do I want to get back? Well, I think I want to get back subject. We'll just do the bare minimum here, actually we'll say subject and we'll say email body.

Testing Adjustments

Okay, now we can test this right away. So I can say, in fact I can just click on here, I can rerun the LLM step. And we get back, we now get back our two different parts, subject and email body. So how do we go about linking this into our Bubble app? Well, if I go back into bubble and then go into plugins, add in the API connector, this is immensely powerful.

Integrate Plum API with Bubble

This will let you connect to hundreds of thousands of other apps and web services out there. So I'm going to add in plum, I'm going to authenticate in the header and I'm going to add in an API call down here and I'll say write email. So let's populate this with the required details. And Plumb is going to tell us where to put different parts of our input. So I'm going to click on deploy, I'm going to go straight to production, click enable production and go on to see URL.

Sending the Post Request

So we can see that we need to send a post request to this URL. So I'm going to copy it, paste it in, not get it's post. Also in bubble there are news as two different states. There's data and action. I'm just going to want it to be action.

I want it to be a part of my bubble workflow to send this request. Then if I go back to plum, I need to have authorization bearer with my client id. I'm going to come back to that, but I also need to include my, sorry, my client secret. I also need to include my plumb client id in the header. So I'm going to add in header Carton id.

Insert Client ID and Secret

I'm going to fetch that in a moment. But here's the bit that goes in the body or the data section of the expression. So let's go back into bubble and paste in here. Now this is JSON. It's a type of coding syntax.

So is it no code? Well basically it's no code because I'm going to explain every bit, which is just mention up front, if you get any punctuation wrong here, you're going to cause an error. So we'll be careful with it. So, but we can see where we have to insert values. So I'm going to say recipient name.

Avoid JSON Syntax Errors

Why am I doing triangle brackets? Because Bubble tells us just up there that that's how we add in dynamic values. And I'll say send the name and I'll say content, say background info and if yours doesn't look exactly like this, it's because you set up slightly different labels or keys in plum.

Ensuring Security

Now none of these should be private. What this means is that this is data that my bubble app user can access. And of course they can access it because it's part of the form that they filled in. I'm also going to make some changes here, which is like I say, punctuation is so easy to create a syntax error in JSON, especially with speech marks, special characters. So I'm actually going to get rid of the speech marks here.

But when I test it and I initialize my call, I'm going to make sure, whoops. That I put my speech marks back in here. So recipient name Bob. Send the name Matt. Okay.

Because that has to be the speech marks. Wherever they come from, they have to be part of this call. Otherwise I'm going to get a syntax error. I'll say write a welcome email for our community. Got speech mark at the end.

Perfect background. We are a no code education platform tone. Let's go professional this time. Okay. Right.

Fetch API Keys

I'm now going to go ahead and grab my API key and my client id, my secret key, two separate things, my secret key and my client id from plum. Plug them in and obscure them. Because a special secret key or an API key, that's like a password, you need to keep that secret and protected. Okay, so I've just scrolled down so that we don't accidentally see it. But remember you have to put that word bearer and a space before your secret key.

Initialize the API Call

I put my client id in here. That's fine. Right now, in order to begin to use this in my bubble app, I have to initialize this. And this is basically testing for issues or errors and it makes it accessible in my bubble workflow section. So I'm going to initialize the call.

Checking for Errors

This is good. If you get an error, it normally comes back very quickly. And in fact, here we go. So we get back an okay status and then we get back an object here. And within that we get back our subject and our email body.

Setting Up the Design in Bubble

So I'm going to click save because this is training bubble, the sort of structure that we should expect our data to return it. If I was to go ahead and add other output fields, I'd probably have to come back here and re initialize it so that bubble learns that those additional fields are there. Perfect. Right, let's go back into design and start putting this all together. So I'm actually going to copy and paste this, remove the button and then I'm going to repurpose part of this.

Displaying the Output

So this is going to be where we display our output and I'm going to use text inputs because it can be really helpful just to click in there, copy and paste content that's generated. So let's make this width 100%.

Using Custom States


So let's set up our workflow. So I click on my button, I say add workflow. First thing I'm going to do is go into plugins and I'll find here plumb write email. That's because that's exactly what I've labeled it in the Bubble API connector. Remember these speech marks, let's get the recipient input value.

Setting JSON Safe

Now there are no speech marks there. Also there's, for some reason someone could put a special character in the person's name. Much more relevant when we come to the content because you could be put there. They could be putting like speech marks in there. But we use JSON safe and this is bubbles way of basically wrapping it all in speech marks and ensuring that the technical coding term is escaped, ensuring that the special characters in that text are going to be treated as text rather than part of the code.

Configuring JSON Safe for Inputs

So we'll do the same here. For sender. I've got two fields called sendername. Easy mistake. So let me update this one.

This is now subject and this is email output. Get noticed by updating the placeholder. In bubble it updates the label. If you update the label of the element, manually updating the placeholder won't overwrite that. So I've send the name Jason safe.

Let's have our dark content. What did I call it? So look through, describe the email JSON. Okay. And let's have our background info.

Finalizing the Form

Background info and let's have our tone JSON safe. Okay. If you're guessing any errors, you probably not got JSON safe on each of those. Or you've double speech marked it in the end because you've left the speech marks in at the API connector stage. So I now want to display two bits of text back and this video is already 20 minutes long.

Integrating the Bubble Workflow

So I'm going to do it a really quick way without actually saving it. In the bubble database. I'm going to use a custom state. So custom states are a way of temporarily storing data. I'm just on the index page.

You can add custom states to any element on the page, but I tend to do them on the page itself so I don't forget where they are. So we're going to have subject, which is text, and we're going to have content. I'll say body to be consistent.

Set the Body and Subject

Okay, so what happens next? We get the response, we send the request. We get the response and we now wait on plum and the LLMs that plum is running like OpenAI to send the response back to plum and enter send the response back to bubble. So we now want to save our response. I say save, but we're putting it in the customer state.

Remember this is not putting in the database. It's like a temporary storage location on the page. So I want to set the body and I want to set the subject now. I go in, I say result of step one email body, result of step one subject. Okay, we're almost there.

Display the Output in Bubble

Now to display it. I'm going to refer to that custom state. So index subject.

Select Initial Content

I'm going in initial content not placeholder, index 40. Okay, I think we should test this. So I'm going to click preview.

Testing the Application

Right. Let's fill this out. We'll say recipient is Bob, sender, name is Matt, tone is. Let's go pirate welcome email for our no code builder community.

Debugging Json Errors

As I plan it. No code is, is a no code education platform.

Can't type this morning. Generate email.

Okay, we're getting invalid JSON back.

Troubleshoot Common Mistakes

Let's have a look and debug that. So I'm going to first of all go back into the API connector and check that I've not made any mistakes here. I'm going to re initialize this call to see if this is working fine. Yep, that works fine. So the issue is going to be here, right?

Ensuring JSON Safe on All Fields

I've forgotten to add JSON safe there. Did you spot it? Is that a deliberate mistake? No, I missed it. Let's go back to our preview and we'll say Bob, Matt Pirate welcome to our community background information planet.

No code is a no code education platform.
Can't type this morning. Generate email. Right. No error. This is a good sign.
And there we go. We get our separator, that subject and email. Now of course you can do so much more with this.

Applications Beyond the Tutorial

I've got a few internal app ideas that I'm working on combining bubble and plumb. One where I've just kind of got layers and layers of data. I'm getting back numbers, I'm getting grab text, I'm getting back lists of items. So plum is just so useful if you're looking to get back structured data. A couple of other ideas that I think this would be great for would be something like a AI fitness app where you're trying to say like on this day, and then you have data within that day of, like, the equipment and the reps and. Yeah, basically any structured data that you need from an AI and you're just wanting to test it and iterate it through and maybe add multiple actions together, then I cannot recommend plumb enough because you