<?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: Himanshu Goswami</title>
    <description>The latest articles on DEV Community by Himanshu Goswami (@himanshu_goswami_0bfd3869).</description>
    <link>https://dev.to/himanshu_goswami_0bfd3869</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%2F3873775%2Fec3b2c39-c9e2-4260-9af1-d78488ec6a71.jpg</url>
      <title>DEV Community: Himanshu Goswami</title>
      <link>https://dev.to/himanshu_goswami_0bfd3869</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/himanshu_goswami_0bfd3869"/>
    <language>en</language>
    <item>
      <title>How I Built a Personalized Funding Newsletter That Sends Every Subscriber a Different Email</title>
      <dc:creator>Himanshu Goswami</dc:creator>
      <pubDate>Sat, 11 Apr 2026 16:54:03 +0000</pubDate>
      <link>https://dev.to/himanshu_goswami_0bfd3869/how-i-built-a-personalized-funding-newsletter-that-sends-every-subscriber-a-different-email-1eb3</link>
      <guid>https://dev.to/himanshu_goswami_0bfd3869/how-i-built-a-personalized-funding-newsletter-that-sends-every-subscriber-a-different-email-1eb3</guid>
      <description>&lt;p&gt;Most newsletters are one-to-many: one piece of content, broadcast to everyone. I wanted to build something different — a newsletter where every single subscriber receives a different set of recommendations based on their profile.&lt;/p&gt;

&lt;p&gt;Here's how I built it with Next.js, Supabase, and Gemini.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.startup911.in" rel="noopener noreferrer"&gt;Startup911&lt;/a&gt; is a funding discovery platform for founders, students, and researchers. Users sign up through a detailed questionnaire — their role, the types of opportunities they want (grants, fellowships, accelerators), their target regions, and their sector tags (AI, climate, health, fintech, etc.).&lt;/p&gt;

&lt;p&gt;The stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js 14 (App Router) deployed on Vercel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; Supabase (PostgreSQL) for subscribers, opportunities, and content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Gemini 2.5 Flash for content enrichment and generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email delivery:&lt;/strong&gt; Custom send pipeline matching subscriber profiles to opportunity tags&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Ingestion pipeline
&lt;/h3&gt;

&lt;p&gt;Opportunities come from multiple sources — RSS feeds from grant-making organizations, government portals, foundation websites, and manual submissions. I built a set of admin API routes that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fetch&lt;/strong&gt; new opportunities from configured RSS sources (&lt;code&gt;/api/admin/fetch-rss&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enrich&lt;/strong&gt; them using Gemini — extracting structured fields like eligibility criteria, funding amount, deadline, regions, and sectors (&lt;code&gt;/api/admin/enrich-opportunities&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approve&lt;/strong&gt; them into a newsletter-ready pool&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The enrichment step is crucial. Raw RSS data is messy — a grant title might say "Innovation Fund for Early-Career Researchers" but not explicitly state the funding amount, geographic restrictions, or whether it's for individuals or organizations. Gemini reads the source page content and extracts this into structured JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Profile-based matching
&lt;/h3&gt;

&lt;p&gt;Every subscriber has a profile stored in Supabase with their selected tags — think of it as a set of interests (e.g., &lt;code&gt;["climate-tech", "africa", "pre-seed", "grant"]&lt;/code&gt;). When it's time to send, the matching logic scores each opportunity against each subscriber's tag set and assembles a personalized email.&lt;/p&gt;

&lt;p&gt;The scoring is straightforward: overlap between the opportunity's enriched tags and the subscriber's profile tags, weighted by how specific the match is. A &lt;code&gt;climate-tech&lt;/code&gt; + &lt;code&gt;africa&lt;/code&gt; match is more valuable than a generic &lt;code&gt;grant&lt;/code&gt; match.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Decision guides (the SEO layer)
&lt;/h3&gt;

&lt;p&gt;Beyond the newsletter, I wanted the enriched opportunity data to serve a second purpose — SEO. For each high-quality opportunity in the pipeline, I built a one-click "generate page" flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/admin/generate-opportunity-page
Body: { "opportunity_id": "&amp;lt;uuid&amp;gt;" }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This calls Gemini with the enriched opportunity data and generates a structured decision guide: who the program is for, who it's not for, what selectors look for, key facts, FAQs, and an editorial "should you apply?" take. The output is stored as a JSON in &lt;code&gt;opportunity_pages&lt;/code&gt; with &lt;code&gt;status: draft&lt;/code&gt; and &lt;code&gt;index_status: noindex&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I review the draft, edit if needed, then publish and flip to &lt;code&gt;index&lt;/code&gt; — at which point it appears on the public &lt;a href="https://www.startup911.in/opportunities" rel="noopener noreferrer"&gt;/opportunities&lt;/a&gt; page and enters the sitemap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Programmatic blog posts
&lt;/h3&gt;

&lt;p&gt;I also built a blog generator that creates "Top 10" listicle posts from the same enriched data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/admin/generate-blog
Body: { "topic": "AI Startup Grants", "time_period": "April 2026" }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gemini generates structured JSON with 10 opportunity cards (program name, organization, funding amount, deadline, summary) plus editorial content. The output includes a &lt;code&gt;structured_items&lt;/code&gt; array that the blog template renders as interactive cards — each with a "Read Full Guide" link to the decision guide (when one exists) and a direct "Apply" button.&lt;/p&gt;

&lt;h3&gt;
  
  
  The tech decisions I'd make differently
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Slug generation was a mess at first.&lt;/strong&gt; My auto-generated slugs looked like &lt;code&gt;the-atlantic-fellows-for-healt-the-atlantic-fellows-for-health-equity-fellowship--2026&lt;/code&gt;. I've since cleaned up the generator, but the early slugs were embarrassing. Lesson: think about your URL structure before you have 30 pages indexed in Google.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I should have used structured JSON from day one&lt;/strong&gt; instead of asking Gemini to output markdown and then parsing it with regex. The structured &lt;code&gt;items[]&lt;/code&gt; approach I'm using now is much more reliable for rendering cards, generating JSON-LD schema, and cross-linking between content types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supabase RLS (Row Level Security) matters.&lt;/strong&gt; My early API routes didn't have proper RLS policies, which meant the admin endpoints were more exposed than they should have been. Lock this down before you have real users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Results so far
&lt;/h3&gt;

&lt;p&gt;It's early — the site is about a year old. We have ~175 newsletter subscribers, around 50% of which came from organic channels (Google search + ChatGPT referrals, which is an interesting signal for AI-era SEO). Google has indexed 191 pages, and we're getting around 6,500 impressions/month with a 0.6% CTR.&lt;/p&gt;

&lt;p&gt;The AI referral traffic is the most surprising part. About 10-15% of our non-direct traffic comes from chatgpt.com and Bing (which feeds Copilot). The structured, fact-heavy format of our decision guides — with explicit eligibility criteria, deadlines, and FAQs — seems to be exactly what LLMs want to cite.&lt;/p&gt;

&lt;p&gt;If you're building content sites in 2026, optimizing for AI answer engines (AEO) alongside traditional SEO isn't optional anymore. Structure your content with clear facts, use FAQ schema, and make your key data points extractable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it
&lt;/h3&gt;

&lt;p&gt;If you work with founders or know people looking for grants/fellowships, &lt;a href="https://www.startup911.in/newsletter" rel="noopener noreferrer"&gt;Startup911's newsletter&lt;/a&gt; is free. Every subscriber gets different recommendations based on their profile.&lt;/p&gt;

&lt;p&gt;The code patterns I described here — RSS ingestion, AI enrichment, profile-based matching, and programmatic content generation — are applicable to any domain where you need to match structured data to user preferences at scale. Happy to answer questions in the comments.&lt;/p&gt;

</description>
      <category>hackathon</category>
      <category>webdev</category>
      <category>ai</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
