<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lawrence</title>
    <description>The latest articles on DEV Community by Lawrence (@aidevoter).</description>
    <link>https://dev.to/aidevoter</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4169360%2F72d1c34c-6143-4d7b-ace3-65abcdb4a8da.png</url>
      <title>DEV Community: Lawrence</title>
      <link>https://dev.to/aidevoter</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aidevoter"/>
    <language>en</language>
    <item>
      <title>How I Built a Cold Email Script That Personalizes Every Message (With Code)</title>
      <dc:creator>Lawrence</dc:creator>
      <pubDate>Wed, 07 Oct 2026 16:15:32 +0000</pubDate>
      <link>https://dev.to/aidevoter/how-i-built-a-cold-email-script-that-personalizes-every-message-with-code-46bd</link>
      <guid>https://dev.to/aidevoter/how-i-built-a-cold-email-script-that-personalizes-every-message-with-code-46bd</guid>
      <description>&lt;p&gt;I'm a university student in Hong Kong. I spent two hours writing cold emails last week — between classes and assignments — trying to land some freelance clients. Every single one started with "Hi [FirstName], I hope you're doing well."&lt;/p&gt;

&lt;p&gt;I sent 40. I got zero replies.&lt;/p&gt;

&lt;p&gt;The problem wasn't the offer. It was that every email was obviously templated. You could smell it from the first line. And the people I was emailing — marketing directors, founders — get 50 of those a day.&lt;/p&gt;

&lt;p&gt;So I built a script to fix it. Here's how it works, and the code behind it.&lt;/p&gt;

&lt;p&gt;The Problem With Mail Merge&lt;/p&gt;

&lt;p&gt;Standard mail merge replaces [FirstName] with the actual name. That's not personalization. That's a template with a name plugged in.&lt;/p&gt;

&lt;p&gt;Real personalization means referencing something specific about the person or their company. Something that proves you actually looked.&lt;/p&gt;

&lt;p&gt;But doing that manually for 100 prospects takes 8-10 hours. As a student with a part-time schedule, I don't have that kind of time.&lt;/p&gt;

&lt;p&gt;The Solution: One Hook Per Prospect&lt;/p&gt;

&lt;p&gt;The script works on a simple premise: you give it one specific hook for each prospect, and it writes the rest.&lt;/p&gt;

&lt;p&gt;Here's what the input looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name,role,company,email,hook
Jane Smith,Marketing Director,Acme Corp,jane@acmecorp.com,Acme just launched a new eco-friendly product line and is hiring 3 marketing roles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That hook column is the key. It's the one piece of information that proves you did your homework. The script takes that hook and writes an email that references it naturally.&lt;/p&gt;

&lt;p&gt;The Code&lt;/p&gt;

&lt;p&gt;The core of the script is a single function that calls an AI model with a structured prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Write a short, personalized cold email.

Recipient: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Personalization hook: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Rules:
- Keep it under 120 words
- Professional but conversational
- Reference the hook naturally
- End with a soft call to action
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a cold email copywriter.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rest of the script is just CSV reading and writing. No complex infrastructure. No database. Just a loop.&lt;/p&gt;

&lt;p&gt;What the Output Looks Like&lt;/p&gt;

&lt;p&gt;Here's a real output generated from the hook above:&lt;/p&gt;

&lt;p&gt;Subject: Quick thought on Acme's eco-friendly launch&lt;/p&gt;

&lt;p&gt;Hi Jane,&lt;/p&gt;

&lt;p&gt;I saw Acme just launched a new eco-friendly product line and is hiring 3 marketing roles. That combination usually means the team is stretched thin on content and campaign execution.&lt;/p&gt;

&lt;p&gt;I help marketing teams automate personalized outreach so they can focus on strategy, not manual work. Worth a 15-minute chat?&lt;/p&gt;

&lt;p&gt;Best,&lt;br&gt;
[Your Name]&lt;/p&gt;

&lt;p&gt;It's not perfect. It's not a human copywriter. But it's specific, it's fast, and it doesn't sound like a template.&lt;/p&gt;

&lt;p&gt;The One Thing I'd Do Differently&lt;/p&gt;

&lt;p&gt;The hook column is everything. If you write a generic hook like "great company," the AI will write a generic email. The quality of the output is directly proportional to the quality of the input.&lt;/p&gt;

&lt;p&gt;The second thing: don't let the script send emails. It only generates them. You review the output and send from your own inbox. This protects your domain reputation and keeps you in control of what goes out.&lt;/p&gt;

&lt;p&gt;What I Learned&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Personalization is about specific signals, not names. The hook matters more than the template.&lt;/li&gt;
&lt;li&gt;Prompt engineering is mostly about constraints. "Under 120 words" and "reference the hook naturally" do more work than any clever instruction.&lt;/li&gt;
&lt;li&gt;Keep the scope narrow. This script does one thing. It doesn't scrape leads. It doesn't send emails. It writes them. That's it.&lt;/li&gt;
&lt;li&gt;Building something small is the fastest way to learn. As a student, I don't have the resources to build a full SaaS. But a single Python script? That I can do in a weekend.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If You Want to Skip the Build&lt;/p&gt;

&lt;p&gt;I packaged the full script with a README, a CSV template, and a setup guide. You can see the output quality in a free sample pack first.&lt;/p&gt;

&lt;p&gt;Free sample pack (3 example emails): &lt;a href="https://wealthaccumulator.gumroad.com/l/yhwke" rel="noopener noreferrer"&gt;https://wealthaccumulator.gumroad.com/l/yhwke&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full script ($29): &lt;a href="https://wealthaccumulator.gumroad.com/l/ovdfpv" rel="noopener noreferrer"&gt;https://wealthaccumulator.gumroad.com/l/ovdfpv&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It takes about 5 minutes to set up. You'll need Python and an OpenAI API key.&lt;/p&gt;

&lt;p&gt;If you have questions about the prompt structure or want to adapt it for your own use case, drop a comment. I'm happy to share what worked and what didn't.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>freelance</category>
      <category>python</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
