A production-ready Microsoft Teams bot that integrates with CustomGPT.ai API to bring your AI-powered knowledge base directly into Teams conversations.
Get you CustomGPT.ai RAG API key here, needed to use this integration.
More information on GitHub - https://github.com/Poll-The-People/customgpt-integrations
Quick Links: Prerequisites | Getting Credentials | Setup | Deployment | Confluence | Troubleshooting
Table of Contents
- Features
- Prerequisites
- Getting Credentials
- Quick Setup
- Configuration
- Deployment
- Confluence Integration
- Usage
- Troubleshooting
- Support
Features
Core Capabilities
- 🤖 Intelligent Q&A: Access your CustomGPT knowledge base in Teams
- 💬 Context-Aware Conversations: Maintains conversation history
- 🧵 Threading Support: Seamless conversation threads
- 🎯 @Mentions: Responds to bot mentions in channels
- 🃏 Adaptive Cards: Rich, interactive UI elements
- ⚡ Slash Commands:
/help,/reset,/status,/search
In personal chat: /help
In channel: @CustomGPT Bot 2 /help
Enterprise Features
- 🔐 Azure AD Authentication: Secure enterprise authentication
- 📋 Audit Logging: Track all bot interactions
- 🛡️ Access Control: Tenant, channel, and user restrictions
- 🔄 Rate Limiting: Multi-tier (user/channel/tenant) protection
- 📊 Analytics: Application Insights integration
- 🌍 Multi-tenant: Works across organizations
Optional Integrations
- 🔍 Confluence: Search Atlassian Confluence directly from Teams
- 📎 File Attachments: Process documents and images
- 💼 Meeting Support: Works in Teams meetings
Prerequisites
| Requirement | Free Tier Available | Purpose |
|---|---|---|
| Azure Account | ✅ Yes | Bot registration and hosting |
| CustomGPT.ai Account | ✅ Trial | AI knowledge base API |
| Microsoft Teams Admin | - | Install bot in Teams |
| Python 3.8 - 3.11 | ✅ Yes | Local development |
| Redis (Optional) | ✅ Yes | Distributed rate limiting |
Getting Credentials
You need 4 required credentials to run the bot. Follow these steps to get them.
1. Microsoft Teams Credentials (Azure Portal)
Step 1: Create App Registration
- Go to Azure Portal
- Search for "Microsoft Entra ID" → "App registrations" → "+ New registration"
- Fill in:
Name: customgpt-teams-bot Supported account types: Single tenant (recommended) or Multi-tenant Redirect URI: Leave blank - Click "Register"
- COPY THE APPLICATION (CLIENT) ID - Save this as your
TEAMS_APP_ID
Step 2: Create Client Secret
- In the left menu, click "Certificates & secrets" → "Client secrets" tab
- Click "+ New client secret"
- Description:
Teams Bot Secret, Expires: 24 months - Click "Add"
- IMMEDIATELY COPY THE VALUE - Save this as your
TEAMS_APP_PASSWORD
⚠️ Copy the Value, NOT the "Secret ID". You can only see it once!
Step 3: Create Azure Bot Resource
- Azure Portal → "Create a resource" → "Azure Bot"
- Fill in:
- Bot handle:
customgpt-teams-bot - Pricing tier: F0 (Free)
- Microsoft App ID: Enter the ID from Step 1
- Bot handle:
- "Review + Create" → "Create"
- You'll add the messaging endpoint later when you deploy
Step 4: Enable Teams Channel
- Go to your Azure Bot → "Channels" → "Microsoft Teams" icon → "Apply"
✅ Credentials ready:
TEAMS_APP_IDfrom Step 1TEAMS_APP_PASSWORDfrom Step 2
2. CustomGPT Credentials
Get CUSTOMGPT_API_KEY
- Go to CustomGPT Dashboard
- Sign in to your account
- Click profile icon (top right) → "API Settings"
- Click "Generate API Key" if you don't have one
- Name it:
Teams Bot - Copy the API Key
Get CUSTOMGPT_PROJECT_ID
Get this from https://app.customgpt.ai/ > Select your agent > Deploy > "See top right section"
3. Optional: Confluence Credentials
Only needed if you want Confluence search integration.
For Confluence Cloud
-
Base URL: Your Confluence URL
Example: https://your-company.atlassian.net -
Create API Token:
- Go to Atlassian API Tokens
- Click "Create API token"
- Label:
Teams Bot - Copy the token
-
Username: Your Atlassian email address
For Confluence Server/Data Center
-
Base URL: Your self-hosted URL
Example: https://confluence.yourcompany.com -
Create Personal Access Token:
- Profile → Personal Access Tokens
- Create token:
Teams Bot - Copy the token
-
Username: Your Confluence username (not email)
Quick Setup
Step 1: Clone and Install
# Clone repository
git clone <your-repo>
cd "customgpt-integrations/MS Teams"
# Create virtual environment
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate # macOS/Linux
# OR
venv\Scripts\activate # Windows
# Install dependencies
pip install --upgrade pip
pip install -r requirements.txtStep 2: Configure Environment
# Copy environment template
cp .env.example .env
# Edit .env with your credentials
nano .env # or use any text editorRequired Configuration:
# Microsoft Teams (from Azure Portal)
TEAMS_APP_ID=12345678-1234-1234-1234-123456789abc
TEAMS_APP_PASSWORD=abc123~XYZ456.789def-GHI012_JKL345
TEAMS_APP_TYPE=MultiTenant
# CustomGPT (from CustomGPT Dashboard)
CUSTOMGPT_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
CUSTOMGPT_PROJECT_ID=12345Optional - Confluence Integration:
# Confluence (only if integrating)
CONFLUENCE_ENABLED=false # Set to true to enable
CONFLUENCE_BASE_URL=https://your-company.atlassian.net
CONFLUENCE_IS_CLOUD=true
[email protected]
CONFLUENCE_API_TOKEN=your-api-tokenStep 3: Start the Bot
# Make sure virtual environment is activated
source venv/bin/activate
# Start the bot
python3 app.pyExpected Output:
INFO - CustomGPT client initialized
INFO - Rate limiter initialized
INFO - Conversation manager initialized
INFO - Bot initialization complete
* Running on http://0.0.0.0:3978
Step 4: Verify Health
Open another terminal:
curl http://localhost:3978/healthExpected Response:
{
"status": "healthy",
"bot": "CustomGPT Teams Bot",
"version": "1.0.0"
}✅ Your bot is now running locally!
Configuration
Rate Limiting
Control request rates to prevent abuse:
RATE_LIMIT_PER_USER=20 # Messages per minute per user
RATE_LIMIT_PER_CHANNEL=100 # Messages per hour per channel
RATE_LIMIT_PER_TENANT=500 # Messages per hour per organizationSecurity & Access Control
Restrict bot access by tenant, channel, or user:
# Restrict to specific organizations (comma-separated)
ALLOWED_TENANTS=tenant-id-1,tenant-id-2
# Restrict to specific channels
ALLOWED_CHANNELS=channel-id-1,channel-id-2
# Block specific users
BLOCKED_USERS=user-id-1,user-id-2Conversation Settings
Control conversation behavior:
CONVERSATION_TIMEOUT=86400 # 24 hours (in seconds)
MAX_CONTEXT_MESSAGES=10 # Number of messages to keep in context
ENABLE_THREADING=true # Enable thread supportBot Behavior
Customize bot responses:
MAX_MESSAGE_LENGTH=4000 # Max message length
SHOW_CITATIONS=true # Show source citations
REQUIRE_MENTION_IN_CHANNELS=true # Require @mention in channels
ENABLE_ADAPTIVE_CARDS=true # Use rich cards
DEFAULT_LANGUAGE=en # Default response language
RESPONSE_TIMEOUT=30 # API timeout in secondsLogging
LOG_LEVEL=INFO # DEBUG for development, INFO for production, WARNING for minimal logsServer Settings
PORT=3978 # Default Teams bot port
HOST=0.0.0.0 # Listen on all interfacesDeployment
Local Development with Ngrok
For testing with Teams while developing locally:
-
Install ngrok:
# macOS brew install ngrok # Or download from https://ngrok.com -
Start your bot:
source venv/bin/activate python3 app.py -
In another terminal, start ngrok:
ngrok http 3978 -
Copy the HTTPS URL from ngrok output:
- Look for the "Forwarding" line in ngrok output
- Copy the HTTPS URL (e.g.,
https://631af35e4e38.ngrok-free.app) - Important: Add
/api/messagesto the end
-
Update Azure Bot messaging endpoint:
- Go to Azure Portal → Your Bot → Configuration
- Find the Messaging endpoint field
- Paste:
https://your-ngrok-url.ngrok-free.app/api/messages - Example:
https://631af35e4e38.ngrok-free.app/api/messages - Click "Apply"
-
Test in Teams - Your bot is now accessible!
⚠️ Important Notes:
- The
/api/messagespath is required - this is where your bot receives messages - Free ngrok URLs change every time you restart ngrok
- You'll need to update the Azure Bot messaging endpoint each time ngrok restarts
- For persistent URLs, consider ngrok paid plan or deploy to production
Production Deployment Options
Option 1: Azure Web App (Recommended)
Best for: Production deployments with enterprise features
Steps:
-
Create Azure Web App:
az webapp up \ --name customgpt-teams-bot \ --resource-group customgpt-rg \ --runtime "PYTHON:3.11" \ --sku B1 -
Configure Environment Variables:
- Azure Portal → Web App → Configuration → Application settings
- Add all variables from your
.envfile - Click "Save"
-
Update Bot Endpoint:
- Azure Portal → Bot → Configuration
- Messaging endpoint:
https://customgpt-teams-bot.azurewebsites.net/api/messages
-
Enable Application Insights (optional but recommended):
- Add
APPLICATION_INSIGHTS_KEYto app settings
- Add
Cost: ~$13/month for B1 tier (or ~$55/month for S1)
Option 2: Docker Container
Best for: Self-hosted or cloud-agnostic deployments
Build and Run:
# Build image
docker build -t customgpt-teams-bot .
# Run container
docker run -d \
--name teams-bot \
-p 3978:3978 \
--env-file .env \
customgpt-teams-bot
# View logs
docker logs -f teams-botDocker Compose:
# Run with Docker Compose
docker-compose up -d
# With Redis for rate limiting
docker-compose --profile with-redis up -dOption 3: Free Cloud Hosting
Railway.app (Recommended for beginners):
- Fork this repository
- Go to Railway.app
- Create new project from GitHub
- Add environment variables
- Deploy automatically
- Copy public URL → Update Azure bot endpoint
Free Tier: 500 hours/month, $5 credit
Render.com:
- Create Web Service
- Connect GitHub repo
- Set environment variables
- Deploy
Free Tier: 750 hours/month
Install in Microsoft Teams
Step 1: Create Teams App Package
-
Update manifest:
- Edit
deployment/manifest.json - Find the
botIdfield (around line 28) - Replace
YOUR-BOT-ID-HEREwith your TEAMS_APP_ID (the Microsoft App ID from your.envfile) - Also update
webApplicationInfo.idwith the same ID - Update
name,description, etc. as needed
Example:
"bots": [ { "botId": "12345678-1234-1234-1234-123456789abc",What is botId?
- It's your Microsoft App ID (same as
TEAMS_APP_IDin.env) - It uniquely identifies your bot to Microsoft Teams
- Teams uses it to route messages to your bot
- It must match the App ID registered in Azure
- Edit
-
Create icons:
color.png: 192x192px color iconoutline.png: 32x32px outline icon- Place in
deployment/folder
-
Create ZIP package:
cd deployment zip -r customgpt-bot.zip manifest.json color.png outline.png
Step 2: Upload to Teams
Method 1: Direct Upload (Simple)
- Open Microsoft Teams
- Go to Apps → Manage your apps → Upload an app
- Choose "Upload a custom app"
- Select
customgpt-bot.zip - Click "Add"
Method 2: Teams Developer Portal (Recommended for troubleshooting duplicates)
If you encounter duplicate app errors or upload issues:
-
Open Teams Developer Portal:
- Visit: https://dev.teams.microsoft.com/apps
- Or in Teams: Apps → Developer Portal
-
Import your app:
- Click "Import app"
- Upload your
customgpt-bot.zip - The portal will detect duplicates and let you overwrite or create new
-
Manage app details:
- Edit app information in the portal if needed
- Preview how it will appear in Teams
-
Publish:
- Click "Publish" → "Publish to org"
- App will be available in your Teams organization
Benefits of Developer Portal:
- Better handling of duplicate apps
- Visual editor for manifest properties
- App validation and testing tools
- Version management
Step 3: Test the Bot
- Personal Chat: Send a direct message to the bot
- Channel: @mention the bot:
@CustomGPT Bot hello - Commands: Try
/helpto see available commands
✅ Your bot is now live in Teams!
Confluence Integration
Enable Confluence Search
Add Confluence search capability to your Teams bot, allowing users to search and access Confluence pages directly from Teams.
Setup
-
Get Confluence credentials (see Getting Credentials)
-
Update
.envfile:CONFLUENCE_ENABLED=true CONFLUENCE_BASE_URL=https://your-company.atlassian.net CONFLUENCE_IS_CLOUD=true [email protected] CONFLUENCE_API_TOKEN=your-confluence-api-token CONFLUENCE_DEFAULT_SPACE= # Optional: default space key CONFLUENCE_SEARCH_LIMIT=5 # Max results to return -
Restart the bot:
python3 app.py -
Verify in logs:
INFO - Confluence client initialized
Usage
Commands:
-
/search <query>- Search Confluence pages/search API documentation /search onboarding process -
/confluence- Show integration status and helpConfluence Integration Active Available Spaces: • Engineering (ENG) • Documentation (DOCS) Commands: • /search <query> - Search Confluence • /confluence - Show this help
Features:
- Rich Adaptive Cards with search results
- Direct links to Confluence pages
- Content excerpts and metadata
- Respects Confluence permissions
Authentication Methods
For Confluence Cloud (Recommended):
[email protected]
CONFLUENCE_API_TOKEN=YOUR_API_TOKENFor Confluence Server/Data Center:
CONFLUENCE_IS_CLOUD=false
CONFLUENCE_USERNAME=your-username # Not email
CONFLUENCE_API_TOKEN=YOUR_PERSONAL_ACCESS_TOKENTroubleshooting Confluence
Authentication Errors:
# Test credentials manually
curl -u "[email protected]:YOUR_TOKEN" \
https://your-domain.atlassian.net/wiki/rest/api/spaceNo Results:
- Check space permissions
- Verify bot user has read access
- Try broader search terms
Timeout Errors:
- Increase
RESPONSE_TIMEOUTin.env - Reduce
CONFLUENCE_SEARCH_LIMIT
Usage
Basic Commands
| Command | Description | Example |
|---|---|---|
/help | Show available commands | /help |
/start | Start new conversation | /start |
/reset | Clear conversation context | /reset |
/status | Check rate limits and bot status | /status |
/search | Search Confluence (if enabled) | /search API docs |
/confluence | Show Confluence integration status | /confluence |
Interacting with the Bot
Personal Chat:
You: What is our refund policy?
Bot: According to our documentation...
In Channels (requires @mention):
You: @CustomGPT Bot what are the office hours?
Bot: Our office hours are...
In Threads:
You: Tell me about product features
Bot: Here are our key features...
You: (reply in thread) What about pricing?
Bot: (continues in thread) Our pricing is...
Adaptive Cards
The bot uses rich Adaptive Cards for:
- Welcome messages with quick actions
- Response cards with citations
- Search results with direct links
- Error messages with helpful tips
Rate Limits
Check your current rate limit status:
/status
Rate Limits:
• User: 15/20 requests this minute
• Channel: 45/100 requests this hour
• Tenant: 230/500 requests this hour
Bot Status: ✅ Healthy
Troubleshooting
Common Issues
1. "Configuration error: Missing required configuration"
Cause: Missing or empty credentials in .env file
Solution:
- Check
.envfile exists in project directory - Verify all required fields are filled:
TEAMS_APP_IDTEAMS_APP_PASSWORDCUSTOMGPT_API_KEYCUSTOMGPT_PROJECT_ID
- No extra spaces or quotes around values
- Restart bot after editing
.env
2. Bot Not Responding in Teams
Possible Causes & Solutions:
✅ Check messaging endpoint:
- Azure Portal → Bot → Configuration
- Verify endpoint is correct:
https://your-domain.com/api/messages - For local dev with ngrok, update with ngrok HTTPS URL
✅ Verify bot is installed:
- Teams → Apps → Manage your apps
- Confirm bot is installed
✅ Check bot is added to channel:
- For channel conversations, bot must be added as member
- Try personal chat first to isolate issue
✅ View bot logs:
# Local
# Check terminal output
# Docker
docker logs customgpt-teams-bot
# Azure
az webapp log tail --name your-bot --resource-group your-rg3. Authentication Errors
Symptom: Authentication failed in logs
Solution:
-
Verify App ID matches Azure Portal:
# Check .env file cat .env | grep TEAMS_APP_ID # Compare with Azure Portal → Bot → Configuration -
Regenerate client secret if needed:
- Azure Portal → Bot → Configuration → Manage
- Certificates & secrets → New client secret
- Update
TEAMS_APP_PASSWORDin.env
-
Restart bot after updating credentials
4. CustomGPT API Errors
Symptom: Bot responds with "Error processing request"
Test API manually:
curl -X POST https://app.customgpt.ai/api/v1/projects/YOUR_PROJECT_ID/conversations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "test"}'If test fails:
- Regenerate API key in CustomGPT dashboard
- Verify project ID is correct
- Check project is active (not paused)
- Update
.envand restart bot
5. Rate Limit Issues
Symptom: "Rate limit exceeded" messages
Solutions:
-
Increase limits in
.env:RATE_LIMIT_PER_USER=30 # Increase from 20 RATE_LIMIT_PER_CHANNEL=200 # Increase from 100 -
Use Redis for distributed rate limiting:
REDIS_URL=redis://localhost:6379 -
Check current status:
/status
6. Python Import Errors
Symptom: ModuleNotFoundError when starting bot
Solution:
# Ensure virtual environment is activated
source venv/bin/activate
# Verify activation (should see "(venv)" in prompt)
# Reinstall dependencies
pip install -r requirements.txt
# Verify bot module imports
python3 -c "import bot; print('✅ Success')"Debug Mode
Enable detailed logging:
LOG_LEVEL=DEBUGRestart bot and check logs for detailed information about:
- HTTP requests/responses
- Authentication attempts
- API calls
- Error stack traces
Health Check
Verify bot is running:
curl http://localhost:3978/healthHealthy Response:
{
"status": "healthy",
"bot": "CustomGPT Teams Bot",
"version": "1.0.0",
"timestamp": "2025-11-04T00:00:00.000Z"
}Unhealthy Response:
- No response: Bot not running or port blocked
- Error response: Check logs for details
Getting Help
Before asking for help, collect:
- Bot logs (last 50 lines with errors)
- Your
.envconfiguration (REDACT secrets!) - Python version:
python3 --version - Steps to reproduce the issue
Development
Running Tests
# Activate virtual environment
source venv/bin/activate
# Run all tests
pytest
# Run with coverage
pytest --cov=. --cov-report=html
# Run specific test
pytest tests/test_bot.py -vCode Quality
# Format code
black *.py
# Lint code
flake8 *.py
# Type check
mypy *.pySecurity Best Practices
1. Credential Management
✅ Never commit secrets:
# .gitignore already includes:
.env
*.token
credentials.json✅ Use Azure Key Vault for production:
az keyvault secret set \
--vault-name your-vault \
--name ConfluenceApiToken \
--value "YOUR_TOKEN"✅ Rotate secrets regularly (every 3-6 months)
2. Access Control
✅ Enable tenant restrictions in production:
ALLOWED_TENANTS=your-tenant-id✅ Use service accounts for Confluence (not personal accounts)
✅ Audit logging enabled:
ENABLE_AUDIT_LOGGING=true3. Network Security
✅ Always use HTTPS ✅ Configure firewalls to allow only necessary traffic ✅ Use Azure Network Security Groups for production
4. Data Privacy
✅ No message storage by default ✅ Conversation timeout clears context:
CONVERSATION_TIMEOUT=86400 # 24 hoursSupport
CustomGPT Resources
- Landing Page: https://customgpt.ai
- Dashboard: https://app.customgpt.ai
- API Docs: https://docs.customgpt.ai/api-reference
- Postman Collection: https://www.postman.com/customgpt/customgpt/overview
- Office Hours: https://calendly.com/pollthepeople/office-hours
- YouTube: https://www.youtube.com/channel/UC6HOk7Z9OwVPNYiC7SKMJ6g
Microsoft Resources
- Azure Bot Service: https://docs.microsoft.com/azure/bot-service
- Teams Platform: https://docs.microsoft.com/microsoftteams/platform
- Bot Framework: https://github.com/microsoft/botbuilder-python
Community
- GitHub Issues: Report bugs or request features
- Discussions: Ask questions and share tips
License
See main repository LICENSE file.
