Build an AI-Powered Email Manager with OAuth

Explore a sophisticated, production-ready email management application that demonstrates advanced Fiberwise patterns. Learn from real-world OAuth implementation, AI agent architecture, and professional frontend development through hands-on examination of working code.

โฑ๏ธ 45-60 minutes ๐Ÿ“š Advanced ๐Ÿ“ง OAuth + AI

๐Ÿš€ What You'll Explore

A sophisticated, production-ready email management application featuring:

  • โœ… Enterprise OAuth Architecture: Multi-provider authentication (Gmail, Outlook, Yahoo) with automatic token management
  • โœ… Advanced AI Agent System: 2500+ line agent with 10+ email operations including search, analysis, sending, and labeling
  • โœ… Intelligent Data Models: Three optimized models for email caching, AI analysis results, and custom prompt templates
  • โœ… Professional Frontend: Component-based architecture with real-time updates and responsive design
  • โœ… AI-Powered Features: Sentiment analysis, priority detection, topic extraction, and customizable AI workflows
  • โœ… Production Patterns: Security best practices, error handling, and scalable architecture patterns

Key Insight: This isn't a tutorial where you build from scratch - it's an exploration of a real, sophisticated application that demonstrates advanced Fiberwise patterns and production-ready code.

๐Ÿ“š What You'll Learn

Real-World OAuth Implementation

  • Multi-Provider OAuth: See how Gmail, Outlook, and Yahoo OAuth are configured and managed
  • Secure Architecture: Understand credential storage, token refresh, and permission management
  • Error Recovery: Learn robust patterns for handling authentication failures and re-authorization
  • Provider Abstraction: Study how different email providers are unified under a common interface

Advanced Agent Development

  • Complex Agent Architecture: Analyze a 2500+ line production agent with multiple operations
  • AI Integration Patterns: See how LLMs are integrated for email analysis with customizable prompts
  • Data Model Design: Study three different data models optimized for different use cases
  • Performance Optimization: Learn caching strategies and efficient data retrieval patterns

Professional Frontend Patterns

  • Component Architecture: Explore modular, reusable web components for complex UIs
  • State Management: Understand real-time data binding and user interface updates
  • User Experience: Study professional UX patterns for email management and analytics
  • API Integration: See how frontend components interact with Fiberwise backend services

๐Ÿ“‹ Prerequisites: Your Setup Checklist

Before you begin, you need a fully configured Fiberwise environment. This is the foundation for building any app on the platform.

๐Ÿ”ง Required Setup

โœ… All Set?

Once all boxes are checked, you are ready to proceed. If not, please complete the linked guides first.

๐Ÿ› ๏ธ Step 1: Get the Email App Code

The email agent app is located in the fiber-apps repository. Let's navigate to it and explore the structure.

1
Navigate to Email Agent App
cd fiber-apps/email-agent-app
2
Explore the App Structure
ls -la
# You'll see:
# app_manifest.yaml  - App configuration and data models
# index.js           - App entry point and initialization
# src/               - Frontend components and services
# agents/            - AI agents for email analysis
# functions/         - Email fetching and processing functions

๐Ÿ“ App Architecture

๐Ÿ“ email-agent-app/
๐Ÿ“„ app_manifest.yaml - App config, models, OAuth settings
๐Ÿ“„ index.js - Frontend initialization
๐Ÿ“ src/
๐Ÿ“ components/ - UI components
๐Ÿ“ services/ - Email services
๐Ÿ“ agents/
๐Ÿ“„ email_agent.py - AI email analysis
๐Ÿ“ functions/
๐Ÿ“„ get_recent_emails.py - Fetch emails from Gmail
๐Ÿ“„ get_email.py - Get individual email details

๐Ÿ“‹ App Manifest Deep Dive

# app_manifest.yaml - The heart of your Fiberwise app
app:
  name: Email Agent App
  app_slug: email-agent-app
  version: 1.0.145
  description: Multi-provider email client with AI-powered analysis
  category: productivity
  icon: fas fa-envelope
  publisher: FiberWise

models:
  - name: Email Prompt Template
    model_slug: email_prompt_templates
    description: User-specific prompt templates for email analysis and actions
    fields:
      - name: Template ID
        field_column: template_id
        type: uuid
        is_primary_key: true
        required: true
      - name: User ID
        field_column: user_id
        type: string
        required: true
      - name: App ID
        field_column: app_id
        type: string
        required: true
      - name: Template Name
        field_column: template_name
        type: string
        required: true
      - name: Template Content
        field_column: template_content
        type: text
        required: true
      - name: Description
        field_column: description
        type: string
        required: false

  - name: Email Analysis
    model_slug: email_analyses
    description: Saved email analysis results
    fields:
      - name: Analysis ID
        field_column: analysis_id
        type: uuid
        is_primary_key: true
        required: true
      - name: User ID
        field_column: user_id
        type: string
        required: true
      - name: Provider ID
        field_column: provider_id
        type: string
        required: true
      - name: Message ID
        field_column: message_id
        type: string
        required: true
      - name: Subject
        field_column: subject
        type: string
      - name: Sender
        field_column: sender
        type: string
      - name: Summary
        field_column: summary
        type: text
      - name: Sentiment
        field_column: sentiment
        type: string
      - name: Priority
        field_column: priority
        type: string
      - name: Topics
        field_column: topics
        type: json
      - name: Action Items
        field_column: action_items
        type: json
      - name: Suggested Labels
        field_column: suggested_labels
        type: json

  - name: Cached Email Messages
    model_slug: cached_messages
    description: Cached email messages for faster inbox loading
    fields:
      - name: Cache ID
        field_column: cache_id
        type: uuid
        is_primary_key: true
        required: true
      - name: Connection ID
        field_column: connection_id
        type: string
        required: true
      - name: Message ID
        field_column: message_id
        type: string
        required: true
      - name: Subject
        field_column: subject
        type: string
      - name: Sender
        field_column: sender
        type: string
      - name: Sender Name
        field_column: sender_name
        type: string
      - name: Recipients
        field_column: recipients
        type: json
      - name: Body Preview
        field_column: body_preview
        type: text
      - name: Body Full
        field_column: body_full
        type: text
      - name: Thread ID
        field_column: thread_id
        type: string
      - name: Labels
        field_column: labels
        type: json
      - name: Is Read
        field_column: is_read
        type: boolean
      - name: Has Attachments
        field_column: has_attachments
        type: boolean
      - name: Message Date
        field_column: message_date
        type: timestamp

agents:
  - name: email-agent
    implementation_path: agents/email_agent.py
    language: python
    agent_type_id: custom
    description: Agent for working with emails across different providers using OAuth
    permissions:
      - credentials.oauth
      - data.read
      - data.write
      - llm.completion
    allowed_context_variables:
      - user_id
      - app_id
      - provider_id
      - template_name

functions:
  - name: get_recent_emails
    implementation_path: functions/get_recent_emails.py
    description: Fetches the most recent emails from a specified provider
    input_schema:
      properties:
        authenticator_id:
          description: The ID of the email authenticator to fetch from
          type: string
        label:
          default: INBOX
          description: Email label/folder to fetch from (e.g., INBOX, SENT)
          type: string
        limit:
          default: 10
          description: Number of emails to fetch (10, 50, or 100)
          enum: [10, 50, 100]
          type: integer
      required:
        - authenticator_id

  - name: get_email
    implementation_path: functions/get_email.py
    description: Fetches detailed email content by message ID
    input_schema:
      properties:
        authenticator_id:
          description: The ID of the email authenticator connection
          type: string
        message_id:
          description: The ID of the message to fetch
          type: string
      required:
        - authenticator_id
        - message_id

oauth:
  authenticators:
    - name: Gmail
      type: oauth2
      scopes:
        - openid
        - profile
        - email
        - https://www.googleapis.com/auth/gmail.readonly
        - https://www.googleapis.com/auth/gmail.send
      file: .fiber/local/oauth/fiberwise_developer.json
      additional_params:
        access_type: offline
        prompt: consent

routes:
  - component: email-agent-app
    icon: fas fa-envelope
    path: /
    title: Email Client
  - component: email-settings
    icon: fas fa-cog
    path: /settings
    title: Settings
  - component: email-connections
    icon: fas fa-plug
    path: /settings/email-connections
    title: Email Connections
  - component: prompt-templates
    icon: fas fa-book
    path: /templates
    title: Prompt Templates
  - component: email-analytics
    icon: fas fa-chart-bar
    path: /analytics
    title: Analytics

๐ŸŽฏ Key Architecture Insights

  • OAuth Integration: Complete Gmail OAuth setup with proper scopes
  • Data Models: Separate models for email cache and AI analysis results
  • Agent Permissions: Granular permissions for LLM access and data operations
  • Function-Based Architecture: Serverless functions for email fetching and processing

๐Ÿ” Step 2: Configure OAuth for Gmail

To access Gmail, we need to set up OAuth credentials. This allows users to securely connect their Gmail accounts.

๐Ÿ” OAuth Flow Overview

๐Ÿ‘ค
User clicks "Connect Gmail"
โ†’
๐Ÿ”
Redirect to Google OAuth
โ†’
โœ…
User grants permissions
โ†’
๐Ÿ“ง
App can access emails
1
Create Google Cloud Project

Go to Google Cloud Console and create a new project.

# Project Name: "My Email Agent App"
# Project ID: Will be auto-generated (e.g., my-email-agent-app-123456)
2
Enable Gmail API

In your Google Cloud project, enable the Gmail API:

  1. Navigate to "APIs & Services" โ†’ "Library"
  2. Search for "Gmail API"
  3. Click "Enable"
3
Create OAuth Credentials

Set up OAuth 2.0 credentials for web application:

Application Type: Web application
Name: Email Agent App
Authorized redirect URIs: http://localhost:5757/api/v1/oauth/callback/fiberwise-developer
4
Download OAuth Configuration

Download the OAuth JSON credentials from Google Cloud Console:

  1. Go to "APIs & Services" โ†’ "Credentials"
  2. Find your OAuth 2.0 Client ID
  3. Click the download icon to get the JSON file
  4. Save it as oauth-credentials.json in your project directory
5
Import OAuth Configuration with CLI

Use the Fiberwise CLI to automatically import and configure OAuth:

# Import OAuth configuration automatically
fiber app oauth import oauth-credentials.json

# Verify import was successful
fiber app oauth list

โœ… The CLI automatically detects the Google OAuth format and converts it to Fiberwise configuration

3. Create OAuth Credentials

  1. Go to APIs & Services โ†’ Credentials
  2. Click "Create Credentials" โ†’ "OAuth 2.0 Client IDs"
  3. Application type: "Web application"
  4. Add redirect URI: http://localhost:7001/api/v1/credentials/auth/callback/google

Configure OAuth in Fiberwise

The email app already includes OAuth configuration in its manifest. Here's how it works:

# From app_manifest.yaml - OAuth authenticators section
oauth:
  authenticators:
  - additional_params:
      access_type: offline
      prompt: consent
    file: .fiber/local/oauth/fiberwise_developer.json
    name: Gmail
    scopes:
    - openid
    - profile
    - email
    - https://www.googleapis.com/auth/gmail.readonly
    - https://www.googleapis.com/auth/gmail.send
    type: oauth2

To use this with your own Google credentials, you'll need to:

# Create the OAuth credentials file
mkdir -p .fiber/local/oauth

# Add your Google OAuth credentials to the file
cat > .fiber/local/oauth/fiberwise_developer.json << EOF
{
  "client_id": "YOUR_GOOGLE_CLIENT_ID",
  "client_secret": "YOUR_GOOGLE_CLIENT_SECRET",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "redirect_uris": ["http://localhost:5757/auth/callback/google"]
}
EOF

# Install the app with OAuth configuration
fiber app install email-agent-app

โœ… OAuth Authenticator Registration

When you install the app, FiberWise automatically registers the OAuth authenticators from the manifest. No additional CLI commands needed!

๐Ÿ“Š Step 3: Understand the Data Models

The email app uses three main data models to store and organize email data efficiently.

๐Ÿ“ง cached_messages

Stores email metadata for fast loading and offline access

๐Ÿ†” cache_id - Primary key (UUID)
๐Ÿ”— connection_id - OAuth connection identifier
โœ‰๏ธ message_id - Original email message ID from provider
๐Ÿ“ subject - Email subject line
๐Ÿ‘ค sender - Email sender address
๏ฟฝ sender_name - Display name of sender
๐Ÿ“ฅ recipients - JSON array of recipients
๐Ÿ“– body_preview - Truncated email content
๐Ÿ“– body_full - Complete email content
๐Ÿงต thread_id - Email thread identifier
๐Ÿท๏ธ labels - JSON array of email labels/folders
๐Ÿ‘๏ธ is_read - Read/unread status
๐Ÿ“Ž has_attachments - Attachment indicator
๐Ÿ“… message_date - When email was sent
โฐ cached_at - When cached in FiberWise

๐Ÿง  email_analyses

AI-generated insights and analysis results

๐Ÿ†” analysis_id - Primary key (UUID)
๏ฟฝ user_id - User who owns this analysis
๐Ÿ”— provider_id - Email provider connection
โœ‰๏ธ message_id - Related email message
๐Ÿ“ subject - Email subject
๐Ÿ‘ค sender - Email sender
๐Ÿ“Š summary - AI-generated summary
๐Ÿ˜Š sentiment - positive/negative/neutral
โญ priority - high/medium/low importance
๐Ÿท๏ธ topics - JSON array of identified topics
โœ… action_items - JSON array of action items
๐ŸŽฏ suggested_labels - JSON array of label suggestions
๐Ÿ“‹ template_used - AI template name used
๐Ÿ“… analysis_date - When analysis was performed

๐Ÿ“ email_prompt_templates

User-created AI prompt templates for custom analysis

๐Ÿ†” template_id - Primary key (UUID)
๐Ÿ‘ค user_id - Template owner
๐Ÿ“ฑ app_id - App context
๐Ÿ“› template_name - Unique template name
๏ฟฝ template_content - Prompt with placeholders
๏ฟฝ description - Optional description
๐Ÿ“… created_at - Creation timestamp
๏ฟฝ updated_at - Last modified timestamp

๐Ÿš€ Step 4: Install and Run the App

Now let's install the email app and see it in action.

1
Install the App
fiber app install email-agent-app

โœ… This installs the app, creates database tables, and registers all components.

2
Start the Development Server
fiber start --dev

โœ… Your email app is now running at http://localhost:5757

3
Access the Email App

Navigate to the email app in your browser:

# Open in browser:
http://localhost:5757/email-agent-app

๐Ÿ”— Step 5: Connect Your Gmail Account

Let's connect your Gmail account and start managing emails with AI.

1
Navigate to Email Connections

In the email app, go to Settings โ†’ Email Connections

๐Ÿ“ธ
Screenshot: Email Connections Page

Shows the Settings โ†’ Email Connections interface with available provider options (Gmail, Outlook, Yahoo) and "Connect" buttons for each provider.

2
Add Gmail Connection

Click "Add Connection" and select "Gmail (OAuth)"

3
Authorize Access

Complete the OAuth flow by granting permissions to:

  • Read your email messages
  • Send emails on your behalf
  • Access basic profile information
๐Ÿ“ธ
Screenshot: Connected State

Shows the Email Connections page after successful OAuth authorization, with Gmail provider showing "Connected โœ“" status and user's email address displayed.

4
Load Recent Emails

Once connected, click "Load Recent Emails" to fetch your latest messages

โœ… Your emails will be cached locally for fast access and AI analysis

๐Ÿ’ป Step 5.5: Frontend Connection Management

Now let's implement the actual frontend code to manage OAuth connections using the credential service.

๐Ÿ“ฑ Credential Service Integration

The email app uses a dedicated credential service to handle OAuth connections securely. Here's how to integrate it:

// src/credential-service.js - Production credential management
class CredentialService {
    constructor() {
        // Uses FiberWise AppBridge for secure communication
        this.router = window.AppBridge?.router;
    }

    // Connect to OAuth provider (Gmail, Outlook, etc.)
    async connectAuthenticator(providerId) {
        try {
            // Use AppBridge credential service for OAuth connections
            const connection = await window.AppBridge.credentials.connect({
                provider_type: 'oauth2',
                provider_id: providerId,
                scopes: ['email', 'profile'] // Provider-specific scopes
            });
            return { success: true, connection };
        } catch (error) {
            console.error('Connection failed:', error);
            return { success: false, error: error.message };
        }
    }

    // List all active connections for current user
    async listConnections() {
        try {
            const response = await window.AppBridge.credentials.list();
            return response.connections || [];
        } catch (error) {
            console.error('Failed to list connections:', error);
            return [];
        }
    }

    // Check if provider is connected
    async isConnected(providerId) {
        const connections = await this.listConnections();
        return connections.some(conn => 
            conn.provider_id === providerId && conn.status === 'active'
        );
    }

    // Revoke connection
    async revokeConnection(connectionId) {
        try {
            await window.AppBridge.credentials.revoke(connectionId);
            return { success: true };
        } catch (error) {
            return { success: false, error: error.message };
        }
    }
}

๐Ÿ”Œ Email Connections Component

Here's the actual web component that manages email provider connections:

// src/components/email-connections.js - Production connection UI
class EmailConnectionsComponent extends HTMLElement {
    constructor() {
        super();
        this.credentialService = new CredentialService();
        this.connections = [];
        this.pendingConnections = new Set();
    }

    async connectedCallback() {
        await this.loadConnections();
        this.render();
    }

    async loadConnections() {
        this.connections = await this.credentialService.listConnections();
    }

    async connectProvider(providerId) {
        // Show loading state
        this.pendingConnections.add(providerId);
        this.render();

        try {
            const result = await this.credentialService.connectAuthenticator(providerId);
            
            if (result.success) {
                // Refresh connections list
                await this.loadConnections();
                this.showSuccess(`Connected to ${providerId} successfully!`);
            } else {
                this.showError(`Failed to connect: ${result.error}`);
            }
        } catch (error) {
            this.showError(`Connection error: ${error.message}`);
        } finally {
            this.pendingConnections.delete(providerId);
            this.render();
        }
    }

    render() {
        this.innerHTML = `
            
        `;
        this.attachEventListeners();
    }

    renderProviderCard(providerId, name, icon) {
        const isConnected = this.connections.some(c => c.provider_id === providerId);
        const isPending = this.pendingConnections.has(providerId);
        
        return `
            
${icon}

${name}

`; } attachEventListeners() { this.querySelectorAll('.connect-btn').forEach(btn => { btn.addEventListener('click', async (e) => { const providerId = e.target.dataset.provider; if (!this.pendingConnections.has(providerId)) { await this.connectProvider(providerId); } }); }); } } // Register the component customElements.define('email-connections', EmailConnectionsComponent);

๐ŸŽฏ Key Integration Patterns

๐Ÿ” Secure OAuth Flow

  • Uses FiberWise AppBridge for secure communication
  • All tokens handled server-side, never exposed to frontend
  • Automatic token refresh handled transparently

๐Ÿ”„ Real-time Updates

  • Connection status updates immediately
  • Pending states during OAuth flow
  • Error handling with user-friendly messages

๐Ÿงฉ Component Architecture

  • Reusable web components
  • Service layer separation
  • Event-driven UI updates

๐Ÿค– Step 6: AI Email Analysis

The email agent app features a sophisticated AI analysis system powered by the email_agent.py file - a 2500+ line production agent that demonstrates advanced Fiberwise patterns.

๐Ÿง  Real Agent Architecture

The email_agent.py file showcases how to build enterprise-grade agents with:

๐Ÿค– What the AI Agent Provides

๏ฟฝ
Multi-Provider Search

Advanced email search across Gmail, Outlook, and Yahoo with unified API

๐Ÿง 
AI-Powered Analysis

LLM integration for sentiment, priority, topics, and action items with customizable templates

๐Ÿ“Š
Real-time Updates

Progress notifications and status updates through Fiberwise realtime system

๐Ÿ’พ
Performance Caching

Intelligent email caching to database for faster subsequent access and analysis

๐ŸŽฏ Agent Operations in Action

The agent supports 10+ different operations including search_emails, analyze_email, send_email, and update_labels. Here's how analysis works:

1
Dependency Injection Pattern

The agent inherits from FiberAgent and receives injected services from the platform:

async def run_agent(
    self, 
    input_data: Dict[str, Any], 
    fiber: FiberApp,                    # Platform SDK access
    llm_service: LLMProviderService,    # AI/LLM integration
    oauth_service: BaseCredentialService # OAuth credential management
) -> Dict[str, Any]:
2
Analyze an Email with AI

The agent processes email analysis requests with structured validation and real-time updates:

// Example AI analysis result from the agent:
{
  "success": true,
  "analysis": {
    "summary": "Meeting request for Q4 planning session with stakeholders",
    "sentiment": "positive",
    "priority": "high", 
    "topics": ["meeting", "Q4 planning", "stakeholders"],
    "action_items": ["Schedule follow-up", "Review Q4 documents"],
    "suggested_labels": ["meetings", "urgent", "Q4"],
    "analysis_id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "message_id": "gmail-msg-12345",
  "processed_at": "2025-09-15T10:30:00Z"
}
3
Real-time Progress Updates

The agent provides professional user experience with status notifications during processing:

# From email_agent.py - Real-time status updates
await self.send_agent_update(
    fiber=fiber,
    task_id=task_id,
    status="processing",
    progress=0.5,
    message="Analyzing email content with AI...",
    provider_id=connection_id,
    operation="analyze_email"
)

โšก Critical FIBER.data API Understanding

๐Ÿšจ Critical Issue: Data Structure in FIBER.data API

Problem: The most common issue when building email apps is accessing data incorrectly from the FIBER.data API. This causes FIBER.data.listItems() to appear to return 0 results when data actually exists.

Understanding API Response Structure

The FIBER.data API returns items with nested data structure:

{
  "items": [
    {
      "item_id": "uuid-123",
      "app_id": "your-app-id", 
      "model_id": "model-uuid",
      "created_at": "2024-01-01T10:00:00Z",
      "updated_at": "2024-01-01T10:00:00Z",
      "data": {
        "subject": "Your actual email subject",
        "sender": "[email protected]",
        "connection_id": "gmail-connection-123",
        "labels": ["INBOX", "IMPORTANT"]
      }
    }
  ],
  "total": 10,
  "page": 1,
  "pages": 1
}

โŒ Common Mistake (Returns Undefined)

// This is WRONG - accessing fields directly on item
const result = await FIBER.data.listItems('cached_messages');
result.items.filter(item => 
  item.subject && // undefined!
  item.connection_id === connectionId // undefined!
);

โœ… Correct Implementation

// This is CORRECT - accessing fields via item.data
const result = await FIBER.data.listItems('cached_messages');
result.items.filter(item => 
  item.data.subject && // โœ… Works!
  item.data.connection_id === connectionId // โœ… Works!
);

Real Email App Example

Here's the actual working code from the email search component:

// src/components/email-search.js
async loadCachedMessages(limit) {
  try {
    // Load cached messages using FIBER.data.listItems
    const result = await FIBER.data.listItems('cached_messages', {
      limit: limit * 2 // Get more to account for filtering
      // Note: sort parameter not supported by API
    });
    
    if (result && result.items) {
      // Filter by connection and label client-side
      const filteredMessages = result.items
        .filter(msg => 
          msg.data.connection_id === this.connectionId && 
          msg.data.labels && msg.data.labels.includes(this.searchLabel)
        )
        .map(msg => ({
          id: msg.data.message_id,
          subject: msg.data.subject,
          sender: msg.data.sender,
          from: msg.data.sender,
          date: msg.data.message_date,
          snippet: msg.data.body_preview
        }))
        .sort((a, b) => {
          // Sort by message date, newest first
          const dateA = new Date(a.date);
          const dateB = new Date(b.date);
          return dateB - dateA;
        })
        .slice(0, limit); // Limit to requested amount after sorting

      console.log(`Loaded ${filteredMessages.length} cached messages`);
      return filteredMessages;
    }
    
    return [];
  } catch (error) {
    console.error('Error loading cached messages:', error);
    return [];
  }
}

๐ŸŽฏ Key Insights

API Limitations & Workarounds

โŒ Not Supported

  • Server-side sorting
  • Complex filtering
  • Full-text search
  • Aggregation functions

โœ… Workarounds

  • Client-side sorting with JavaScript
  • Fetch more data and filter locally
  • Use simple filters in listItems()
  • Implement pagination for large datasets

๐Ÿš€ Step 3: Deploy and Test the App

Install the App

# Make sure Fiberwise server is running
fiber start --dev

# Install the email agent app
fiber app install email-agent-app

# Verify installation
fiber app list

Access the Email App

Open your browser and navigate to the email app:

# Open in browser:
http://localhost:5757/email-agent-app

Connect Your Gmail Account

Now the fun part - let's connect your Gmail account:

  1. In the email app, go to Settings โ†’ Email Connections
  2. Click "Add Connection" and select "Gmail (OAuth)"
  3. Complete the OAuth flow by granting permissions to:
    • Read your email messages
    • Send emails on your behalf
    • Access basic profile information
  4. Once connected, click "Load Recent Emails" to fetch your latest messages

๐ŸŽฌ What Happens During OAuth Flow

  1. Initiate: App redirects to Google's OAuth server
  2. Authorize: You grant permissions to access Gmail
  3. Callback: Google redirects back with authorization code
  4. Exchange: App exchanges code for access token
  5. Store: Token is securely stored in Fiberwise credentials

Test Email Fetching

Once connected, test that everything works:

# Test fetching emails via CLI
fiber activate email-agent --input-data '{
  "action": "fetch_emails",
  "provider": "google",
  "limit": 5
}'

๐Ÿ”ง Common Issues & Solutions

๐Ÿง  Step 4: Explore AI-Powered Email Features

Email Analysis with AI

The real power of this app comes from AI analysis. Let's see it in action:

๐Ÿ“ง Try These AI Features

  1. Smart Summaries: Click "Analyze" on any email to get an AI-generated summary
  2. Sentiment Detection: See if emails are positive, negative, or neutral
  3. Priority Assessment: AI determines if emails need urgent attention
  4. Topic Extraction: Identify key themes and subjects automatically

Understanding the Email Agent

Let's look at how the AI agent processes emails:

# agents/email_agent.py - The brain of our email processing
from fiberwise_sdk import FiberApp
import json
import uuid
import datetime
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

fiber = FiberApp()

class EmailAgent:
    """
    Comprehensive email agent supporting multiple providers and AI operations
    """
    
    def search_emails(self, authenticator_id, query, max_results=10):
        """
        Search emails using Gmail's advanced search syntax
        """
        credentials = self._get_credentials(authenticator_id)
        service = build('gmail', 'v1', credentials=credentials)
        
        results = service.users().messages().list(
            userId='me',
            q=query,
            maxResults=max_results
        ).execute()
        
        messages = []
        for msg in results.get('messages', []):
            message_detail = service.users().messages().get(
                userId='me', 
                id=msg['id'],
                format='metadata',
                metadataHeaders=['Subject', 'From', 'Date']
            ).execute()
            
            headers = {h['name']: h['value'] for h in message_detail['payload']['headers']}
            messages.append({
                'id': msg['id'],
                'subject': headers.get('Subject', ''),
                'sender': headers.get('From', ''),
                'date': headers.get('Date', ''),
                'snippet': message_detail.get('snippet', '')
            })
        
        return {'messages': messages, 'total_found': len(messages)}
    
    def analyze_email(self, authenticator_id, message_id, template_name=None):
        """
        Perform AI analysis on an email using customizable templates
        """
        # Get the full email content
        email_data = self.get_email(authenticator_id, message_id)
        
        # Get analysis template (user custom or default)
        if template_name:
            template = self._get_user_template(template_name)
        else:
            template = self._get_default_template()
        
        # Format prompt with email content
        prompt = template.format(
            subject=email_data['subject'],
            sender=email_data['sender'],
            body=email_data['body'][:2000]  # Limit for LLM context
        )
        
        # Use LLM for analysis
        analysis_result = fiber.llm.complete(
            prompt=prompt,
            temperature=0.3,
            max_tokens=1000
        )
        
        # Parse structured analysis
        try:
            analysis = json.loads(analysis_result['content'])
        except:
            # Fallback if JSON parsing fails
            analysis = {
                'summary': analysis_result['content'][:200],
                'sentiment': 'neutral',
                'priority': 'medium',
                'topics': [],
                'action_items': []
            }
        
        # Save analysis to database
        analysis_record = {
            'analysis_id': str(uuid.uuid4()),
            'user_id': fiber.context.user_id,
            'provider_id': authenticator_id,
            'message_id': message_id,
            'subject': email_data['subject'],
            'sender': email_data['sender'],
            'summary': analysis.get('summary', ''),
            'sentiment': analysis.get('sentiment', 'neutral'),
            'priority': analysis.get('priority', 'medium'),
            'topics': analysis.get('topics', []),
            'action_items': analysis.get('action_items', []),
            'suggested_labels': analysis.get('suggested_labels', [])
        }
        
        fiber.data.create_record('email_analyses', analysis_record)
        
        return analysis
    
    def send_email(self, authenticator_id, to_email, subject, body, cc=None, bcc=None):
        """
        Send an email through the connected provider
        """
        credentials = self._get_credentials(authenticator_id)
        service = build('gmail', 'v1', credentials=credentials)
        
        # Construct email message
        message = self._create_message(to_email, subject, body, cc, bcc)
        
        # Send the email
        try:
            sent_message = service.users().messages().send(
                userId='me',
                body=message
            ).execute()
            
            return {
                'success': True,
                'message_id': sent_message['id'],
                'thread_id': sent_message.get('threadId')
            }
        except Exception as e:
            return {
                'success': False,
                'error': str(e)
            }
    
    def _get_default_template(self):
        """Default email analysis template"""
        return """
        Analyze this email and return a JSON response with the following structure:
        
        Email Subject: {subject}
        From: {sender}
        Body: {body}
        
        Provide analysis in this exact JSON format:
        {{
            "summary": "Brief 2-3 sentence summary of the email",
            "sentiment": "positive/negative/neutral",
            "priority": "low/medium/high/urgent",
            "topics": ["topic1", "topic2", "topic3"],
            "action_items": ["action1", "action2"],
            "suggested_labels": ["label1", "label2"]
        }}
        """
    
    def _get_user_template(self, template_name):
        """Get user's custom template"""
        templates = fiber.data.query_records('email_prompt_templates', {
            'template_name': template_name,
            'user_id': fiber.context.user_id
        })
        
        if templates:
            return templates[0]['template_content']
        else:
            return self._get_default_template()
    
    def _get_credentials(self, authenticator_id):
        """Get OAuth credentials for email provider"""
        creds_data = fiber.oauth.get_credentials(authenticator_id)
        return Credentials(
            token=creds_data.get('access_token'),
            refresh_token=creds_data.get('refresh_token'),
            token_uri=creds_data.get('token_uri'),
            client_id=creds_data.get('client_id'),
            client_secret=creds_data.get('client_secret'),
            scopes=creds_data.get('scopes')
        )

Custom AI Templates

One of the coolest features is creating your own AI prompt templates:

๐Ÿ“ Create a Custom Template

  1. Go to the "Prompt Templates" section
  2. Click "New Template"
  3. Try this customer service template:
Template Name: Customer Service Analysis

Template Content:
Analyze this customer email for support purposes:

Email: {email_content}

Please provide:
1. Customer sentiment (happy/frustrated/neutral)
2. Issue severity (low/medium/high/critical)
3. Department to route to (billing/technical/sales)
4. Urgency level (immediate/same-day/next-business-day)
5. Suggested response tone (empathetic/professional/apologetic)

Format as JSON.

๐Ÿ“Š Step 5: Analytics and Advanced Features

Email Analytics Dashboard

The app includes a powerful analytics dashboard that shows:

Multi-Provider Support

Want to add more email accounts? The app supports multiple providers:

# Add Microsoft Outlook
fiber account oauth configure microsoft \
  --client-id "YOUR_MICROSOFT_CLIENT_ID" \
  --client-secret "YOUR_MICROSOFT_CLIENT_SECRET" \
  --redirect-uri "http://localhost:7001/api/v1/credentials/auth/callback/microsoft" \
  --scopes "Mail.Read User.Read"

# Add Yahoo Mail
fiber account oauth configure yahoo \
  --client-id "YOUR_YAHOO_CLIENT_ID" \
  --client-secret "YOUR_YAHOO_CLIENT_SECRET" \
  --redirect-uri "http://localhost:7001/api/v1/credentials/auth/callback/yahoo" \
  --scopes "mail-r profile"

Advanced Customization

๐ŸŽจ Ideas for Further Development

๐Ÿค– Smart Auto-Reply

Create an agent that generates contextual email responses based on your writing style and the email content.

๐Ÿ“… Calendar Integration

Extract meeting requests and automatically create calendar events with AI-suggested details.

๐Ÿ” Advanced Search

Implement semantic search that understands meaning, not just keywords, using AI embeddings.

๐Ÿ“ˆ Productivity Insights

Track email response times, identify communication patterns, and suggest optimization opportunities.

๐ŸŽฏ Step 6: Understanding the Technical Architecture

OAuth Token Management

Let's understand how the app handles OAuth security:

// services/email-service.js - Secure token handling
class EmailService {
    async getAuthenticatedClient(providerId) {
        // Fiberwise handles token refresh automatically
        const credentials = await FIBER.credentials.get(providerId);
        
        if (credentials.isExpired()) {
            // Automatic refresh - no user intervention needed
            await credentials.refresh();
        }
        
        return this.createProviderClient(credentials);
    }
    
    async fetchEmails(providerId, options = {}) {
        try {
            const client = await this.getAuthenticatedClient(providerId);
            return await client.listMessages(options);
        } catch (error) {
            if (error.status === 401) {
                // Handle auth errors gracefully
                throw new AuthenticationError('Please re-authorize your account');
            }
            throw error;
        }
    }
}

Data Flow Architecture

๐Ÿ“Š How Data Moves Through the App

  1. OAuth Setup: User authorizes โ†’ Credentials stored securely
  2. Email Fetching: UI requests โ†’ Service layer โ†’ Provider API โ†’ Fiberwise data store
  3. AI Analysis: Email content โ†’ Agent processing โ†’ LLM analysis โ†’ Results storage
  4. UI Updates: Real-time data binding โ†’ Component updates โ†’ User sees results

Security Best Practices

๐Ÿ”’ Security Features You Get

๐Ÿ† Congratulations!

You've successfully built and deployed a production-ready email management application! You now understand:

๐Ÿ” OAuth Mastery

  • Complete OAuth 2.0 implementation
  • Multi-provider authentication
  • Secure token management
  • Error handling and recovery

๐Ÿค– AI Integration

  • Custom agent development
  • LLM prompt engineering
  • Data model design
  • Template customization

๐Ÿ—๏ธ App Architecture

  • Modern web components
  • Service layer patterns
  • Real-time data flow
  • Production deployment

๐Ÿ“Š Advanced Features

  • Analytics and insights
  • Custom templates
  • Multi-provider support
  • Extensible architecture

๐ŸŽฏ Key Architecture Insights

This tutorial demonstrated enterprise-grade Fiberwise patterns:

๐Ÿš€ What's Next?

๐Ÿ”ง Extend the App

Add calendar integration, smart auto-replies, or advanced search features

Advanced Patterns

๐Ÿข Deploy to Production

Learn about scaling, monitoring, and enterprise deployment

Production Guide

๐ŸŒ Explore OAuth Further

Dive deeper into OAuth configurations and advanced provider setups

OAuth Deep Dive

๐Ÿค– Advanced AI Agents

Build sophisticated multi-agent systems and workflow automation

Agent Mastery

๐ŸŽ‰ You're Now an OAuth + AI Integration Expert!

You've mastered one of the most complex aspects of modern app development: secure OAuth integration combined with intelligent AI processing. The email manager you built showcases enterprise-grade patterns that you can apply to any integration challenge.