<?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: David</title>
    <description>The latest articles on DEV Community by David (@hanson489).</description>
    <link>https://dev.to/hanson489</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3582498%2Fcad8912e-7c9c-40f6-9806-bd0e571f202b.png</url>
      <title>DEV Community: David</title>
      <link>https://dev.to/hanson489</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hanson489"/>
    <language>en</language>
    <item>
      <title>So I Got Tired of Sending Emails All Day... So I Coded This Bot Instead.</title>
      <dc:creator>David</dc:creator>
      <pubDate>Thu, 13 Nov 2025 16:33:59 +0000</pubDate>
      <link>https://dev.to/hanson489/so-i-got-tired-of-sending-emails-all-day-so-i-coded-this-bot-instead-2lm2</link>
      <guid>https://dev.to/hanson489/so-i-got-tired-of-sending-emails-all-day-so-i-coded-this-bot-instead-2lm2</guid>
      <description>&lt;p&gt;Hey folks. Let's be real for a second - how many of you have found yourself stuck in "email hell" when trying to grow your side projects? I sure have.&lt;/p&gt;

&lt;p&gt;Picture this: it's 11 PM, I'm on my third cup of coffee, manually sending the same dang email to different people. I'm a developer, for crying out loud! I automate things for a living, but here I was acting like a human copy-paste machine.&lt;/p&gt;

&lt;p&gt;So I did what any frustrated developer would do - I spent a weekend building something to fire myself from this boring job.&lt;br&gt;
What This Thing Actually Does&lt;/p&gt;

&lt;p&gt;Basically, I wanted a simple bot that could:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Remember who I've emailed and who I haven't

Send follow-ups automatically (because I always forget)

Not mess up people's names or links

Let me sleep while it works
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The Tools I Grabbed&lt;/p&gt;

&lt;p&gt;I went with Node.js because, well, it's what I know best. Plus, the whole async thing is perfect for "hey, go send these emails and don't bother me while you're at it."&lt;/p&gt;

&lt;p&gt;For actually sending emails, I used SendGrid. Their free tier is generous, and let's be honest - I don't want to deal with email deliverability drama. They handle all that SPF/DKIM nonsense that makes my head hurt.&lt;/p&gt;

&lt;p&gt;And for storing data? I kept it stupid simple - just a JSON file. Yeah, I know, not exactly production-ready, but this is a prototype, people!&lt;br&gt;
Here's the Actual Code I Wrote&lt;/p&gt;

&lt;p&gt;First, the boring setup stuff:&lt;br&gt;
bash&lt;/p&gt;

&lt;h1&gt;
  
  
  Seriously, that's it for packages
&lt;/h1&gt;

&lt;p&gt;npm init -y&lt;br&gt;
npm install @sendgrid/mail&lt;/p&gt;

&lt;p&gt;Now for the "database" - and I use that term loosely:&lt;br&gt;
javascript&lt;/p&gt;

&lt;p&gt;// leads.json - it's just an array of people&lt;br&gt;
[&lt;br&gt;
  {&lt;br&gt;
    "id": 1,&lt;br&gt;
    "email": "&lt;a href="mailto:someone@example.com"&gt;someone@example.com&lt;/a&gt;",&lt;br&gt;
    "firstName": "Alex",&lt;br&gt;
    "status": "new",&lt;br&gt;
    "myCoolAffiliateLink": "&lt;a href="https://example.com/alex" rel="noopener noreferrer"&gt;https://example.com/alex&lt;/a&gt;"&lt;br&gt;
  },&lt;br&gt;
  {&lt;br&gt;
    "id": 2, &lt;br&gt;
    "email": "&lt;a href="mailto:anotherperson@website.com"&gt;anotherperson@website.com&lt;/a&gt;",&lt;br&gt;
    "firstName": "Taylor",&lt;br&gt;
    "status": "waiting_for_reply",&lt;br&gt;
    "myCoolAffiliateLink": "&lt;a href="https://example.com/taylor" rel="noopener noreferrer"&gt;https://example.com/taylor&lt;/a&gt;"&lt;br&gt;
  }&lt;br&gt;
]&lt;/p&gt;

&lt;p&gt;The email templates live in their own file:&lt;br&gt;
javascript&lt;/p&gt;

&lt;p&gt;// emails.js&lt;br&gt;
const emails = {&lt;br&gt;
  firstEmail: {&lt;br&gt;
    subject: "Hey {{firstName}}, thought you might like this",&lt;br&gt;
    body: `&lt;/p&gt;

&lt;p&gt;Hi {{firstName}},&lt;/p&gt;

&lt;p&gt;Stumbled across this resource and your name immediately popped into my head.&lt;/p&gt;

&lt;p&gt;Figured I'd share: &lt;a href="{{myCoolAffiliateLink}}"&gt;check it out here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Your Name&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;},&lt;/p&gt;

&lt;p&gt;followUp: {&lt;br&gt;
    subject: "Just following up",&lt;br&gt;
    body: `&lt;/p&gt;

&lt;p&gt;Hey {{firstName}},&lt;/p&gt;

&lt;p&gt;Circling back on my previous email - did you get a chance to look?&lt;/p&gt;

&lt;p&gt;Here's that link again: &lt;a href="{{myCoolAffiliateLink}}"&gt;{{myCoolAffiliateLink}}&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;module.exports = emails;&lt;/p&gt;

&lt;p&gt;And here's the main event - the actual bot:&lt;br&gt;
javascript&lt;/p&gt;

&lt;p&gt;const sgMail = require('@sendgrid/mail');&lt;br&gt;
const people = require('./leads.json');&lt;br&gt;
const emailTemplates = require('./emails.js');&lt;/p&gt;

&lt;p&gt;// Pro tip: Keep your API key out of the code!&lt;br&gt;
sgMail.setApiKey(process.env.SENDGRID_API_KEY);&lt;/p&gt;

&lt;p&gt;async function sendEmail(person, whichEmail) {&lt;br&gt;
  let subject = whichEmail.subject;&lt;br&gt;
  let body = whichEmail.body;&lt;/p&gt;

&lt;p&gt;// This replaces {{firstName}} with actual names, etc&lt;br&gt;
  Object.keys(person).forEach(key =&amp;gt; {&lt;br&gt;
    subject = subject.replace(&lt;code&gt;{{${key}}}&lt;/code&gt;, person[key]);&lt;br&gt;
    body = body.replace(&lt;code&gt;{{${key}}}&lt;/code&gt;, person[key]);&lt;br&gt;
  });&lt;/p&gt;

&lt;p&gt;const email = {&lt;br&gt;
    to: person.email,&lt;br&gt;
    from: '&lt;a href="mailto:you@yourdomain.com"&gt;you@yourdomain.com&lt;/a&gt;', // Use a verified email!&lt;br&gt;
    subject: subject,&lt;br&gt;
    html: body,&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
    await sgMail.send(email);&lt;br&gt;
    console.log(&lt;code&gt;✓ Email sent to ${person.email}&lt;/code&gt;);&lt;br&gt;
    return true;&lt;br&gt;
  } catch (error) {&lt;br&gt;
    console.log(&lt;code&gt;✗ Failed for ${person.email}:&lt;/code&gt;, error.message);&lt;br&gt;
    return false;&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;async function run() {&lt;br&gt;
  for (const person of people) {&lt;br&gt;
    let whichTemplate = null;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (person.status === 'new') {
  whichTemplate = emailTemplates.firstEmail;
} else if (person.status === 'waiting_for_reply') {
  whichTemplate = emailTemplates.followUp;
}

if (whichTemplate) {
  const worked = await sendEmail(person, whichTemplate);
  if (worked) {
    console.log(`Updated ${person.firstName}'s status`);
    // Here you'd update their status in a real database
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;run();&lt;/p&gt;

&lt;p&gt;How to Make This Thing Actually Work&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get a SendGrid account (it's free to start)

Verify your email so you can actually send stuff

Set your API key: export SENDGRID_API_KEY='your_key_here'

Run it: node mailbot.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Was It Worth It?&lt;/p&gt;

&lt;p&gt;Honestly? Yeah. That weekend of coding saved me hours each week. The bot never forgets to follow up, never sends an email to the wrong person, and works while I'm asleep.&lt;/p&gt;

&lt;p&gt;Is this ready for a Fortune 500 company? Absolutely not. But for my side projects? It's perfect.&lt;br&gt;
Where I'd Take This Next&lt;/p&gt;

&lt;p&gt;If I were to make this more robust, I'd probably:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add a proper database (maybe SQLite to start)

Put a simple web interface on it

Handle bounce backs and unsubscribes properly

Add some basic analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But for now? It works, and that's what matters.&lt;/p&gt;

&lt;p&gt;What about you? Ever built something to automate your own grunt work? I'd love to hear about it in the comments!&lt;/p&gt;

</description>
      <category>node</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
