Yo! I'm Shawn, an indie maker that derives great joy from shipping something new very quickly. I’ve previously gone from idea to a top ProductHunt launch in single night. Recently, I've been struggling with cold outreach and reaching the right person's inbox.
Writing great cold DMing is an invaluable skill. You have to be concise and provide immediate value to the person you’re messaging. And if you’re like me, messaging someone for the first time always feels awkward af lol.
Come along with me and in an hour or so you’ll have a small web app (or browser extension if you’re feeling ambitious) that’ll generate a starter message that you can then edit and use!
Here’s what it’ll look like:
I was heavily inspired to do this as soon as I finished the AI Writer project. If you haven't checked it out, make sure to join the next kickoff below!
If you have also never worked with GPT-3 before, make sure to check out these notes after you're done reading this!
No experience with AI is necessary - though experience building web apps will definitely help!
Here’s an overview of what we’re gonna do:
Play around in the OpenAI Playground to understand what prompt works best for you.
Generalize and templatize the prompt - identify what part of the prompt will be user input and what will be static.
Build a web app on top of this - UI that takes user input and backend that makes a call to OpenAI’s API and returns the result. (easy-peasy, especially if you’ve worked with React/NextJS before)
Alright, let's get started!
Understanding prompt engineering
Head over to the OpenAI Playground. Sign up for a new OpenAI account if you haven't already. You'll get $18 worth of credits on a new account and then have to pay for more post usage or expiry (your credits will last 3 months).
The playground should like this:
For now, use the default model selected (it’s text-davinci-003 for me). Keep the temperature at 0.7 and change the maximum length to something in the range of 500-600. If you don’t know what any of these mean, don’t worry too much about it right now.
Here’s where the fun starts: think of a person you want to message and a reason why you’re messaging them - I’m going to write to Elon asking him to invest in my (unfortunately fictitious) interstellar space travel company. In the large textbox on the Playground, describe to the model in simple English what you want it to do.
For example, this was mine:
Write a cold message to the person for the specified reason below. Make sure the message is tailored toward the person's experience & skillset. Person: Elon Musk, CEO of SpaceX, Tesla, Twitter Reason: Convince them to fund my company which is building spaceships capable of interstellar travel using warpdrive
Hit Submit. This is what I get. Your output will be somewhat different.
Congrats, you successfully played around with GPT-3 and got it to write your cold DM for you! 🥳
While this is cool, it’s not the most user-friendly interface. What if you want to share this with your friends? We need to build an app on top of this!
If you’re not happy with the output or just want to play around more, do that now! Try other models, temperatures, max lengths and even tweak the prompt until you’re satisfied. Playing around with different prompts is the best way to understand prompt engineering and what all is possible.
🛠
Build in public checkpoint
Let's get more creative!
I’m only mentioning a small description of the person and the reason why you’re messaging them but you can add more specifics.
For example, where they’ve worked previously, their LinkedIn bio etc.
Make sure to increase your max length if your output feels too small or cut off - maximum length also considers input length.
Turning your prompt into a template
Look at your prompt - can you identify parts of that will remain the same no matter who’s using your app and parts that will vary?
Here’s what that would look like for my prompt:
Write a cold message to the person for the specified reason below. Make sure the message is tailored toward the person's experience & skillset.
Person: {{person’s description}}
Reason: {{reason why you’re messaging them}}
I have 2 parts that will vary with each user’s input and the rest will be fixed. If you changed the prompt and added more specifics like LinkedIn bio, you should have more than 2 variable parts.
Once you've identified the template, we’re ready to build! 🔧
Building your slick web app
I’m going to build this in NextJS but feel free to use anything else you’re comfortable with.
Heck, you don’t even have to build a web app - mobile or desktop apps also work (major respect if you’re attempting a Chrome extension instead lol).
Fork and clone locally this repo from the good people at Buildspace.
When quickly shipping something, you don’t need to (and shouldn’t) spend too much time on trivial stuff like setting up a new NextJS project or writing a lot of custom CSS - not at the beginning at least. Focus on building that one killer feature/function and gtfol.
I'm going to assume you know how to set up a repo and familiarity with code editor and basic commands. If you don't, please check out the full project I mentioned in the beginning of this note.
Once you had your repo cloned, open up a terminal and cd into the project directory. Install next, react, and react-dom and then start the development server.
yarn add next react react-dom
yarn dev
You should see this in localhost:3000:
Open up the project directory in an IDE. VSCode is good. Add the code for title, subtitle, inputs, submit button and output area to pages/index.js file.
Also add a function to call an endpoint that we’ll create soon as well as onChange listener functions to the input elements. Your pages/index.js file should look like this:
Create a new folder under pages called api. Inside api, create a new file write.js. We can write our logic for the /api/write endpoint that we’re calling from our frontend code here. NextJS is super cool!
Add the following code to your write.js file. Don’t forget to change the model, temperature and max_tokens values to whatever worked best for you on the Playground.
Now let’s figure out what to set prompt to!
In JavaScript, we can create template strings like this: `static parts here ${variable1} more static part here ${variable2} and so on`. Check the MDN docs if you want to learn more about how these work.
Go to your Playground again and remove any output you had generated and only keep your prompt in the editor. Now click on View Code. Copy the prompt string from the code displayed. You should get \n for each new line in your prompt.
Remember the template we identified earlier? Convert the prompt string you copied into a template string. You can access your input variables from the form submission you made via the frontend via the req.body.
For example, mine would be accessible by req.body.personInput and req.body.reasonInput.
Here’s what my final write.js file looks like with my fancy template string:
Still with me?
Great! But wait, if you were paying attention, you might noticed that there’s a variable that hasn’t been defined yet: process.env.OPENAI_API_KEY
Create a file called .env in your project directory and paste this:
OPENAI_API_KEY=INSERT_YOUR_API_KEY_HERE
You should be able to get this from openAI. I'll let you figure that out.
🚨 Remember to keep your API key safe and secure. Make sure you never commit it to GitHub or share it with anyone else.
If you had the project already running, restart your terminal. Run yarn dev again so NextJS picks up the environment variable.
And voila! You should be done! Head over to localhost:3000 and give your app a spin!
What’s next?
Congratulations, you’ve shipped an app on top of GPT-3! In record time too, I bet! What comes next is… entirely up to you.
Don't have ideas? Here's where you can go next with this:
If you weren’t the biggest fan of a cold DM writer, spin up a completely different app — a movie summary or a new book recommender would be cool!
If you hadn’t played around much with the prompt, try different temperatures, input texts, etc.
Make this a browser extension that automatically pulls a person’s details when you’re DMing them on LinkedIn and injects the generated DM into your message editor for you to tweak before sending.
And get off localhost lol. You don't want to be know as Mr. Localhost. Deploy your project to Vercel, Netlify, Replit or the like. Just get it out there.
Regardless of what you build, I love to see what you make from here.
Looking forward to seeing what you all ship!
Love,
Shawn