An intelligent AI-powered phone bot for outgoing bulk calls using Twilio and Ollama. Perfect for sales campaigns, lead generation, and customer outreach with dynamic AI conversations.
- π― AI-Powered Conversations: Uses local Ollama AI for dynamic, intelligent call interactions
- π Bulk Outgoing Calls: Call hundreds of contacts from CSV/JSON files or direct phone lists
- π Campaign Management: Create, manage, and track calling campaigns
- π Detailed Reporting: Automatic CSV reports with call results and statistics
- βοΈ Rate Limiting: Configurable delays and concurrent call limits
- π‘οΈ Robust Architecture: Built with FastAPI, SQLAlchemy, and modern Python patterns
- π§ Easy Setup: No Docker required - runs directly with Python
- Windows 10/11
- Python 3.11+ (with PATH enabled during installation)
- Ollama installed locally
- Twilio Account with phone number and credentials
- Internet connection for API calls
# Clone the repository (if not already done)
git clone <repository-url>
cd twilio-ollama-bot-python
# Create virtual environment
python -m venv venv
# Activate virtual environment
.\venv\Scripts\Activate.ps1
# Install dependencies
pip install --upgrade pip
pip install -r requirements.txt
# Option A: Download from https://ollama.ai
# Option B: Install via winget
winget install Ollama.Ollama
# Pull the AI model
ollama pull llama3.2
# Copy environment template
copy .env.example .env
# Edit .env with your Twilio credentials
notepad .env
Required settings in .env
:
# Twilio Configuration
TWILIO_ACCOUNT_SID=your_twilio_account_sid_here
TWILIO_AUTH_TOKEN=your_twilio_auth_token_here
TWILIO_NUMBER=+1234567890
# Ollama Configuration (default is fine for local)
OLLAMA_BASE_URL=http://127.0.0.1:11434
MODEL=llama3.2
# Other settings (defaults are fine for testing)
DEBUG=true
LOG_LEVEL=INFO
PUBLIC_BASE_URL=https://test-webhook.example.com
# Create data and logs directories
if (!(Test-Path "data")) { New-Item -ItemType Directory -Path "data" }
if (!(Test-Path "logs")) { New-Item -ItemType Directory -Path "logs" }
# Start Ollama (in a new terminal/window)
ollama serve
# Set Python path and start the bot server
$env:PYTHONPATH = "$env:PYTHONPATH;$((Get-Location).Path)\src"
python -m uvicorn twilio_bot.main:app --host 0.0.0.0 --port 8000 --reload
The server will be available at:
- Main API: http://localhost:8000
- Health Check: http://localhost:8000/health/
- API Docs: http://localhost:8000/docs (if DEBUG=true)
# Check server health
Invoke-RestMethod -Uri "http://localhost:8000/health/" -Method Get
# Should return: status="healthy", service="Twilio-Ollama Bot"
# Call specific numbers directly
python scripts\bulk_caller.py --phones "+15551234567,+15559876543" --names "John Doe,Jane Smith"
Create a CSV file (contacts.csv
):
name,phone_number
John Doe,+15551234567
Jane Smith,+15559876543
Bob Johnson,+15551112222
# Call from CSV file
python scripts\bulk_caller.py contacts.csv
Create a JSON file (contacts.json
):
[
{"name": "John Doe", "phone": "+15551234567"},
{"name": "Jane Smith", "phone": "+15559876543"},
{"name": "Bob Johnson", "phone": "+15551112222"}
]
# Call from JSON file
python scripts\bulk_caller.py contacts.json
# Custom delay between calls (seconds)
python scripts\bulk_caller.py contacts.csv --delay 3
# Control maximum concurrent calls
python scripts\bulk_caller.py contacts.csv --concurrent 2
# Combine options
python scripts\bulk_caller.py contacts.csv --delay 2.5 --concurrent 3 --output my_results.csv
# Conservative (good for important calls)
python scripts\bulk_caller.py contacts.csv --delay 5 --concurrent 2
# Balanced (recommended)
python scripts\bulk_caller.py contacts.csv --delay 2 --concurrent 5
# Aggressive (use carefully)
python scripts\bulk_caller.py contacts.csv --delay 1 --concurrent 10
# Create a new campaign
python scripts\campaign_manager.py create --name "Q4 Sales Campaign" --file contacts.csv --desc "Quarter 4 lead generation"
# List all campaigns
python scripts\campaign_manager.py list
# Run a specific campaign
python scripts\campaign_manager.py run campaign_20251203_143022 --delay 3 --concurrent 2
# Delete a campaign
python scripts\campaign_manager.py delete campaign_20251203_143022
Every bulk call session creates a CSV file in the data\
folder with:
- phone_number: The called number
- name: Contact name
- timestamp: When the call was initiated
- status: "success" or "failed"
- call_sid: Twilio call identifier (if successful)
- error: Error message (if failed)
phone_number,name,timestamp,status,call_sid,error
+15551234567,John Doe,2025-12-03T14:30:41.991087,success,CAa3c7fe5b8b,
+15559876543,Jane Smith,2025-12-03T14:30:43.002894,failed,,Invalid phone number
+15551112222,Bob Johnson,2025-12-03T14:30:45.167326,success,CAb4d8gf9c9d,
# Test with included sample files
python scripts\bulk_caller.py sample_contacts.csv --delay 1 --concurrent 2
python scripts\bulk_caller.py sample_contacts.json --delay 1 --concurrent 2
"Server not ready":
# Check if bot server is running
Invoke-RestMethod -Uri "http://localhost:8000/health/" -Method Get
# If not running, start the server:
$env:PYTHONPATH = "$env:PYTHONPATH;$((Get-Location).Path)\src"
python -m uvicorn twilio_bot.main:app --host 0.0.0.0 --port 8000 --reload
"Cannot connect to bot server":
# Verify Ollama is running
ollama list
# If Ollama not running:
ollama serve
"Invalid phone number":
- Ensure numbers are in E.164 format:
+15551234567
- No spaces, dashes, or parentheses
- Must start with
+
followed by country code
CSV/JSON loading errors:
- Check file encoding (should be UTF-8)
- Verify column headers:
name
,phone_number
,number
,phone
- Ensure JSON is valid format
# Enable verbose logging
python scripts\bulk_caller.py contacts.csv --verbose
# Check application logs
Get-Content logs\app.log | Select-Object -Last 20
-
Get Twilio Credentials:
- Sign up at https://twilio.com
- Get your Account SID, Auth Token, and phone number
- Update
.env
file with real credentials
-
Test with One Number First:
python scripts\bulk_caller.py --phones "+1234567890" --names "Test Call"
-
Run Your Campaign:
python scripts\bulk_caller.py real_contacts.csv --delay 3 --concurrent 2
# Install ngrok
winget install ngrok.ngrok
# Start tunnel
ngrok http 8000
# Copy the https URL and update PUBLIC_BASE_URL in .env
twilio-ollama-bot-python/
βββ src/
β βββ twilio_bot/ # Main bot application
β βββ main.py # FastAPI server
β βββ config.py # Configuration
β βββ api/ # API endpoints
βββ scripts/
β βββ bulk_caller.py # Bulk calling script
β βββ campaign_manager.py # Campaign management
β βββ make_call.py # Single call utility
βββ data/ # Results and database files
βββ logs/ # Application logs
βββ sample_contacts.csv # Example CSV file
βββ sample_contacts.json # Example JSON file
βββ .env # Your configuration
βββ requirements.txt # Python dependencies
# Twilio (Required)
TWILIO_ACCOUNT_SID=your_account_sid
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_NUMBER=+1234567890
# AI Model (Local Ollama)
OLLAMA_BASE_URL=http://127.0.0.1:11434
MODEL=llama3.2
# Server Settings
HOST=0.0.0.0
PORT=8000
DEBUG=true
# Call Settings
MAX_EXCHANGES=4 # AI conversation turns per call
SPEECH_TIMEOUT=auto
GATHER_TIMEOUT=5
# Company Info (used in calls)
COMPANY_NAME=Your Company
AGENT_NAME=Sarah
- Use 2-5 second delays between calls to avoid overwhelming Twilio
- Keep concurrent calls low (2-10) for better call quality
- For large lists (1000+), consider splitting into smaller batches
- Always use E.164 format:
+1234567890
- Include country code
- No spaces, dashes, or special characters
β οΈ Important: Always comply with local regulations- Obtain proper consent before calling contacts
- Respect Do Not Call lists
- Include opt-out mechanisms
# Create leads campaign
python scripts\campaign_manager.py create --name "Daily Leads" --file daily_leads.csv
# Run with conservative settings
python scripts\campaign_manager.py run campaign_id --delay 4 --concurrent 2
# Split large file into smaller batches
python scripts\bulk_caller.py batch1_contacts.csv --delay 2 --concurrent 5 --output batch1_results.csv
python scripts\bulk_caller.py batch2_contacts.csv --delay 2 --concurrent 5 --output batch2_results.csv
# Call specific follow-up list
python scripts\bulk_caller.py --phones "+1111111111,+2222222222" --names "Follow-up 1,Follow-up 2" --delay 5
- Check logs:
Get-Content logs\app.log
- Test connectivity:
http://localhost:8000/health/
- Verify Ollama:
ollama list
- Test single call:
python scripts\make_call.py +15551234567
- Python 3.11+ installed
- Virtual environment created and activated
- Dependencies installed (
pip install -r requirements.txt
) - Ollama installed and running (
ollama serve
) - AI model downloaded (
ollama pull llama3.2
) -
.env
file configured with Twilio credentials - Required directories created (
data
,logs
) - Bot server running (
http://localhost:8000/health/
returns healthy) - Test call successful
Once everything is set up:
# Test with sample data
python scripts\bulk_caller.py sample_contacts.csv
# Create your first real campaign
python scripts\campaign_manager.py create --name "My First Campaign" --file your_contacts.csv
# Run it!
python scripts\campaign_manager.py run your_campaign_id --delay 3 --concurrent 3
π You're ready to make AI-powered bulk calls! The system handles everything from AI conversations to detailed reporting, all running locally on your Windows machine.
For questions or issues, check the troubleshooting section above or review the application logs in logs\app.log
.