<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Somesh Bhardwaj]]></title><description><![CDATA[Somesh Bhardwaj]]></description><link>https://blog.someshbhardwaj.me</link><generator>RSS for Node</generator><lastBuildDate>Tue, 28 Apr 2026 04:02:27 GMT</lastBuildDate><atom:link href="https://blog.someshbhardwaj.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[🚀 Case Study: Solving the “Context Gap” in Team Communication]]></title><description><![CDATA[In fast-moving teams, important conversations often get lost — especially when they reference sensitive topics like finance indirectly.
Someone might say:

"Can we loop in the finance team here?"

But]]></description><link>https://blog.someshbhardwaj.me/case-study-solving-the-context-gap-in-team-communication</link><guid isPermaLink="true">https://blog.someshbhardwaj.me/case-study-solving-the-context-gap-in-team-communication</guid><dc:creator><![CDATA[Er Somesh Bhardwaj]]></dc:creator><pubDate>Tue, 17 Mar 2026 17:09:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/9b413c73-83a0-4fef-a434-3721f1680b05.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In fast-moving teams, important conversations often get lost — especially when they reference sensitive topics like finance indirectly.</p>
<p>Someone might say:</p>
<blockquote>
<p>"Can we loop in the finance team here?"</p>
</blockquote>
<p>But never actually tag the finance channel.</p>
<p>That’s where problems begin.</p>
<hr />
<h1>🧠 The Problem</h1>
<p>In a growing Slack workspace:</p>
<ul>
<li><p>Conversations happen across multiple channels</p>
</li>
<li><p>Teams reference other teams without tagging them</p>
</li>
<li><p>Critical finance-related discussions can go unnoticed</p>
</li>
</ul>
<p>This creates:</p>
<ul>
<li><p>Missed dependencies</p>
</li>
<li><p>Delayed responses</p>
</li>
<li><p>Lack of governance visibility</p>
</li>
</ul>
<p>I wanted to build a <strong>proactive system</strong> instead of relying on manual tracking.</p>
<hr />
<h1>💡 The Solution</h1>
<p>I built an <strong>Automated Governance &amp; Finance Mention Bot</strong>.</p>
<h3>What it does:</h3>
<ul>
<li><p>Monitors messages across the entire Slack workspace</p>
</li>
<li><p>Detects indirect mentions of finance-related channels</p>
</li>
<li><p>Extracts context from the message</p>
</li>
<li><p>Cross-posts relevant insights to a governance channel</p>
</li>
</ul>
<p>👉 Result: No important finance conversation goes unnoticed.</p>
<hr />
<h1>🏗 System Architecture</h1>
<h3>Core Stack</h3>
<ul>
<li><p><strong>TypeScript + Node.js</strong></p>
</li>
<li><p><strong>Slack Bolt SDK</strong></p>
</li>
<li><p><strong>Slack Web API</strong></p>
</li>
<li><p><strong>Render (PaaS)</strong></p>
</li>
<li><p><strong>GitHub (CI/CD)</strong></p>
</li>
</ul>
<hr />
<h2>⚙️ How It Works</h2>
<h3>1. Event-Driven Processing</h3>
<p>The bot listens to Slack events in real time:</p>
<ul>
<li><p><code>message</code> events</p>
</li>
<li><p><code>channel_created</code> events</p>
</li>
</ul>
<p>Using Slack’s <strong>Socket Mode</strong>, it processes messages asynchronously.</p>
<hr />
<h3>2. Context Extraction (The Core Logic)</h3>
<p>Slack messages are not plain text.</p>
<p>Channel mentions look like this:</p>
<pre><code class="language-plaintext">&lt;#C123456789&gt;
</code></pre>
<p>So I implemented:</p>
<ul>
<li><p>Regex-based parsing</p>
</li>
<li><p>Mapping of channel IDs → actual meaning</p>
</li>
<li><p>Detection of indirect references</p>
</li>
</ul>
<p>This allows the bot to <strong>understand intent</strong>, not just keywords.</p>
<hr />
<h3>3. Auto-Join Mechanism (Zero Config)</h3>
<p>Instead of manually adding the bot to channels:</p>
<ul>
<li><p>It fetches all public channels via Slack API</p>
</li>
<li><p>Automatically joins them</p>
</li>
<li><p>Listens to new channels as they are created</p>
</li>
</ul>
<p>👉 This makes the system <strong>self-scaling with zero manual setup</strong></p>
<hr />
<h3>4. Governance Routing</h3>
<p>When a relevant mention is detected:</p>
<ul>
<li><p>Extract message context</p>
</li>
<li><p>Identify related channels</p>
</li>
<li><p>Send structured alert to governance channel</p>
</li>
</ul>
<hr />
<h1>🚧 The Real Challenge (Render Constraint)</h1>
<p>Here’s where it got interesting.</p>
<h3>Problem:</h3>
<ul>
<li><p>Slack Socket Mode does NOT require an HTTP server</p>
</li>
<li><p>But Render requires a service to listen on a port</p>
</li>
</ul>
<h3>Solution:</h3>
<p>I built a <strong>sidecar HTTP health-check server</strong> inside the same app.</p>
<pre><code class="language-ts">import express from "express";

const app = express();

app.get("/", (req, res) =&gt; {
  res.send("Bot is running");
});

app.listen(process.env.PORT || 3000);
</code></pre>
<p>👉 This allowed:</p>
<ul>
<li><p>Render to keep the service alive</p>
</li>
<li><p>Slack bot to run independently via Socket Mode</p>
</li>
</ul>
<p>This was a <strong>small but critical DevOps workaround</strong></p>
<hr />
<h1>🔐 Security &amp; Permissions</h1>
<p>Handled Slack API scopes carefully:</p>
<ul>
<li><p><code>channels:join</code></p>
</li>
<li><p><code>channels:history</code></p>
</li>
<li><p><code>chat:write</code></p>
</li>
</ul>
<p>Ensured:</p>
<ul>
<li><p>No user impersonation</p>
</li>
<li><p>Controlled access to sensitive discussions</p>
</li>
</ul>
<hr />
<h1>⚙️ Deployment &amp; DevOps</h1>
<ul>
<li><p>Environment management using <code>.env</code></p>
</li>
<li><p>CI/CD via GitHub → Render</p>
</li>
<li><p>Free-tier uptime optimization</p>
</li>
</ul>
<hr />
<h1>📊 Impact</h1>
<ul>
<li><p>Monitors <strong>100% of public Slack channels</strong></p>
</li>
<li><p>Eliminates missed finance dependencies</p>
</li>
<li><p>Reduces manual oversight effort</p>
</li>
<li><p>Creates a <strong>central governance visibility layer</strong></p>
</li>
</ul>
<hr />
<h1>💡 Key Learnings</h1>
<h3>1. Event-Driven Systems Are Powerful</h3>
<p>Handling real-time streams changes how systems react and scale.</p>
<hr />
<h3>2. Context &gt; Keywords</h3>
<p>Understanding structured data inside messages is far more powerful than simple keyword matching.</p>
<hr />
<h3>3. Constraints Drive Innovation</h3>
<p>The Render workaround forced a creative solution that improved system robustness.</p>
<hr />
<h3>4. Automation Should Be Invisible</h3>
<p>The best systems:</p>
<ul>
<li><p>Require zero configuration</p>
</li>
<li><p>Adapt automatically</p>
</li>
<li><p>Work silently in the background</p>
</li>
</ul>
<hr />
<h1>🚀 What’s Next</h1>
<p>This is just the beginning.</p>
<p>Future improvements:</p>
<ul>
<li><p>AI-based semantic detection (not just regex)</p>
</li>
<li><p>Multi-channel governance workflows</p>
</li>
<li><p>Ticket creation + task assignment (Asana / Jira integration)</p>
</li>
<li><p>Slack → Calendar → OKR linking</p>
</li>
</ul>
<hr />
<h1>🧠 Final Thought</h1>
<p>This project is not just a bot.</p>
<p>It’s a <strong>step toward building autonomous operational systems</strong> that reduce human friction and increase organizational clarity.</p>
<hr />
<p>If you're building something similar or exploring automation systems, would love to connect and exchange ideas.</p>
<hr />
<h1>🧩 Architecture Diagram</h1>
<p>Below is a simple architecture diagram using Mermaid (supported on many platforms including Hashnode):</p>
<pre><code class="language-mermaid">graph TD
    A[Slack Workspace] --&gt;|Events: message, channel_created| B[Slack Bolt App]
    B --&gt; C[Event Processor]
    C --&gt; D[Regex Engine / Context Parser]
    D --&gt; E[Channel Mapping Logic]
    E --&gt; F[Governance Decision Layer]
    F --&gt; G[Governance Channel Notification]

    B --&gt; H[Auto Join Service]
    H --&gt; A

    B --&gt; I[HTTP Health Check Server]
    I --&gt; J[Render PaaS]

    K[GitHub CI/CD] --&gt; J
</code></pre>
<hr />
<h1>🔍 Architecture Breakdown</h1>
<ul>
<li><p><strong>Slack Workspace</strong> → Source of real-time events</p>
</li>
<li><p><strong>Slack Bolt App</strong> → Entry point handling Socket Mode connections</p>
</li>
<li><p><strong>Event Processor</strong> → Filters and routes incoming events</p>
</li>
<li><p><strong>Regex Engine</strong> → Extracts structured data from messages</p>
</li>
<li><p><strong>Channel Mapping Logic</strong> → Resolves Slack IDs to meaningful context</p>
</li>
<li><p><strong>Governance Layer</strong> → Decides whether to trigger alerts</p>
</li>
<li><p><strong>Auto Join Service</strong> → Ensures bot coverage across all channels</p>
</li>
<li><p><strong>HTTP Health Server</strong> → Keeps Render deployment alive</p>
</li>
<li><p><strong>CI/CD (GitHub)</strong> → Automates deployment lifecycle</p>
</li>
</ul>
<hr />
<h1>🎯 Visual Tip for Hashnode</h1>
<ul>
<li><p>Place the cover image at the very top of the blog</p>
</li>
<li><p>Place the architecture diagram right after "System Architecture" section</p>
</li>
<li><p>Keep diagrams clean, avoid clutter</p>
</li>
</ul>
<hr />
]]></content:encoded></item><item><title><![CDATA[Building an AI-Powered Portfolio with React 19, Vite, and Gemini 2.5 Flash]]></title><description><![CDATA[As developers, our portfolio is often the first impression we make. Instead of just listing my skills and projects, I wanted visitors to experience what I can build. That's why I decided to rebuild my]]></description><link>https://blog.someshbhardwaj.me/building-an-ai-powered-portfolio-with-react-19-vite-and-gemini-2-5-flash</link><guid isPermaLink="true">https://blog.someshbhardwaj.me/building-an-ai-powered-portfolio-with-react-19-vite-and-gemini-2-5-flash</guid><dc:creator><![CDATA[Er Somesh Bhardwaj]]></dc:creator><pubDate>Fri, 13 Mar 2026 11:23:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/53ecc8e4-cb34-4480-878c-ab85df8d4611.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As developers, our portfolio is often the first impression we make. Instead of just listing my skills and projects, I wanted visitors to <strong>experience</strong> what I can build. That's why I decided to rebuild my portfolio as an AI-powered interactive web experience.</p>
<p>In this post, I'll walk you through how I built my new high-performance portfolio using <strong>React 19</strong>, <strong>Vite</strong>, <strong>Tailwind CSS 4</strong>, and the incredible <strong>Google Gemini 2.5 Flash</strong> model. </p>
<h2>The Vision: More Than Just a Website</h2>
<p>My goal was to create a site that was not only fast and accessible but also highly interactive. I wanted an AI assistant that could:</p>
<ol>
<li>Answer questions about my experience and skills.</li>
<li>Control the UI (e.g., scroll to specific sections, filter projects, or toggle themes).</li>
<li>Act as an intelligent lead-capture tool.</li>
</ol>
<h2>The Tech Stack</h2>
<p>I chose a stack optimized for speed and developer experience:</p>
<ul>
<li><strong>Frontend Framework:</strong> React 19 &amp; Vite </li>
<li><strong>Styling:</strong> Tailwind CSS 4 with custom CSS and glassmorphism design.</li>
<li><strong>AI Integration:</strong> Google Gemini 2.5 Flash (via API) &amp; <code>react-markdown</code> for formatting.</li>
<li><strong>Visualizations:</strong> Recharts &amp; custom SVGs for interactive skill radars.</li>
<li><strong>Deployment:</strong> Netlify (Functions + CDN) to securely handle API keys.</li>
</ul>
<h2>Integrating Google Gemini for Function Calling</h2>
<p>The standout feature of this portfolio is the <strong>AI Chatbot</strong>. Instead of just returning text, the chatbot utilizes <strong>Function Calling</strong>. </p>
<p>When a user asks, <em>"Show me your web development projects"</em>, or <em>"Switch to dark mode"</em>, Gemini processes the intent. Using predefined tools, it returns a structured JSON response to call a specific frontend function. </p>
<p>Here is a simplified look at how I implemented this:</p>
<pre><code class="language-typescript">// Defining the tool schema for Gemini
const tools = [
  {
    name: "filterProjects",
    description: "Filters the project gallery based on the user's request.",
    parameters: {
      type: "object",
      properties: {
        category: { type: "string" }
      }
    }
  },
  {
    name: "scrollToSection",
    description: "Scrolls the page to a specific section like 'Experience' or 'Contact'."
  }
];
</code></pre>
<p>When the frontend receives this tool invocation, it triggers the necessary React state changes to filter the project gallery smoothly.</p>
<h2>Dynamic UI and Animations</h2>
<p>A chatbot is cool, but the aesthetics matter. I incorporated:</p>
<ul>
<li><strong>Time-based ambient backgrounds</strong> that subtly shift colors.</li>
<li><strong>Glassmorphism design</strong> featuring backdrop blurs to keep text readable over dynamic elements.</li>
<li><strong>Scroll Spy Navigation</strong> and staggered animations using intersection observers.</li>
</ul>
<p>All of this was achieved while maintaining <strong>WCAG 2.1 AA compliance</strong>. Accessibility shouldn't be an afterthought, even heavily customized UIs need screen-reader optimizations and keyboard navigation support.</p>
<h2>Content Management Architecture</h2>
<p>One of the best developer decisions I made was centralizing all the content into a single <code>constants.ts</code> file:</p>
<pre><code class="language-typescript">export const PROJECTS = [...];
export const EXPERIENCE = [...];
export const SKILL_CATEGORIES = [...];
</code></pre>
<p>Instead of hunting down specific components to update my resume or add a new project, I simply modify the data object. The entire UI trickles down from these constants, making the portfolio incredibly maintainable.</p>
<h2>What's Next?</h2>
<p>The portfolio is live, but software is never really "finished." My roadmap includes:</p>
<ul>
<li>Migrating the server-side chatbot logic to <strong>n8n</strong> for more complex workflow automation.</li>
<li>Enhancing lead capture directly into Google Sheets using Apps Script (already underway!).</li>
<li>Expanding end-to-end testing with Playwright.</li>
</ul>
<p>Building this was a fantastic journey merging modern frontend performance with cutting-edge AI integrations. If you're looking to stand out, I highly recommend finding creative ways to weave LLMs into your personal projects.</p>
<p><em>Feel free to explore the code on my <a href="https://github.com/Dev-Somesh/Somesh-Bhardwaj-Portfolio-Ai-Chatbot">GitHub</a> or chat with the AI on my live portfolio at <a href="https://someshbhardwaj.me">someshbhardwaj.me</a>!</em></p>
]]></content:encoded></item><item><title><![CDATA[How to Build an AI Portfolio Chatbot with Tool Calling (Gemini + Netlify)]]></title><description><![CDATA[How to Build an AI Portfolio Chatbot with Tool Calling (Gemini + Netlify)
A portfolio that can answer questions, control the page, and capture leads—without exposing your API key—is within reach with ]]></description><link>https://blog.someshbhardwaj.me/how-to-build-an-ai-portfolio-chatbot-with-tool-calling-gemini-netlify</link><guid isPermaLink="true">https://blog.someshbhardwaj.me/how-to-build-an-ai-portfolio-chatbot-with-tool-calling-gemini-netlify</guid><dc:creator><![CDATA[Er Somesh Bhardwaj]]></dc:creator><pubDate>Thu, 12 Mar 2026 10:51:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/87ec4821-b064-4621-9ca4-e63db7609db4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>How to Build an AI Portfolio Chatbot with Tool Calling (Gemini + Netlify)</h1>
<p>A portfolio that can answer questions, control the page, and capture leads—without exposing your API key—is within reach with a single LLM and a serverless function.</p>
<p>This post walks through how to add an <strong>AI chatbot with tool calling</strong> to your portfolio: we’ll use <strong>Google Gemini</strong> for the model, <strong>Netlify Functions</strong> to keep the API key server-side, and <strong>React</strong> on the front end. By the end, you’ll have a chatbot that can scroll to sections, toggle theme, filter projects, and collect leads via a webhook.</p>
<hr />
<h1>Why Add an AI Chatbot to Your Portfolio?</h1>
<p>A static “Contact” form is fine. An AI agent that knows your skills, projects, and case studies is better.</p>
<p><strong>Benefits:</strong></p>
<p>• <strong>Differentiation</strong> — Few portfolios offer a conversational, context-aware assistant.<br />• <strong>Engagement</strong> — Visitors can ask “What’s his experience with n8n?” or “Show automation work” and get direct answers.<br />• <strong>Lead capture</strong> — When someone says “I want to hire you,” the agent can collect name, email, budget, and timeline in a natural flow and send them to your CRM or sheet.<br />• <strong>Learning</strong> — You get hands-on practice with LLM APIs, function calling, and serverless security.</p>
<p>The catch: you must keep your <strong>API key off the client</strong> and give the model <strong>tools</strong> so it can act (scroll, toggle theme, save lead) instead of only replying with text.</p>
<hr />
<h1>Architecture at a Glance</h1>
<p>The setup has three parts:</p>
<ol>
<li><strong>React app</strong> — Chat UI, message state, and tool execution (theme, scroll, filter, lead).  </li>
<li><strong>Netlify serverless function</strong> — Receives chat requests (message + history + tools), calls Gemini with your API key, streams the response back.  </li>
<li><strong>Gemini API</strong> — Model + system instruction + tool declarations; returns text and/or function calls.</li>
</ol>
<p>Flow:</p>
<p><strong>User types</strong> → <strong>Frontend</strong> sends message (and optional history) to <strong><code>/.netlify/functions/chat</code></strong> → <strong>Function</strong> calls <strong>Gemini</strong> with <code>GEMINI_API_KEY</code> from env → <strong>Stream</strong> of text and tool calls returns to <strong>Frontend</strong> → <strong>Frontend</strong> renders text and runs tools (e.g. <code>scrollToSection('projects')</code>).</p>
<p>Your API key never leaves Netlify’s server.</p>
<hr />
<h1>Step 1: Keep the API Key Server-Side</h1>
<p>Never put <code>GEMINI_API_KEY</code> in client-side code or in a public repo.</p>
<p><strong>Option A – Chat runs entirely in the serverless function (recommended)</strong><br />The frontend only calls <code>POST /.netlify/functions/chat</code> with <code>{ message, history, systemInstruction, tools }</code>. The function creates the Gemini chat, sends the message, and returns the stream. The key stays in <code>process.env.GEMINI_API_KEY</code> on Netlify.</p>
<p><strong>Option B – Key delivery for client-side chat</strong><br />If you want the chat session to live in the browser (e.g. using <code>@google/genai</code> in React), you need a separate endpoint that returns a temporary key or proxy. A simple approach is a small function that reads <code>GEMINI_API_KEY</code> and returns it only to your origin; you can lock this down by checking <code>Origin</code> or a secret header. Even then, prefer doing the heavy lifting (Gemini calls) in the serverless function so the key is used only on the server.</p>
<p>In the reference project, the frontend fetches the key from <code>/.netlify/functions/env</code> and then creates the chat in the client. For maximum security, moving the chat into the Netlify function (Option A) is the cleanest: the client only sends messages and receives streamed responses.</p>
<hr />
<h1>Step 2: Define Tools (Function Declarations)</h1>
<p>Gemini supports <strong>function calling</strong>: you declare tools with names, descriptions, and parameters; the model can return a tool call instead of (or in addition to) text. Your frontend then runs the corresponding logic.</p>
<p>Example tools for a portfolio:</p>
<table>
<thead>
<tr>
<th>Tool</th>
<th>Purpose</th>
</tr>
</thead>
<tbody><tr>
<td><code>scrollToSection</code></td>
<td>Scroll the page to <code>home</code>, <code>skills</code>, <code>projects</code>, etc.</td>
</tr>
<tr>
<td><code>toggleTheme</code></td>
<td>Switch between light and dark mode.</td>
</tr>
<tr>
<td><code>filterProjects</code></td>
<td>Filter the project list by category.</td>
</tr>
<tr>
<td><code>saveLead</code></td>
<td>Send name, email, interest, budget, timeline to a webhook (e.g. Google Sheets, n8n).</td>
</tr>
</tbody></table>
<p>In code, each tool is a <strong>function declaration</strong> with a name, description, and a JSON schema for parameters. For example, in TypeScript with <code>@google/genai</code>:</p>
<pre><code class="language-ts">const scrollToSectionTool = {
  name: "scrollToSection",
  description: "Scrolls the page to a specific section.",
  parameters: {
    type: Type.OBJECT,
    properties: {
      sectionId: {
        type: Type.STRING,
        description: "Section ID: 'home' | 'skills' | 'projects' | 'experience' | 'contact'"
      }
    },
    required: ["sectionId"]
  }
};
</code></pre>
<p>You pass an array of these into the chat config as <code>tools: [{ functionDeclarations: [scrollToSectionTool, toggleThemeTool, filterProjectsTool, saveLeadTool] }]</code>. The model will use them when it decides the user wants to navigate, change theme, filter, or submit a lead.</p>
<hr />
<h1>Step 3: System Instruction: Context and Behavior</h1>
<p>The <strong>system instruction</strong> is where you teach the bot who you are and how to behave.</p>
<p>Include:</p>
<p>• <strong>Role</strong> — e.g. “You are [Name]’s portfolio assistant.”<br />• <strong>Context</strong> — Concise summaries of skills, experience, projects, and case studies (or links to them).<br />• <strong>Capabilities</strong> — “You can scroll to sections, toggle theme, filter projects, and save leads.”<br />• <strong>Lead capture rules</strong> — When the user shows intent (e.g. “I want to hire you,” “Get in touch”), collect name, email, interest, budget, and timeline one by one; only call <code>saveLead</code> when all five are present.<br />• <strong>Tone</strong> — e.g. friendly, professional, concise.</p>
<p>Keep the instruction within token limits. You can build it dynamically from your existing data (e.g. map over <code>SKILL_CATEGORIES</code>, <code>PROJECTS</code>, <code>CASE_STUDIES</code>) so one source of truth drives both the site and the bot.</p>
<hr />
<h1>Step 4: Handle Streaming and Tool Calls in the Frontend</h1>
<p>When you call <code>chat.sendMessageStream({ message })</code>, you get an async iterator. Each chunk can contain:</p>
<p>• <strong>Text</strong> — append to the current assistant message.<br />• <strong>Function calls</strong> — e.g. <code>{ name: "scrollToSection", args: { sectionId: "projects" } }</code>.</p>
<p>Pseudocode:</p>
<pre><code class="language-ts">for await (const chunk of result) {
  if (chunk.text) appendToMessage(chunk.text);
  if (chunk.functionCalls?.length) {
    for (const call of chunk.functionCalls) {
      if (call.name === 'scrollToSection') scrollToSection(call.args.sectionId);
      if (call.name === 'toggleTheme') toggleTheme();
      if (call.name === 'filterProjects') setProjectFilter(call.args.category);
      if (call.name === 'saveLead') await sendToWebhook(call.args);
    }
  }
}
</code></pre>
<p>You can show a short “Done!” message for UI actions (theme, scroll, filter) and a confirmation for lead capture. If you use streaming, render text as it arrives and run tools as soon as a full call is available.</p>
<hr />
<h1>Step 5: Lead Capture via Webhook</h1>
<p>The <code>saveLead</code> tool should send data to <em>your</em> backend, not hardcode anything in the client. A simple pattern:</p>
<p>• <strong>Webhook URL</strong> — Stored in env (e.g. <code>VITE_WEBHOOK_URL</code>) or returned from a small serverless function.<br />• <strong>Payload</strong> — Name, email, interest, budget, timeline, and optionally a short conversation summary.<br />• <strong>Receiver</strong> — Google Apps Script (Google Sheets), n8n, Make, or any HTTP endpoint that appends a row or creates a CRM contact.</p>
<p>Your frontend (or a small Netlify function) does <code>fetch(WEBHOOK_URL, { method: 'POST', body: JSON.stringify(lead) })</code>. That keeps the chatbot decoupled from your CRM and lets you switch providers without changing the bot logic.</p>
<hr />
<h1>Step 6: Netlify Function for Chat</h1>
<p>A minimal Netlify function that proxies to Gemini could look like this:</p>
<p>• <strong>Method</strong> — <code>POST</code> only.<br />• <strong>Body</strong> — <code>{ message, history?, systemInstruction?, tools? }</code>.<br />• <strong>Env</strong> — <code>GEMINI_API_KEY</code> set in Netlify dashboard.<br />• <strong>Logic</strong> — Instantiate Gemini with the key, create a chat with the given system instruction and tools, send the message (and history if provided), then stream the response back (or collect chunks and return once).</p>
<p>If the frontend creates the chat in the client, you can still use a function to send a single message and return the stream so the key stays server-side; the only difference is where the “session” (history) is stored (client vs server).</p>
<hr />
<h1>Takeaways</h1>
<p>• <strong>API key</strong> — Never in the client. Use a serverless function (e.g. Netlify) to call Gemini.<br />• <strong>Tools</strong> — Define clear function declarations (name, description, parameters) so the model can scroll, toggle theme, filter, and save leads.<br />• <strong>System instruction</strong> — One place for role, context (skills/projects/case studies), and lead-capture rules.<br />• <strong>Streaming</strong> — Handle both text chunks and function calls in the same loop; execute tools and optionally show short confirmations.<br />• <strong>Leads</strong> — Send to a webhook (Sheets, n8n, Make) so you can change the backend without touching the chatbot.</p>
<p>Building this flow gives you a portfolio that feels alive, captures intent cleanly, and teaches you how to combine an LLM with real-world actions—all with a small, maintainable stack (React, Gemini, Netlify).</p>
<hr />
<h1>Author Note</h1>
<p>This article is based on a production portfolio that uses React, TypeScript, Vite, Google Gemini, and Netlify. The same pattern (serverless + tool calling + webhook) applies to other LLMs and hosting providers.</p>
]]></content:encoded></item><item><title><![CDATA[How a Simple Event Tool Evolved into an Integration-Driven SaaS Platform]]></title><description><![CDATA[How a Simple Event Tool Evolved into an Integration-Driven SaaS Platform
Many software projects start with a simple idea.
In this case, the goal was straightforward: build a tool to manage online even]]></description><link>https://blog.someshbhardwaj.me/how-a-simple-event-tool-evolved-into-an-integration-driven-saas-platform</link><guid isPermaLink="true">https://blog.someshbhardwaj.me/how-a-simple-event-tool-evolved-into-an-integration-driven-saas-platform</guid><dc:creator><![CDATA[Er Somesh Bhardwaj]]></dc:creator><pubDate>Thu, 12 Mar 2026 10:45:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/73b69520-ad2b-4d4f-a7ed-9a86e4e08a78.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>How a Simple Event Tool Evolved into an Integration-Driven SaaS Platform</h1>
<p>Many software projects start with a simple idea.</p>
<p>In this case, the goal was straightforward: build a tool to manage online events, registrations, and reminders.</p>
<p>But as real users began interacting with the platform and integrations were introduced, the architecture evolved significantly.</p>
<p>What started as a basic event workflow gradually became a system responsible for orchestrating multiple external services, automation processes, and operational workflows.</p>
<p>This article shares architectural lessons from building that system and how a simple tool evolved into an <strong>integration-driven SaaS platform</strong>.</p>
<hr />
<h1>The Initial Concept</h1>
<p>At the beginning, the system architecture was simple and easy to reason about.</p>
<p>Users could browse events, register, and receive confirmation emails.</p>
<p>The architecture looked something like this:</p>
<p><strong>Participants</strong></p>
<p>↓</p>
<p><strong>Frontend Web Application</strong></p>
<p>↓</p>
<p><strong>Backend Application</strong></p>
<p>↓</p>
<p><strong>Database</strong></p>
<p>↓</p>
<p><strong>Email Service + Video Meeting Platform</strong></p>
<p><strong>Before Architecture</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/5cef74d1-84e8-4518-970b-689c49b44fa6.png" alt="" style="display:block;margin:0 auto" />

<p>At this stage the platform handled:</p>
<p>• Event registration • Confirmation emails • Basic event management</p>
<p>The system was small, easy to maintain, and the architecture was straightforward.</p>
<p>But as the product grew, new requirements started appearing.</p>
<hr />
<h1>When Complexity Appears</h1>
<p>As the platform began supporting more use cases, the architecture needed to evolve.</p>
<p>New requirements included:</p>
<p>• Multi-session events • Global users across multiple time zones • Automated reminders • Analytics and reporting • Integration with external services • Operational monitoring</p>
<p>Each new capability introduced additional complexity.</p>
<p>What started as a simple application gradually transformed into a <strong>coordination platform between multiple systems</strong>.</p>
<hr />
<h1>The Production Architecture</h1>
<p>In production, the system evolved into a layered architecture designed to handle integrations, automation, and operational workflows reliably.</p>
<p><strong>Full Platform Architecture</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/5e5fdbd3-fec7-4ea9-90cf-476892a50078.png" alt="" style="display:block;margin:0 auto" />

<p>The architecture can be understood through several layers.</p>
<hr />
<h2>Users</h2>
<p>The platform serves multiple types of users:</p>
<p>• Participants attending events • Event Leads / Admins managing events • Operations teams monitoring and maintaining the system</p>
<p>Each interacts with the system through the web application.</p>
<hr />
<h2>Application Layer</h2>
<p>The frontend web application provides the user interface.</p>
<p>This layer handles:</p>
<p>• Event browsing • Registration forms • Admin dashboards • Event management tools • Analytics views</p>
<p>It communicates with the platform through secure APIs.</p>
<hr />
<h2>Core Platform (Orchestration Layer)</h2>
<p>This is the heart of the system.</p>
<p>Instead of rebuilding every capability internally, the platform focuses on orchestrating workflows between different services.</p>
<p>Core responsibilities include:</p>
<p>• Event orchestration • Registration management • Reminder scheduling • Integration coordination • Administrative workflows • System observability</p>
<p>Key internal components include:</p>
<p>• Event Management Engine • Registration Engine • Reminder Scheduler • Integration Manager • Observability Layer</p>
<hr />
<h2>Data Layer</h2>
<p>The database stores operational data such as:</p>
<p>• Events • Sessions • Registrations • Attendance records • Reminder logs • System logs • Audit trails</p>
<p>The data layer also supports:</p>
<p>• Idempotency controls • Operational dashboards • Debugging production incidents</p>
<hr />
<h2>External Integrations</h2>
<p>Rather than rebuilding specialized capabilities, the platform integrates with external services such as:</p>
<p>• Video meeting platforms • Email delivery infrastructure • Marketing automation tools • AI services • Analytics platforms • Calendar ecosystems</p>
<p>These integrations are handled through <strong>translation layers</strong> so external APIs never dictate the internal system architecture.</p>
<hr />
<h2>Automation Layer</h2>
<p>Background automation ensures the system operates reliably.</p>
<p>These processes include:</p>
<p>• Scheduled reminder processing • Attendance synchronization • Data synchronization with external systems • Operational automation tasks</p>
<p>Automation runs periodically and evaluates system state rather than relying solely on delayed job queues.</p>
<hr />
<h1>Architectural Decisions That Made the System Reliable</h1>
<p>During development, a few architectural decisions significantly improved system reliability and usability.</p>
<p><strong>Architectural Blueprint</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/921a489f-07e2-448e-933d-82af2167445a.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>Frictionless Access Architecture</h2>
<p>Participants do not need user accounts to attend events.</p>
<p>Instead, registrations are mapped to secure identifiers.</p>
<p>Advantages include:</p>
<p>• Reduced onboarding friction • Faster user adoption • Simpler user experience</p>
<p>The tradeoff is that the backend must manage identity mapping and access control carefully.</p>
<hr />
<h2>Polling Schedulers Instead of Delayed Job Queues</h2>
<p>Rather than scheduling thousands of delayed tasks, the system periodically evaluates what actions need to run.</p>
<p>Benefits include:</p>
<p>• Higher reliability • Simpler debugging • Reduced operational complexity</p>
<p>Although this approach sacrifices some scheduling precision, it significantly improves system resilience.</p>
<hr />
<h2>API Boundary Translation</h2>
<p>External APIs should never dictate internal architecture.</p>
<p>Instead, the platform maintains its own internal data model and translates it when interacting with external services.</p>
<p>Advantages include:</p>
<p>• Reduced coupling with third-party systems • Easier provider changes • Cleaner domain logic</p>
<hr />
<h2>Observability-First Design</h2>
<p>Operational visibility was built directly into the system.</p>
<p>Structured logs capture events such as:</p>
<p>• Email delivery attempts • Reminder processing • External API failures • Administrative actions</p>
<p>This makes debugging production issues significantly easier.</p>
<p>Instead of searching through logs, many operational questions can be answered through simple database queries.</p>
<hr />
<h1>Lessons Learned</h1>
<p>Building this platform revealed several important lessons about designing modern SaaS systems.</p>
<p>• Simplicity often improves reliability • Integration design matters more than individual features • Observability should be built early in the architecture • External APIs introduce unpredictability that must be handled carefully • Removing friction for users often shifts complexity into backend workflows</p>
<p>Perhaps the most important insight was realizing that many modern SaaS platforms are less about building everything internally and more about orchestrating specialized services reliably.</p>
<hr />
<h1>Final Reflection</h1>
<p>What started as a simple event registration tool eventually evolved into a system coordinating multiple services, workflows, and automation layers.</p>
<p>The experience reinforced a key principle of software architecture:</p>
<p>Good systems are not defined by their complexity, but by their ability to remain understandable and resilient as they grow.</p>
<p>Modern SaaS engineering is often less about writing code and more about designing reliable workflows between people, systems, and services.</p>
<hr />
<h1>Author Note</h1>
<p>This article shares architectural lessons from building a production system. Specific implementation details and vendor choices have been intentionally generalized.</p>
]]></content:encoded></item><item><title><![CDATA[Google Workspace Admin Tips Every Small Team Should Know]]></title><description><![CDATA[Managing a small team on Google Workspace can be rewarding — but also challenging if you’re not familiar with all the admin tools at your disposal. Over time, I’ve picked up a few tips that have made ]]></description><link>https://blog.someshbhardwaj.me/google-workspace-admin-tips-small-teams</link><guid isPermaLink="true">https://blog.someshbhardwaj.me/google-workspace-admin-tips-small-teams</guid><category><![CDATA[Admin Tips]]></category><category><![CDATA[Google Workspace]]></category><category><![CDATA[Small business]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[team collaboration]]></category><category><![CDATA[it management ]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[tools]]></category><dc:creator><![CDATA[Er Somesh Bhardwaj]]></dc:creator><pubDate>Fri, 06 Jun 2025 07:38:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6836d46ef5fef0a9449b753a/67eac7c2-2f3a-4cbd-81d4-017da9a9c798.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<p>Managing a small team on Google Workspace can be rewarding — but also challenging if you’re not familiar with all the admin tools at your disposal. Over time, I’ve picked up a few tips that have made a huge difference in managing users, maintaining security, and streamlining collaboration.</p>
<p>Here are some <strong>essential Google Workspace admin tips</strong> that every small team should know.</p>
<h2>1. Set Up Organizational Units (OUs) Early</h2>
<p>Organizational Units help you group users based on departments, seniority, or project needs. Even for small teams, having OUs allows you to apply different settings, permissions, and policies easily.</p>
<p>Example: Keep the Sales team and the Tech team under separate OUs to manage app access or email restrictions separately.</p>
<h2>2. Enforce 2-Step Verification (2SV)</h2>
<p>Security should always be a priority. Enable <strong>2-Step Verification</strong> for all users to add an extra layer of protection to accounts.</p>
<p>Admin Console: <code>Security</code> &gt; <code>Authentication</code> &gt; <code>2-Step Verification</code> &gt; <code>Enforce</code></p>
<h2>3. Use Groups for Easier Communication</h2>
<p>Instead of emailing multiple people individually, create Groups (like <a href="mailto:team@yourdomain.com"><code>team@yourdomain.com</code></a>) for project teams or departments. It makes collaboration seamless and easier to manage access permissions to Docs, Sheets, and Drives.</p>
<h2>4. Monitor Activity with Audit Logs</h2>
<p>Google Workspace provides extensive <strong>audit logs</strong> — use them to monitor account activity, file sharing, and login attempts. This can help spot unusual behavior early.</p>
<p>Admin Console: <code>Reports</code> &gt; <code>Audit log</code></p>
<h2>5. Manage Licenses Smartly</h2>
<p>Small teams often scale quickly. Periodically audit your licenses to ensure you’re not paying for inactive accounts. Suspend users who leave the organization instead of deleting immediately — you can transfer data safely later.</p>
<h2>6. Implement Shared Drives</h2>
<p>Instead of users saving files in personal Drives, create <strong>Shared Drives</strong> for team projects. This ensures data remains accessible even if someone leaves the organization.</p>
<p>Shared Drives make it easier to set permission levels and keep file ownership with the organization.</p>
<h2>7. Automate Onboarding with Google Workspace APIs</h2>
<p>For growing teams, consider automating user creation and group assignment using Google’s Admin SDK APIs or low-code tools like n8n.</p>
<p>It saves time and reduces the chance of manual errors.</p>
<h2>Final Thoughts</h2>
<p>Google Workspace is incredibly powerful, but only if you leverage its full potential. Setting up best practices early ensures your small team stays secure, organized, and productive as you scale.</p>
<p>If you're just starting or looking to optimize your Google Workspace setup, these tips will give you a head start.</p>
<hr />
<p><em>I regularly share Google Workspace management strategies — stay tuned for more practical guides and tips!</em></p>
]]></content:encoded></item><item><title><![CDATA[Building Powerful Web Automations with n8n]]></title><description><![CDATA[In today's fast-paced digital world, automating repetitive tasks can free up your time and boost your efficiency dramatically. One of the most powerful open-source tools available for this purpose is n8n.
I’ve been using n8n to automate web tasks acr...]]></description><link>https://blog.someshbhardwaj.me/building-powerful-web-automations-with-n8n</link><guid isPermaLink="true">https://blog.someshbhardwaj.me/building-powerful-web-automations-with-n8n</guid><category><![CDATA[automation]]></category><category><![CDATA[nocode]]></category><category><![CDATA[n8n]]></category><category><![CDATA[Web Automation]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[techblog]]></category><dc:creator><![CDATA[Er Somesh Bhardwaj]]></dc:creator><pubDate>Sat, 31 May 2025 20:45:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748724197062/ffde6b72-0e4c-4336-9c84-a2f444955ba1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In today's fast-paced digital world, automating repetitive tasks can free up your time and boost your efficiency dramatically. One of the most powerful open-source tools available for this purpose is <strong>n8n</strong>.</p>
<p>I’ve been using n8n to automate web tasks across various projects, and it has fundamentally changed how I approach problem-solving. Whether you're a developer or a no-code enthusiast, n8n can help you build complex workflows without writing a single line of code.</p>
<h2 id="heading-what-is-n8n">What is n8n?</h2>
<p>n8n (short for "nodemation") is a <strong>fair-code licensed</strong>, <strong>open-source workflow automation tool</strong> that allows you to connect different services via simple, visual workflows.</p>
<p>Think of it as your personal digital assistant — one that can interact with hundreds of apps like Google Sheets, Slack, Notion, Airtable, and more.</p>
<h2 id="heading-why-i-chose-n8n">Why I Chose n8n</h2>
<ul>
<li><p><strong>Open-source flexibility</strong>: No vendor lock-in; self-host if you want.</p>
</li>
<li><p><strong>No-code/low-code</strong>: Drag and drop interface makes it easy.</p>
</li>
<li><p><strong>Powerful integrations</strong>: 350+ apps and services natively supported.</p>
</li>
<li><p><strong>Self-hosting</strong>: Full control over your workflows and data.</p>
</li>
<li><p><strong>Community-driven</strong>: Growing ecosystem and support.</p>
</li>
</ul>
<h2 id="heading-real-world-use-cases">Real-World Use Cases</h2>
<p>Here are some of the automations I’ve built using n8n:</p>
<ul>
<li><p><strong>Lead Collection</strong>: Scrape form submissions and automatically add them to my CRM.</p>
</li>
<li><p><strong>Content Scheduling</strong>: Publish blog posts to multiple platforms simultaneously.</p>
</li>
<li><p><strong>Daily Reports</strong>: Fetch analytics data and email a summary every morning.</p>
</li>
<li><p><strong>Slack Alerts</strong>: Get notified instantly when a specific event occurs on a website.</p>
</li>
</ul>
<h2 id="heading-getting-started-with-n8n">Getting Started with n8n</h2>
<ol>
<li><p><strong>Install locally</strong> with Docker or Node.js.</p>
</li>
<li><p><strong>Use their cloud version</strong> (<a target="_blank" href="http://n8n.cloud">n8n.cloud</a>) if you prefer hassle-free hosting.</p>
</li>
<li><p><strong>Build a workflow</strong> using drag-and-drop nodes.</p>
</li>
<li><p><strong>Test and deploy</strong> — your automation is ready!</p>
</li>
</ol>
<p>Here’s a simple example: <strong>New Email ➔ Save Attachment to Google Drive ➔ Send Slack Notification</strong> — done in minutes without coding.</p>
<h2 id="heading-lessons-learned">Lessons Learned</h2>
<ul>
<li><p><strong>Start simple</strong>: Begin with basic workflows and expand gradually.</p>
</li>
<li><p><strong>Fail fast</strong>: Test as you build to avoid surprises.</p>
</li>
<li><p><strong>Stay organized</strong>: Label your workflows clearly for easy management.</p>
</li>
</ul>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Automation is not just for developers anymore. With tools like n8n, anyone can automate complex web tasks and boost their productivity.</p>
<p>If you haven’t explored n8n yet, now is a perfect time. It might just be the tool that takes your workflow efficiency to the next level.</p>
<hr />
<p><em>I often share my automation experiments and tutorials — follow along for more hands-on guides!</em></p>
]]></content:encoded></item><item><title><![CDATA[How AI-driven Automation Transformed My Workflow]]></title><description><![CDATA[In the fast-evolving world of technology, finding ways to streamline workflows is essential for staying productive. Over the last few years, I’ve explored various strategies, but nothing has matched the impact that AI-driven automation has had on my ...]]></description><link>https://blog.someshbhardwaj.me/how-ai-driven-automation-transformed-my-workflow</link><guid isPermaLink="true">https://blog.someshbhardwaj.me/how-ai-driven-automation-transformed-my-workflow</guid><category><![CDATA[AI]]></category><category><![CDATA[automation]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[workflow optimization]]></category><category><![CDATA[nocode]]></category><category><![CDATA[#ai-tools]]></category><category><![CDATA[aitools]]></category><category><![CDATA[techblog]]></category><category><![CDATA[Digital Transformation]]></category><dc:creator><![CDATA[Er Somesh Bhardwaj]]></dc:creator><pubDate>Sat, 31 May 2025 20:32:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748723615348/9343001a-876a-4e59-aa7d-ec1d9c59441b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the fast-evolving world of technology, finding ways to streamline workflows is essential for staying productive. Over the last few years, I’ve explored various strategies, but nothing has matched the impact that <strong>AI-driven automation</strong> has had on my work.</p>
<p>From system administration to building client-facing websites, automation now touches every part of my day. Here’s how AI transformed my workflow — and why I believe it’s the future for anyone serious about scaling their productivity.</p>
<h2 id="heading-the-starting-point-manual-overload">The Starting Point: Manual Overload</h2>
<p>A few years ago, my daily tasks were a maze of repetitive actions — managing Google Workspace accounts, onboarding new users, updating websites, analyzing campaign metrics manually. While necessary, these tasks drained time from creative and strategic work.</p>
<p>That's when I realized: <strong>manual work doesn't scale</strong>.</p>
<h2 id="heading-enter-ai-powered-automation">Enter AI-Powered Automation</h2>
<p>Leveraging AI tools like <a target="_blank" href="http://Make.com">Make.com</a>, n8n, OpenAI, and no-code platforms, I began building smart workflows:</p>
<ul>
<li><p>Automating onboarding and offboarding in Google Workspace.</p>
</li>
<li><p>Scraping and organizing lead data into CRM systems.</p>
</li>
<li><p>Setting up chatbots that handle common queries.</p>
</li>
<li><p>Running scheduled reports and analytics using AI summarization.</p>
</li>
<li><p>Creating dynamic website content pipelines with AI writers and auto-publishers.</p>
</li>
</ul>
<p>Every small automation led to compounding gains — more free time, fewer mistakes, faster delivery.</p>
<h2 id="heading-real-world-wins">Real-World Wins</h2>
<ul>
<li><p><strong>Saved 10+ hours/week</strong> by automating client onboarding.</p>
</li>
<li><p><strong>Improved response time</strong> by integrating AI-based chat assistants.</p>
</li>
<li><p><strong>Reduced manual errors</strong> in campaign analytics by syncing data through automated workflows.</p>
</li>
</ul>
<p>What started as minor automations evolved into a robust personal system — AI agents handling routine tasks while I focus on what really matters: strategy, creativity, and innovation.</p>
<h2 id="heading-lessons-learned">Lessons Learned</h2>
<ul>
<li><p><strong>Start small</strong>: Automate one task at a time.</p>
</li>
<li><p><strong>Focus on bottlenecks</strong>: Identify where manual effort creates delays.</p>
</li>
<li><p><strong>Embrace iteration</strong>: Automation is not “set and forget”; it evolves with your work.</p>
</li>
</ul>
<p>Most importantly, automation isn’t just about saving time — it’s about <strong>amplifying your capabilities</strong>.</p>
<h2 id="heading-why-it-matters-now-more-than-ever">Why It Matters Now More Than Ever</h2>
<p>In a world where the pace of change is relentless, those who master automation aren’t just more productive — they’re more adaptable. AI isn’t here to replace us. It’s here to <strong>empower</strong> us.</p>
<p>If you haven’t yet explored AI-driven automation, now is the time to start. It might just transform your workflow — and your career — like it did mine.</p>
<hr />
<p><em>Interested in seeing real automation workflows in action? I often share tutorials and project breakdowns — feel free to connect!</em></p>
]]></content:encoded></item></channel></rss>