<?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: Krishna Chaudhary</title>
    <description>The latest articles on DEV Community by Krishna Chaudhary (@krishna_chaudhary_53d52cb).</description>
    <link>https://dev.to/krishna_chaudhary_53d52cb</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%2F4229269%2F1d88a701-570e-4dac-954a-362f8b49f4f0.jpg</url>
      <title>DEV Community: Krishna Chaudhary</title>
      <link>https://dev.to/krishna_chaudhary_53d52cb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/krishna_chaudhary_53d52cb"/>
    <language>en</language>
    <item>
      <title>MY INBOX HAS 99 PROBLEMS. JOE AIN'T ONE.</title>
      <dc:creator>Krishna Chaudhary</dc:creator>
      <pubDate>Fri, 06 Nov 2026 18:59:25 +0000</pubDate>
      <link>https://dev.to/krishna_chaudhary_53d52cb/my-inbox-has-99-problems-joe-aint-one-11ag</link>
      <guid>https://dev.to/krishna_chaudhary_53d52cb/my-inbox-has-99-problems-joe-aint-one-11ag</guid>
      <description>&lt;p&gt;&lt;strong&gt;Built for the Flip the Switch Hackathon 2026.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/engineerkrish/joe-ai-email-assistant" rel="noopener noreferrer"&gt;https://github.com/engineerkrish/joe-ai-email-assistant&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo video:&lt;/strong&gt; &lt;a href="https://youtu.be/Q9CcvPKpbho?si=n_RmI6IHP4l8NZOn" rel="noopener noreferrer"&gt;https://youtu.be/Q9CcvPKpbho?si=n_RmI6IHP4l8NZOn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every morning, the same thing happens.&lt;/p&gt;

&lt;p&gt;You open Gmail, see a bunch of unread emails, and start figuring out which ones actually matter.&lt;/p&gt;

&lt;p&gt;Some are important. Some are promotional. Some need a response. Others can wait.&lt;/p&gt;

&lt;p&gt;The problem isn't receiving emails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem is figuring out what deserves your attention.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted an assistant that could handle the first part of that work: check my inbox, identify important messages, search for specific emails, and help me draft replies.&lt;/p&gt;

&lt;p&gt;But there was one rule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The assistant should help me manage my inbox, not take control of it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's how I started building &lt;strong&gt;Joe AI Email Assistant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And what I thought would be a straightforward AI integration turned into a series of authentication problems, missing integrations, local server debugging, Docker issues, and a surprising amount of learning about how AI agents actually work.&lt;/p&gt;

&lt;p&gt;Here's how it went.&lt;/p&gt;




&lt;h2&gt;
  
  
  Meet Joe: My AI Email Assistant
&lt;/h2&gt;

&lt;p&gt;Joe is an AI-powered email assistant built using Python, Gmail API, Google Gemini, Switch Console, and Mattermost.&lt;/p&gt;

&lt;p&gt;Instead of manually navigating Gmail, I can open my Mattermost room and ask Joe to help.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; &lt;code&gt;@joe Check my emails.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Joe retrieves the latest five emails and presents their sender, subject, and date.&lt;/p&gt;

&lt;p&gt;It can also suggest which messages deserve attention first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; &lt;code&gt;@joe Search my inbox for hackathon emails.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Joe searches Gmail and returns matching messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; &lt;code&gt;@joe Draft a reply to the hackathon registration email.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Joe prepares a proposed response that I can review and edit.&lt;/p&gt;

&lt;p&gt;It doesn't send the email.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;Joe is designed to assist with reading, organizing, and drafting—not to make irreversible decisions on my behalf.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfm6dl7ksgmu2n02boo9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfm6dl7ksgmu2n02boo9.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caption: Joe retrieves recent Gmail messages and helps identify which ones need attention.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/engineerkrish/joe-ai-email-assistant" rel="noopener noreferrer"&gt;https://github.com/engineerkrish/joe-ai-email-assistant&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo video:&lt;/strong&gt; &lt;a href="https://youtu.be/Q9CcvPKpbho?si=n_RmI6IHP4l8NZOn" rel="noopener noreferrer"&gt;https://youtu.be/Q9CcvPKpbho?si=n_RmI6IHP4l8NZOn&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;Most people don't need another email application.&lt;/p&gt;

&lt;p&gt;They need something that reduces the effort required to use the one they already have.&lt;/p&gt;

&lt;p&gt;Traditional email filters can organize messages according to predefined rules.&lt;/p&gt;

&lt;p&gt;But they don't always answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which emails should I focus on today?&lt;/li&gt;
&lt;li&gt;Did I receive anything important about my hackathon?&lt;/li&gt;
&lt;li&gt;Which messages might require a response?&lt;/li&gt;
&lt;li&gt;Can you help me write a professional reply?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted to interact with my inbox conversationally.&lt;/p&gt;

&lt;p&gt;Not through complicated commands.&lt;/p&gt;

&lt;p&gt;Just by asking.&lt;/p&gt;

&lt;p&gt;And I wanted that experience inside an agent workspace rather than building an entirely separate email dashboard.&lt;/p&gt;

&lt;p&gt;That's where Switch Console came in.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Joe Actually Does
&lt;/h2&gt;

&lt;p&gt;Joe currently supports four main workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Check Recent Emails
&lt;/h3&gt;

&lt;p&gt;When I ask Joe to check my inbox, it retrieves up to five recent messages.&lt;/p&gt;

&lt;p&gt;For each message, the Gmail bridge returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sender&lt;/li&gt;
&lt;li&gt;Subject&lt;/li&gt;
&lt;li&gt;Date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Joe can then organize those results into a readable response and suggest priorities.&lt;/p&gt;

&lt;p&gt;The important detail is that the bridge currently retrieves &lt;strong&gt;email metadata, not full message bodies&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means Joe's prioritization is based on limited information.&lt;/p&gt;

&lt;p&gt;It can identify potentially important messages, but it cannot reliably determine everything an email contains.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Search Gmail Using Natural Language
&lt;/h3&gt;

&lt;p&gt;I can ask:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@joe Search my inbox for hackathon emails.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Joe can use a Gmail search query such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;in:inbox hackathon&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The bridge forwards that query to Gmail and returns matching messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4448qzs577t9r4ixlpj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4448qzs577t9r4ixlpj.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caption: Joe searches Gmail for relevant messages directly from the Mattermost conversation.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Draft Email Replies
&lt;/h3&gt;

&lt;p&gt;After finding a relevant message, I can ask Joe to draft a response.&lt;/p&gt;

&lt;p&gt;For example, during testing, I used a hackathon email from WeMakeDevs.&lt;/p&gt;

&lt;p&gt;Joe generated a proposed reply based on the information available.&lt;/p&gt;

&lt;p&gt;Because it only had email metadata, the draft had to avoid inventing details from the unseen email body.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3t4dg33y2poqk1yx0hq7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3t4dg33y2poqk1yx0hq7.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caption: Joe prepares a proposed email reply without sending it.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Refine Drafts Through Conversation
&lt;/h3&gt;

&lt;p&gt;I can continue the conversation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@joe Make the reply shorter and friendlier.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Joe updates the draft based on my instructions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faag3i9q7jgwi68inwtee.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faag3i9q7jgwi68inwtee.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caption: Joe adjusts its proposed response based on user feedback.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is one of my favorite parts of the project.&lt;/p&gt;

&lt;p&gt;It feels less like operating a tool and more like collaborating with an assistant.&lt;/p&gt;




&lt;h1&gt;
  
  
  How It Works
&lt;/h1&gt;

&lt;p&gt;The architecture is relatively simple.&lt;/p&gt;

&lt;p&gt;But getting every component to communicate was the hardest part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 USER
                   |
                   v
           Mattermost Room
                   |
                   v
             Switch Console
                   |
                   v
              Joe AI Agent
                   |
                   v
           gmail_helper.py
                   |
                   v
        Authenticated HTTP Request
                   |
                   v
       Python Bridge (127.0.0.1:8765)
                   |
                   v
               Gmail API
                   |
                   v
          Email Metadata / Search
                   |
                   v
              Joe AI Agent
                   |
                   v
           Mattermost Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two important pieces of Python code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;bridge.py&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This runs a local HTTP server.&lt;/p&gt;

&lt;p&gt;It communicates with Gmail using OAuth credentials and returns email metadata in JSON format.&lt;/p&gt;

&lt;p&gt;The bridge listens on:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;127.0.0.1:8765&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It also checks an authentication token before processing requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;gmail_helper.py&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the interface Joe uses to communicate with the bridge.&lt;/p&gt;

&lt;p&gt;Instead of manually constructing authenticated HTTP requests, Joe can run the helper script.&lt;/p&gt;

&lt;p&gt;The helper loads the bridge token from the local environment and sends the request.&lt;/p&gt;

&lt;p&gt;The result is a small but functional connection between an AI agent and a real Gmail inbox.&lt;/p&gt;

&lt;p&gt;The standalone &lt;code&gt;main.py&lt;/code&gt; also provides a Python-based Gmail and Gemini workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy6gevybcy6p8ix2j1x6h.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy6gevybcy6p8ix2j1x6h.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  The Part Nobody Sees: What Went Wrong
&lt;/h1&gt;

&lt;p&gt;This is where the project became interesting.&lt;/p&gt;

&lt;p&gt;The final demo looks simple.&lt;/p&gt;

&lt;p&gt;Ask Joe a question.&lt;/p&gt;

&lt;p&gt;Joe checks Gmail.&lt;/p&gt;

&lt;p&gt;Joe responds.&lt;/p&gt;

&lt;p&gt;But making that happen required solving several problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 1: Gmail Authentication Wasn't Just an API Key
&lt;/h2&gt;

&lt;p&gt;Initially, I thought connecting Gmail would be similar to calling a regular API.&lt;/p&gt;

&lt;p&gt;It wasn't.&lt;/p&gt;

&lt;p&gt;Gmail requires OAuth authorization to access a user's mailbox.&lt;/p&gt;

&lt;p&gt;That meant configuring Google API credentials, handling the authorization process, and storing the resulting tokens locally.&lt;/p&gt;

&lt;p&gt;There were multiple moving parts.&lt;/p&gt;

&lt;p&gt;A mistake in the credentials, permissions, or token handling could prevent the entire integration from working.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Solved It
&lt;/h3&gt;

&lt;p&gt;I configured the Gmail API authentication flow and used the &lt;code&gt;gmail.readonly&lt;/code&gt; scope.&lt;/p&gt;

&lt;p&gt;This was an intentional decision.&lt;/p&gt;

&lt;p&gt;Joe only needed to retrieve information.&lt;/p&gt;

&lt;p&gt;It didn't need permission to send, delete, or modify emails.&lt;/p&gt;

&lt;p&gt;Once the OAuth flow was working, the Python application could access Gmail successfully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Give an AI application only the permissions it actually needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 2: Switch Couldn't Directly Access Gmail
&lt;/h2&gt;

&lt;p&gt;This was one of the biggest challenges.&lt;/p&gt;

&lt;p&gt;I had a working Python Gmail integration.&lt;/p&gt;

&lt;p&gt;I also had Switch Console running.&lt;/p&gt;

&lt;p&gt;But connecting those two systems wasn't automatic.&lt;/p&gt;

&lt;p&gt;The available Google Workspace connection didn't provide the Gmail access required for our workflow.&lt;/p&gt;

&lt;p&gt;So even though Gmail worked in Python, Joe couldn't simply ask the connector to retrieve my messages.&lt;/p&gt;

&lt;p&gt;For a while, I had two working components that couldn't communicate.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Solved It
&lt;/h3&gt;

&lt;p&gt;I built a local HTTP bridge.&lt;/p&gt;

&lt;p&gt;The bridge runs in Python and exposes a small authenticated endpoint.&lt;/p&gt;

&lt;p&gt;It connects to Gmail, retrieves a limited set of messages, and returns structured JSON.&lt;/p&gt;

&lt;p&gt;Then I connected Joe to that bridge through a Python helper script.&lt;/p&gt;

&lt;p&gt;Instead of waiting for a direct integration, I created a small interface between the systems.&lt;/p&gt;

&lt;p&gt;That was the breakthrough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; When two tools don't integrate directly, a narrow, well-defined interface can connect them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 3: The Bridge Needed Authentication
&lt;/h2&gt;

&lt;p&gt;Once the bridge was working, another question appeared.&lt;/p&gt;

&lt;p&gt;What stops an unauthorized local request from accessing the email data?&lt;/p&gt;

&lt;p&gt;Even a development prototype needs to think about security.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Solved It
&lt;/h3&gt;

&lt;p&gt;I added token-based authentication.&lt;/p&gt;

&lt;p&gt;The bridge checks the &lt;code&gt;X-Joe-Token&lt;/code&gt; request header against a locally configured token.&lt;/p&gt;

&lt;p&gt;Requests without the correct token are rejected.&lt;/p&gt;

&lt;p&gt;I also bound the bridge to &lt;code&gt;127.0.0.1&lt;/code&gt;, keeping it on the local machine rather than exposing it as a public web service.&lt;/p&gt;

&lt;p&gt;The token is stored in the local &lt;code&gt;.env&lt;/code&gt; file, which is excluded from Git.&lt;/p&gt;

&lt;p&gt;This doesn't make the entire system immune to attacks, but it reduces unnecessary exposure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Security should be part of the integration design, not something added after deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 4: Joe Needed a Reliable Way to Call the Bridge
&lt;/h2&gt;

&lt;p&gt;The bridge was working.&lt;/p&gt;

&lt;p&gt;The authentication token was working.&lt;/p&gt;

&lt;p&gt;But I still needed a simple way for Joe to make requests.&lt;/p&gt;

&lt;p&gt;Manually handling authentication headers and query parameters during every interaction was unnecessarily complicated.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Solved It
&lt;/h3&gt;

&lt;p&gt;I created &lt;code&gt;gmail_helper.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The helper handles the HTTP request, authentication header, and optional Gmail search query.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python gmail_helper.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for searching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python gmail_helper.py &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"in:inbox hackathon"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This made the interface easier for Joe to use and easier for me to test independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; A small helper tool can make an agent integration significantly more reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 5: Mattermost Suddenly Couldn't Be Reached
&lt;/h2&gt;

&lt;p&gt;This was one of the most frustrating moments.&lt;/p&gt;

&lt;p&gt;The Python integration was ready.&lt;/p&gt;

&lt;p&gt;Switch Console was configured.&lt;/p&gt;

&lt;p&gt;But the Mattermost room wasn't responding correctly.&lt;/p&gt;

&lt;p&gt;The error indicated that the Mattermost channel couldn't be reached.&lt;/p&gt;

&lt;p&gt;The problem wasn't Gmail.&lt;/p&gt;

&lt;p&gt;It wasn't Gemini.&lt;/p&gt;

&lt;p&gt;It wasn't even the bridge.&lt;/p&gt;

&lt;p&gt;The messaging environment itself wasn't fully available.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Solved It
&lt;/h3&gt;

&lt;p&gt;I checked Docker Desktop and the local Switch services.&lt;/p&gt;

&lt;p&gt;After starting Docker Desktop, enabling Mattermost, and restarting the relevant Switch server components, the room became accessible again.&lt;/p&gt;

&lt;p&gt;Joe could finally receive and respond to messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; When an integration fails, check the infrastructure underneath it before rewriting working application code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 6: Checking Emails Wasn't Enough
&lt;/h2&gt;

&lt;p&gt;At first, Joe could retrieve recent inbox messages.&lt;/p&gt;

&lt;p&gt;That was useful.&lt;/p&gt;

&lt;p&gt;But I wanted to ask more specific questions.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Did I receive anything about the hackathon?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The original bridge workflow focused on retrieving recent emails.&lt;/p&gt;

&lt;p&gt;It needed additional support for search.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Solved It
&lt;/h3&gt;

&lt;p&gt;I extended the bridge to accept a Gmail query parameter.&lt;/p&gt;

&lt;p&gt;I also updated the helper script to pass search queries correctly.&lt;/p&gt;

&lt;p&gt;That allowed Joe to use Gmail's existing search capabilities.&lt;/p&gt;

&lt;p&gt;During testing, I searched for:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;in:inbox hackathon&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And Joe returned relevant messages.&lt;/p&gt;

&lt;p&gt;This made the assistant much more practical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Build a small working version first, then extend it based on real interactions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 7: Publishing the Project Without Publishing My Secrets
&lt;/h2&gt;

&lt;p&gt;After the application worked, I wanted to upload it to GitHub.&lt;/p&gt;

&lt;p&gt;But the project used sensitive configuration files.&lt;/p&gt;

&lt;p&gt;These included Gmail OAuth credentials, authorization tokens, and API keys.&lt;/p&gt;

&lt;p&gt;Uploading those files would have been a serious mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Solved It
&lt;/h3&gt;

&lt;p&gt;I updated &lt;code&gt;.gitignore&lt;/code&gt; to exclude sensitive files and directories.&lt;/p&gt;

&lt;p&gt;I also created &lt;code&gt;.env.example&lt;/code&gt; with placeholder values so other developers could understand the configuration without seeing real credentials.&lt;/p&gt;

&lt;p&gt;Before publishing, I checked the repository contents.&lt;/p&gt;

&lt;p&gt;The committed project included the Python source files, dependency list, README, and safe configuration template.&lt;/p&gt;

&lt;p&gt;It did not include the local credential files.&lt;/p&gt;

&lt;p&gt;Finally, I pushed the repository to GitHub.&lt;/p&gt;

&lt;p&gt;Seeing the successful push was a satisfying moment because the project had gone from a local experiment to something other developers could explore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; A successful GitHub push is only a success if the repository is safe to publish.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I Chose Switch Console and Mattermost
&lt;/h1&gt;

&lt;p&gt;I didn't want Joe to be just another Python script that prints email information in a terminal.&lt;/p&gt;

&lt;p&gt;I wanted a conversational assistant.&lt;/p&gt;

&lt;p&gt;Switch Console provides the agent environment.&lt;/p&gt;

&lt;p&gt;Mattermost provides the chat interface where I interact with Joe.&lt;/p&gt;

&lt;p&gt;The Python bridge connects that environment to Gmail.&lt;/p&gt;

&lt;p&gt;This separation makes the system easier to understand.&lt;/p&gt;

&lt;p&gt;Each component has a specific responsibility.&lt;/p&gt;

&lt;p&gt;The Gmail API retrieves information.&lt;/p&gt;

&lt;p&gt;The bridge exposes a limited interface.&lt;/p&gt;

&lt;p&gt;The helper communicates with the bridge.&lt;/p&gt;

&lt;p&gt;Joe interprets requests and generates responses.&lt;/p&gt;

&lt;p&gt;Mattermost displays the conversation.&lt;/p&gt;

&lt;p&gt;Instead of trying to make one component do everything, I connected several smaller components.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Security Decision I'm Most Glad I Made
&lt;/h1&gt;

&lt;p&gt;Joe can read email metadata.&lt;/p&gt;

&lt;p&gt;Joe can search Gmail.&lt;/p&gt;

&lt;p&gt;Joe can draft replies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Joe cannot send emails through the current integration.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not a hidden feature waiting for an approval button.&lt;/p&gt;

&lt;p&gt;Sending is simply not implemented.&lt;/p&gt;

&lt;p&gt;The Gmail OAuth scope is read-only, and the bridge exposes read operations.&lt;/p&gt;

&lt;p&gt;That creates a useful boundary for the prototype.&lt;/p&gt;

&lt;p&gt;The assistant can help me prepare a response, but I remain responsible for reviewing and sending it.&lt;/p&gt;

&lt;p&gt;There is an important distinction between telling an agent not to send emails and giving it no email-sending capability.&lt;/p&gt;

&lt;p&gt;For this version, I chose the latter.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I Tested
&lt;/h1&gt;

&lt;p&gt;I tested Joe through the Mattermost room using real requests.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Check recent Gmail messages&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retrieve sender, subject, and date&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suggest which emails need attention&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search for hackathon emails&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Draft a proposed reply&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Make the reply shorter and friendlier&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connect through the authenticated Python bridge&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publish source code to GitHub&lt;/td&gt;
&lt;td&gt;Successful&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These tests demonstrate the core workflow.&lt;/p&gt;

&lt;p&gt;They don't establish that Joe's priority suggestions are always correct or that drafts always reflect the full meaning of an email.&lt;/p&gt;

&lt;p&gt;The current bridge doesn't provide email bodies, so those limitations matter.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I Learned About Building AI Agents
&lt;/h1&gt;

&lt;p&gt;Three lessons stood out.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Integration Is Often Harder Than the AI
&lt;/h3&gt;

&lt;p&gt;The most difficult parts weren't writing prompts.&lt;/p&gt;

&lt;p&gt;They were getting OAuth, Python, local HTTP requests, Switch Console, Docker, and Mattermost to work together.&lt;/p&gt;

&lt;p&gt;The AI experience depended on the reliability of everything underneath it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Smaller Tools Make Better Building Blocks
&lt;/h3&gt;

&lt;p&gt;Creating &lt;code&gt;gmail_helper.py&lt;/code&gt; was a small change, but it made the workflow easier to operate.&lt;/p&gt;

&lt;p&gt;Instead of giving Joe a complicated sequence of HTTP instructions, I gave it a focused tool.&lt;/p&gt;

&lt;p&gt;That reduced unnecessary complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. An AI Assistant Doesn't Need Full Control to Be Useful
&lt;/h3&gt;

&lt;p&gt;Joe doesn't send emails.&lt;/p&gt;

&lt;p&gt;It doesn't delete messages.&lt;/p&gt;

&lt;p&gt;It doesn't modify my inbox.&lt;/p&gt;

&lt;p&gt;And it still helps with real tasks.&lt;/p&gt;

&lt;p&gt;Sometimes the most useful automation is the one that prepares the work and leaves the final decision to the human.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Joe Doesn't Do Yet
&lt;/h1&gt;

&lt;p&gt;I want to be clear about the limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No automatic email sending.&lt;/strong&gt; Joe drafts responses but cannot send them through the current Gmail integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No full email-body retrieval through the bridge.&lt;/strong&gt; The current bridge returns sender, subject, and date, so summaries and drafts are limited by that information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No public cloud deployment.&lt;/strong&gt; The bridge runs locally and must remain active for Joe to access Gmail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No autonomous background monitoring.&lt;/strong&gt; Joe responds to requests; it doesn't continuously monitor the inbox and independently notify users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No guaranteed priority accuracy.&lt;/strong&gt; Prioritization is an AI-generated suggestion based on available metadata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local setup is required.&lt;/strong&gt; Running the complete experience requires the Python environment, Gmail authorization, Switch Console, and Mattermost services.&lt;/p&gt;

&lt;p&gt;These aren't features I'm claiming to have completed.&lt;/p&gt;

&lt;p&gt;They're opportunities for future development.&lt;/p&gt;




&lt;h1&gt;
  
  
  What's Next?
&lt;/h1&gt;

&lt;p&gt;If I continue building Joe, I'd like to explore:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Secure access to full email bodies for more accurate summaries.&lt;/li&gt;
&lt;li&gt;A reviewed, explicit approval workflow for sending drafted replies.&lt;/li&gt;
&lt;li&gt;Scheduled inbox summaries.&lt;/li&gt;
&lt;li&gt;Better email categorization and priority signals.&lt;/li&gt;
&lt;li&gt;A deployment option that doesn't require manually running a local bridge.&lt;/li&gt;
&lt;li&gt;More robust automated tests and monitoring.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But for the hackathon, my goal was to build a working end-to-end AI email assistant.&lt;/p&gt;

&lt;p&gt;And I achieved that core workflow.&lt;/p&gt;




&lt;h1&gt;
  
  
  Try Joe AI Email Assistant
&lt;/h1&gt;

&lt;p&gt;The source code is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/engineerkrish/joe-ai-email-assistant" rel="noopener noreferrer"&gt;https://github.com/engineerkrish/joe-ai-email-assistant&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The repository contains the Python application, local Gmail bridge, helper script, dependencies, configuration example, and setup documentation.&lt;/p&gt;

&lt;p&gt;You'll need to configure your own Gmail OAuth credentials and local environment.&lt;/p&gt;

&lt;p&gt;The README explains the project structure and setup process.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;When I started, I thought the hardest part would be making an AI understand emails.&lt;/p&gt;

&lt;p&gt;I was wrong.&lt;/p&gt;

&lt;p&gt;The hardest part was getting all the systems around the AI to communicate reliably.&lt;/p&gt;

&lt;p&gt;Gmail authentication.&lt;/p&gt;

&lt;p&gt;Missing connector functionality.&lt;/p&gt;

&lt;p&gt;A custom Python bridge.&lt;/p&gt;

&lt;p&gt;Token authentication.&lt;/p&gt;

&lt;p&gt;Docker and Mattermost connectivity.&lt;/p&gt;

&lt;p&gt;Gmail search support.&lt;/p&gt;

&lt;p&gt;Protecting secrets before publishing.&lt;/p&gt;

&lt;p&gt;Each issue forced me to understand a different part of the system.&lt;/p&gt;

&lt;p&gt;And each solution made the project more complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Joe AI Email Assistant started as an idea to make email management easier. It became a practical lesson in building secure, connected AI agents.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The best part?&lt;/p&gt;

&lt;p&gt;I can now open Mattermost, type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@joe Check my emails.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And Joe actually does.&lt;/p&gt;

&lt;p&gt;That's a small interaction built on a lot of engineering.&lt;/p&gt;

&lt;p&gt;And that's what made this project worth building.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Built for the Flip the Switch Hackathon 2026.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/engineerkrish/joe-ai-email-assistant" rel="noopener noreferrer"&gt;https://github.com/engineerkrish/joe-ai-email-assistant&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="https://youtu.be/Q9CcvPKpbho?si=n_RmI6IHP4l8NZOn" rel="noopener noreferrer"&gt;https://youtu.be/Q9CcvPKpbho?si=n_RmI6IHP4l8NZOn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agentaichallenge</category>
      <category>python</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
