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.
๐ 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.
Navigate to Email Agent App
cd fiber-apps/email-agent-app
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
๐ 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
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)
Enable Gmail API
In your Google Cloud project, enable the Gmail API:
- Navigate to "APIs & Services" โ "Library"
- Search for "Gmail API"
- Click "Enable"
Create OAuth Credentials
Set up OAuth 2.0 credentials for web application:
http://localhost:5757/api/v1/oauth/callback/fiberwise-developer
Download OAuth Configuration
Download the OAuth JSON credentials from Google Cloud Console:
- Go to "APIs & Services" โ "Credentials"
- Find your OAuth 2.0 Client ID
- Click the download icon to get the JSON file
- Save it as
oauth-credentials.json
in your project directory
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
- Go to APIs & Services โ Credentials
- Click "Create Credentials" โ "OAuth 2.0 Client IDs"
- Application type: "Web application"
- 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
๐ง email_analyses
AI-generated insights and analysis results
๐ email_prompt_templates
User-created AI prompt templates for custom analysis
๐ Step 4: Install and Run the App
Now let's install the email app and see it in action.
Install the App
fiber app install email-agent-app
โ This installs the app, creates database tables, and registers all components.
Start the Development Server
fiber start --dev
โ
Your email app is now running at http://localhost:5757
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.
Navigate to Email Connections
In the email app, go to Settings โ Email Connections
Shows the Settings โ Email Connections interface with available provider options (Gmail, Outlook, Yahoo) and "Connect" buttons for each provider.
Add Gmail Connection
Click "Add Connection" and select "Gmail (OAuth)"
Authorize Access
Complete the OAuth flow by granting permissions to:
- Read your email messages
- Send emails on your behalf
- Access basic profile information
Shows the Email Connections page after successful OAuth authorization, with Gmail provider showing "Connected โ" status and user's email address displayed.
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 = `
๐ง Email Provider Connections
${this.renderProviderCard('gmail', 'Gmail', '๐ฎ')}
${this.renderProviderCard('outlook', 'Outlook', '๐จ')}
${this.renderProviderCard('yahoo', 'Yahoo Mail', '๐ฌ')}
Active Connections:
${this.renderActiveConnections()}
`;
this.attachEventListeners();
}
renderProviderCard(providerId, name, icon) {
const isConnected = this.connections.some(c => c.provider_id === providerId);
const isPending = this.pendingConnections.has(providerId);
return `
${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
Advanced email search across Gmail, Outlook, and Yahoo with unified API
LLM integration for sentiment, priority, topics, and action items with customizable templates
Progress notifications and status updates through Fiberwise realtime system
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:
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]:
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"
}
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"
)