AI-powered multi-channel sales automation platform
Project description
ReachGenie - AI-Powered Sales Automation Platform
ReachGenie is a comprehensive AI-powered sales automation platform that enables businesses to run multi-channel outbound campaigns through email, phone calls, and LinkedIn. The platform leverages AI for personalized content generation, lead enrichment, and intelligent follow-ups to maximize sales efficiency and meeting bookings.
Table of Contents
- Overview
- Key Features
- Tech Stack
- Architecture
- Database Schema
- API Endpoints
- Installation & Setup
- Environment Variables
- Running the Application
- Background Jobs & Cron Tasks
- Integrations
- Development Guide
- Project Structure
Overview
ReachGenie is an AI SDR (Sales Development Representative) platform that automates the entire outbound sales process. It helps companies:
- Manage products and value propositions
- Upload and enrich leads with company intelligence
- Create and execute multi-channel campaigns (Email, Phone, LinkedIn)
- Generate personalized AI-driven content for each prospect
- Track engagement and automatically follow up
- Book meetings directly into calendars
- Monitor campaign performance with detailed analytics
Key Features
Multi-Channel Campaign Execution
ReachGenie supports 3 primary communication channels for outbound sales automation:
1. Email Channel
- AI-Generated Content: Personalized emails using GPT-4/Claude based on lead data
- SMTP Integration: Support for Gmail, Outlook, Yahoo, and custom SMTP servers
- Reply Detection: Automatic IMAP monitoring for prospect replies
- Smart Follow-ups: Context-aware reminder emails with engagement tracking
- Email Threading: Proper Message-ID and References headers for conversation threads
- Open Tracking: Pixel-based open detection
- Bounce Handling: Automatic bounce processing and suppression list management
- Throttling: Configurable hourly/daily sending limits to protect sender reputation
- Queue System: Redis-based email queue with retry logic and priority handling
- Auto-Reply AI: Intelligent AI responses to prospect replies when enabled
2. Phone/Voice Channel
- AI Voice Agent: Natural conversations powered by Bland AI
- Dynamic Scripts: AI-generated call scripts personalized per prospect
- Real-time Conversations: Natural language understanding and response
- Meeting Booking: Direct calendar integration during calls via tools
- Call Recording: Automatic recording and transcription
- Sentiment Analysis: AI-powered call sentiment detection
- Call Queue: Redis-based queue with business hours respect
- Call Reminders: Automatic follow-up calls based on previous outcomes
- Voicemail Detection: Smart handling of voicemail scenarios
- Multi-timezone Support: Respects prospect local business hours
3. LinkedIn Channel
- Automated Connection Requests: Personalized invitation messages
- Direct Messaging: AI-generated messages to 1st-degree connections
- Profile Views: Automated profile viewing to increase visibility
- Message Threading: Maintains conversation context
- Rate Limiting: Built-in safety limits (80 invites/day, 100 views/day)
- Human-like Delays: Randomized delays between actions
- Account Management: Multi-account support via Unipile
- Webhook Integration: Real-time message and connection status updates
- Campaign Tracking: Full analytics on connection acceptance and reply rates
Campaign Types
- Email Only: Pure email outreach campaigns
- Call Only: Voice-only campaigns
- Email + Call: Hybrid campaigns with email first, call as follow-up
- LinkedIn Only: LinkedIn-exclusive campaigns
- Multi-Channel: Combined email, call, and LinkedIn sequences
AI-Powered Intelligence
- Lead Enrichment: Automatic company and prospect research using Perplexity AI
- Content Generation: Personalized email and call scripts using OpenAI GPT-4 and Anthropic Claude
- Smart Follow-ups: Context-aware reminder emails based on engagement patterns
- Sentiment Analysis: AI-powered call analysis and lead scoring
Advanced Campaign Management
- Queue System: Redis-based email and call queues with retry logic
- Throttling: Configurable email sending limits to protect sender reputation
- Schedule Management: Campaign scheduling and automated execution
- A/B Testing: Test campaigns before full deployment
Calendar Integration
- Cronofy Integration: Seamless calendar booking with availability checking
- Custom Calendar Links: Support for Calendly and other scheduling tools
- Meeting Tracking: Automatic meeting confirmation and follow-up
Subscription & Billing
- Stripe Integration: Multi-tier subscription plans (Trial, Fixed, Performance)
- Usage-based Billing: Metered billing for performance plans
- Channel Management: Per-channel subscription add-ons
Team Collaboration
- Multi-user Support: Company-level user management with role-based access (Admin, SDR)
- Team Invitations: Invite team members with automatic onboarding
Analytics & Reporting
- Email Tracking: Open rates, reply rates, and engagement metrics
- Call Analytics: Duration, sentiment, and conversion tracking
- Campaign Reports: Automated summary emails with performance benchmarks
- Lead History: Complete communication timeline for each prospect
Tech Stack
Core Framework
- FastAPI 0.104.1: Modern Python web framework for building APIs
- Uvicorn 0.24.0: ASGI server for FastAPI
- Pydantic 2.4.2: Data validation using Python type annotations
- Pydantic Settings 2.0.3: Configuration management
- Python 3.12+: Latest Python features and performance improvements
Database & Storage
- PostgreSQL: Primary database (via Supabase)
- Supabase 2.6.0: Backend-as-a-Service platform
- Asyncpg 0.30.0: High-performance asynchronous PostgreSQL driver
- Redis 6.1.0: Queue management and caching
Background Processing
- Celery 5.5.2: Distributed task queue for campaign execution
- Flower: Real-time Celery monitoring
- Watchdog 6.0.0: File system monitoring for auto-reload
AI & ML Services
- OpenAI 1.59.4: GPT-4 for email and script generation
- Anthropic (latest): Claude for advanced content generation
- Perplexity API: Company research and lead enrichment
Communication Services
- Bland AI: AI-powered voice calling platform
- Mailjet Rest 1.3.4: Email delivery and tracking
- aiosmtplib 3.0.1: Asynchronous SMTP client
- IMAP: Direct email integration for reply processing
- Unipile: LinkedIn automation and messaging
Third-Party Integrations
- Stripe 12.0.1: Payment processing and subscription management
- Cronofy 2.0.7: Calendar integration and meeting scheduling
- Bugsnag 4.6.1: Error tracking and monitoring
Security & Authentication
- python-jose 3.3.0: JWT token handling
- passlib 1.7.4: Password hashing
- bcrypt 4.2.1: Secure password hashing
- cryptography 42.0.2: Email credential encryption
- email-validator 2.2.0: Email format validation
HTTP & Networking
- httpx 0.27.2: Async HTTP client with HTTP/2 support
- requests 2.31.0: Synchronous HTTP library
- urllib3 2.0.7: HTTP client library
- python-multipart 0.0.6: Form data parsing
Document Processing
- python-docx 0.8.11: Word document processing
- PyPDF2 3.0.1: PDF document parsing
Utilities
- pytz 2025.2: Timezone handling
- chardet 5.2.0: Character encoding detection
- charset-normalizer 3.3.2: Unicode string normalization
- python-dotenv 1.0.0: Environment variable management
Architecture
System Architecture
┌─────────────────┐
│ Frontend UI │
└────────┬────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ FastAPI Backend │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Auth │ │ Routes │ │ Services │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────┬───────────────────────────────────────────────┘
│
├─────────────┬──────────────┬──────────────┬────────────┐
▼ ▼ ▼ ▼ ▼
┌──────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐
│PostgreSQL│ │ Redis │ │ Celery │ │ AI │ │External │
│ DB │ │ Queue │ │ Workers │ │Services │ │ APIs │
└──────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘
Campaign Execution Flow
User Creates Campaign
│
▼
Campaign Queued (Redis)
│
▼
Celery Worker Picks Up Task
│
├─── Email Campaign ──────┐
│ 1. Fetch Leads │
│ 2. AI Enrichment │
│ 3. Generate Email │
│ 4. Queue in Redis │
│ 5. SMTP Send │
│ 6. Track Opens/Replies│
│ │
├─── Call Campaign ────────┤
│ 1. Fetch Leads │
│ 2. Generate Script │
│ 3. Queue Calls │
│ 4. Bland AI Execute │
│ 5. Process Results │
│ 6. Book Meetings │
│ │
└─── LinkedIn Campaign ────┘
1. Fetch Leads
2. Generate Messages
3. Queue Actions
4. Unipile Execute
5. Track Engagement
Data Flow
- User Registration → Email verification → Trial plan activation
- Company Setup → Add products → Enrich with Perplexity
- Lead Upload → CSV processing → Data validation → Enrichment
- Campaign Creation → Template selection → Target audience
- Campaign Execution → Queue processing → AI generation → Delivery
- Engagement Tracking → Opens/Replies → Sentiment analysis → Follow-ups
- Meeting Booking → Calendar check → Slot booking → Confirmation
- Reporting → Analytics aggregation → Email summaries
Database Schema
Core Tables
users
Stores user authentication and subscription information.
- id: UUID (Primary Key)
- email: TEXT (Unique)
- name: TEXT
- password_hash: TEXT
- verified: BOOLEAN
- stripe_customer_id: TEXT
- plan_type: TEXT (trial, fixed, performance)
- lead_tier: INTEGER (2500, 5000, 7500, 10000)
- channels_active: JSONB
- subscription_id: TEXT
- subscription_status: TEXT
- billing_period_start: TIMESTAMP
- billing_period_end: TIMESTAMP
- created_at: TIMESTAMP
companies
Company profiles and configuration.
- id: UUID (Primary Key)
- user_id: UUID (Foreign Key)
- name: TEXT
- address: TEXT
- industry: TEXT
- website: TEXT
- overview: TEXT
- background: TEXT
- products_services: TEXT
- account_email: TEXT (for email campaigns)
- account_password: TEXT (encrypted)
- account_type: TEXT (gmail, outlook, etc.)
- cronofy_access_token: TEXT
- cronofy_refresh_token: TEXT
- cronofy_provider: TEXT
- voice_agent_settings: JSONB
- custom_calendar_link: TEXT
- last_processed_uid: TEXT (for bounce processing)
- created_at: TIMESTAMP
products
Product/service offerings for targeting.
- id: UUID (Primary Key)
- company_id: UUID (Foreign Key)
- product_name: TEXT
- file_name: TEXT (uploaded document)
- original_filename: TEXT
- description: TEXT
- enriched_information: JSONB
- ideal_icps: JSONB (Ideal Customer Profiles)
- created_at: TIMESTAMP
leads
Prospect database with enrichment.
- id: UUID (Primary Key)
- company_id: UUID (Foreign Key)
- upload_task_id: UUID (Foreign Key)
- name: TEXT
- first_name: TEXT
- last_name: TEXT
- email: TEXT
- company: TEXT
- phone_number: TEXT
- job_title: TEXT
- lead_source: TEXT
- education: TEXT
- personal_linkedin_url: TEXT
- country: TEXT
- website: TEXT
- company_linkedin_url: TEXT
- company_description: TEXT
- technologies: JSONB
- financials: JSONB
- enriched_data: JSONB (AI-generated insights)
- deleted_at: TIMESTAMP (soft delete)
- created_at: TIMESTAMP
campaigns
Multi-channel campaign definitions.
- id: UUID (Primary Key)
- company_id: UUID (Foreign Key)
- product_id: UUID (Foreign Key)
- name: TEXT
- description: TEXT
- type: TEXT (email, call, email_and_call, linkedin)
- template: TEXT
- number_of_reminders: INTEGER
- days_between_reminders: INTEGER
- phone_number_of_reminders: INTEGER
- phone_days_between_reminders: INTEGER
- auto_reply_enabled: BOOLEAN
- trigger_call_on: TEXT
- scheduled_at: TIMESTAMP
- auto_run_triggered: BOOLEAN
- created_at: TIMESTAMP
campaign_runs
Execution history and status.
- id: UUID (Primary Key)
- campaign_id: UUID (Foreign Key)
- run_at: TIMESTAMP
- leads_total: INTEGER
- status: TEXT (idle, running, completed, failed)
- failure_reason: TEXT
- celery_task_id: TEXT
- created_at: TIMESTAMP
Communication Tables
email_logs
Email campaign tracking.
- id: UUID (Primary Key)
- campaign_id: UUID (Foreign Key)
- campaign_run_id: UUID (Foreign Key)
- lead_id: UUID (Foreign Key)
- sent_at: TIMESTAMP
- has_replied: BOOLEAN
- has_opened: BOOLEAN
- has_meeting_booked: BOOLEAN
- last_reminder_sent: VARCHAR(2)
- last_reminder_sent_at: TIMESTAMP
- created_at: TIMESTAMP
email_log_details
Individual email messages in threads.
- id: UUID (Primary Key)
- email_logs_id: UUID (Foreign Key)
- message_id: TEXT (Unique)
- email_subject: TEXT
- email_body: TEXT
- sender_type: TEXT (user, assistant)
- sent_at: TIMESTAMP
- from_name: TEXT
- from_email: TEXT
- to_email: TEXT
- reminder_type: VARCHAR(2)
- created_at: TIMESTAMP
calls
Voice call records.
- id: UUID (Primary Key)
- lead_id: UUID (Foreign Key)
- product_id: UUID (Foreign Key)
- campaign_id: UUID (Foreign Key)
- campaign_run_id: UUID (Foreign Key)
- duration: INTEGER
- sentiment: TEXT
- summary: TEXT
- bland_call_id: TEXT
- has_meeting_booked: BOOLEAN
- transcripts: JSONB
- script: TEXT
- recording_url: TEXT
- failure_reason: TEXT
- last_reminder_sent: VARCHAR(2)
- last_reminder_sent_at: TIMESTAMP
- is_reminder_eligible: BOOLEAN
- last_called_at: TIMESTAMP
- created_at: TIMESTAMP
Queue Tables
email_queue
Email delivery queue with retry logic.
- id: UUID (Primary Key)
- company_id: UUID (Foreign Key)
- campaign_id: UUID (Foreign Key)
- campaign_run_id: UUID (Foreign Key)
- lead_id: UUID (Foreign Key)
- email_log_id: UUID (Foreign Key)
- subject: TEXT
- email_body: TEXT
- status: TEXT (pending, processing, sent, failed)
- priority: INTEGER
- retry_count: INTEGER
- max_retries: INTEGER
- error_message: TEXT
- message_id: TEXT
- reference_ids: TEXT (for threading)
- scheduled_for: TIMESTAMP
- processed_at: TIMESTAMP
- created_at: TIMESTAMP
call_queue
Call execution queue.
- id: UUID (Primary Key)
- company_id: UUID (Foreign Key)
- campaign_id: UUID (Foreign Key)
- campaign_run_id: UUID (Foreign Key)
- lead_id: UUID (Foreign Key)
- call_log_id: UUID (Foreign Key)
- status: TEXT (pending, processing, sent, failed)
- priority: INTEGER
- retry_count: INTEGER
- max_retries: INTEGER
- error_message: TEXT
- call_script: TEXT
- work_time_start: TIME
- work_time_end: TIME
- processed_at: TIMESTAMP
- created_at: TIMESTAMP
Supporting Tables
user_company_profiles
Multi-user company access with roles.
- id: UUID (Primary Key)
- user_id: UUID (Foreign Key)
- company_id: UUID (Foreign Key)
- role: VARCHAR(5) (admin, sdr)
- created_at: TIMESTAMP
booked_meetings
Tracks successful meeting bookings for billing.
- id: UUID (Primary Key)
- user_id: UUID (Foreign Key)
- company_id: UUID (Foreign Key)
- item_id: UUID (email_logs or calls id)
- type: TEXT (email, call)
- booked_at: TIMESTAMP
- reported_to_stripe: BOOLEAN
- created_at: TIMESTAMP
upload_tasks
Async CSV upload processing.
- id: UUID (Primary Key)
- company_id: UUID (Foreign Key)
- user_id: UUID (Foreign Key)
- file_url: TEXT (storage location)
- file_name: TEXT
- type: TEXT (leads, do_not_email)
- status: TEXT (pending, processing, completed, failed)
- result: TEXT (JSON result)
- celery_task_id: TEXT
- created_at: TIMESTAMP
- updated_at: TIMESTAMP
do_not_email_list
Global and company-specific suppression list.
- id: UUID (Primary Key)
- email: TEXT
- reason: TEXT
- company_id: UUID (NULL for global)
- created_at: TIMESTAMP
- updated_at: TIMESTAMP
API Endpoints
Authentication
POST /api/auth/signup- User registrationPOST /api/auth/login- User login (returns JWT)POST /api/auth/verify- Email verificationPOST /api/auth/resend-verification- Resend verification emailPOST /api/auth/forgot-password- Request password resetPOST /api/auth/reset-password- Reset password with tokenGET /api/users/me- Get current user detailsPATCH /api/users/me- Update user profile
Company Management
POST /api/companies- Create companyGET /api/companies- List user's companiesGET /api/companies/{company_id}- Get company detailsPATCH /api/companies/{company_id}- Update companyDELETE /api/companies/{company_id}- Soft delete companyPATCH /api/companies/{company_id}/account-credentials- Update email credentialsGET /api/companies/{company_id}/account-email/check- Check if email exists in other companiesPATCH /api/companies/{company_id}/voice-agent-settings- Update call settingsGET /api/companies/{company_id}/users- List company team membersPOST /api/companies/{company_id}/invite-users- Invite team membersDELETE /api/companies/{company_id}/users/{user_company_profile_id}- Remove team member
Product Management
POST /api/companies/{company_id}/products- Create productGET /api/companies/{company_id}/products- List productsGET /api/products/{product_id}- Get product detailsPATCH /api/products/{product_id}- Update productDELETE /api/products/{product_id}- Soft delete productGET /api/products/{product_id}/icps- Get ideal customer profilesPATCH /api/products/{product_id}/icps- Update ICPs
Lead Management
POST /api/companies/{company_id}/leads/upload- Upload leads CSVPOST /api/companies/{company_id}/leads- Create single leadGET /api/companies/{company_id}/leads- List leads (paginated)GET /api/leads/{lead_id}- Get lead details with communication historyDELETE /api/leads/{lead_id}- Delete leadPOST /api/leads/{lead_id}/enrich- Manually trigger enrichmentGET /api/leads/search- Search leads by email or phone
Campaign Management
POST /api/companies/{company_id}/campaigns- Create campaignGET /api/companies/{company_id}/campaigns- List campaignsGET /api/campaigns/{campaign_id}- Get campaign detailsPOST /api/campaigns/{campaign_id}/run- Execute campaignPOST /api/campaigns/{campaign_id}/test-run- Test campaign with single leadGET /api/campaigns/{campaign_id}/runs- List campaign execution historyPOST /api/campaigns/{campaign_id}/retry- Retry failed campaign itemsPOST /api/campaigns/{campaign_id}/generate-campaign- AI-generate campaign content
Email Management
GET /api/companies/{company_id}/emails- List email logs (paginated)GET /api/emails/{email_log_id}- Get email conversation threadPOST /api/companies/{company_id}/emails/throttle- Update email throttle settingsGET /api/companies/{company_id}/emails/throttle- Get throttle settings
Call Management
GET /api/companies/{company_id}/calls- List call logs (paginated)GET /api/calls/{call_id}- Get call detailsPOST /api/webhooks/bland- Bland AI webhook for call updates
Queue Management
GET /api/companies/{company_id}/email-queues- View email queueGET /api/companies/{company_id}/call-queues- View call queueGET /api/campaign-runs/{campaign_run_id}/email-queues- View run-specific email queuePOST /api/call-queues/{queue_id}/retry- Retry failed call queue item
Calendar Integration
GET /api/calendar/connect- Initiate Cronofy OAuthGET /api/calendar/callback- Cronofy OAuth callbackPOST /api/calendar/disconnect- Disconnect calendarPOST /api/book-appointment- Book meeting slot
LinkedIn Integration
POST /api/linkedin/auth- Create LinkedIn hosted auth linkGET /api/linkedin/accounts- List connected LinkedIn accountsDELETE /api/linkedin/accounts/{account_id}- Disconnect LinkedIn accountGET /api/linkedin/messaging/stats- Get LinkedIn messaging statisticsPOST /api/webhooks/unipile- Unipile webhook for LinkedIn events
Subscription & Billing
POST /api/checkout-sessions- Create Stripe checkout sessionGET /api/subscriptions/current- Get current subscription detailsPOST /api/subscriptions/cancel- Cancel subscriptionPOST /api/subscriptions/update- Update subscriptionPOST /api/webhooks/stripe- Stripe webhook handler
Partner Applications
POST /api/partner-applications- Submit partnership applicationGET /api/partner-applications- List applications (admin)GET /api/partner-applications/{application_id}- Get application detailsPATCH /api/partner-applications/{application_id}/status- Update application statusPOST /api/partner-applications/{application_id}/notes- Add note to applicationGET /api/partner-applications/stats- Get application statistics
Web Agent (Bland AI Integration)
POST /api/web-agent/create- Create web voice agentPOST /api/web-agent/webhook- Web agent webhook handler
File Management
GET /api/upload-tasks- List upload tasks (paginated)GET /api/upload-tasks/{task_id}/skipped-rows- Get skipped rows from uploadPOST /api/files/download/leads- Download leads templatePOST /api/files/download/do-not-email- Download do-not-email template
Do Not Email Management
POST /api/do-not-email/add- Add email to suppression listGET /api/do-not-email/list- List suppressed emailsDELETE /api/do-not-email/{id}- Remove from suppression listPOST /api/do-not-email/bulk-import- Bulk import suppression listGET /api/do-not-email/check- Check if email is suppressed
Script Generation (Testing/Preview)
POST /api/campaigns/{campaign_id}/generate-call-script- Generate call script previewPOST /api/campaigns/{campaign_id}/generate-email-script- Generate email preview
Installation & Setup
Prerequisites
- Python 3.12+
- PostgreSQL (via Supabase or self-hosted)
- Redis
- Required API keys (OpenAI, Bland AI, Stripe, etc.)
Installation Methods
Option 1: Install from PyPI (Recommended)
pip install reachgenie
Then run:
reachgenie
Option 2: Install from GitHub
pip install git+https://github.com/alinaqi/reachgenie.git
Option 3: Development Installation
- Clone the repository
git clone https://github.com/alinaqi/reachgenie.git
cd reachgenie/backend
- Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
- Install in development mode
# Install package in editable mode
pip install -e .
# Or with development dependencies
pip install -e ".[dev]"
Configuration
- Set up environment variables
cp .env.example .env
# Edit .env with your actual credentials
- Set up database
# Run schema.sql on your PostgreSQL database
psql -U postgres -d your_database -f schema.sql
# Run any pending migrations
# Check the migrations/ directory for migration files
See INSTALL.md for detailed installation instructions.
Docker Deployment
- Build and start services
docker compose up -d
This starts:
- web: FastAPI application (port 8000)
- redis: Redis server (port 6379)
- celery_worker: Background task processor
- flower: Celery monitoring dashboard (port 5555)
- View logs
docker compose logs -f
- Stop services
docker compose down
Environment Variables
Create a .env file in the root directory with the following variables:
Database & Core
SUPABASE_URL=your_supabase_project_url
SUPABASE_KEY=your_supabase_anon_key
SUPABASE_SERVICE_KEY=your_supabase_service_role_key
JWT_SECRET_KEY=your_jwt_secret_key_here
AI Services
OPENAI_API_KEY=sk-your-openai-api-key
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
PERPLEXITY_API_KEY=pplx-your-perplexity-key
Voice Calls (Bland AI)
BLAND_API_KEY=your_bland_api_key
BLAND_TOOL_ID=your_bland_tool_id
BLAND_SECRET_KEY=your_bland_tool_secret
WEBHOOK_BASE_URL=https://your-domain.com
Email Services
MAILJET_API_KEY=your_mailjet_api_key
MAILJET_API_SECRET=your_mailjet_api_secret
MAILJET_SENDER_EMAIL=verified-sender@yourdomain.com
MAILJET_SENDER_NAME=ReachGenie
MAILJET_WEBHOOK_SECRET=your_mailjet_webhook_secret
MAILJET_PARSE_EMAIL=parse@yourdomain.com
Partner Application Emails
NOREPLY_EMAIL=noreply@yourdomain.com
NOREPLY_PASSWORD=your_email_app_password
NOREPLY_PROVIDER=gmail # or outlook, yahoo
Calendar Integration
CRONOFY_CLIENT_ID=your_cronofy_client_id
CRONOFY_CLIENT_SECRET=your_cronofy_client_secret
CALENDLY_USERNAME=your_calendly_username
LinkedIn (Unipile)
UNIPILE_API_KEY=your_unipile_api_key
UNIPILE_DSN=your_unipile_dsn
UNIPILE_WEBHOOK_SECRET=your_unipile_webhook_secret
LINKEDIN_MESSAGING_ENABLED=true
LINKEDIN_DAILY_INVITE_LIMIT=80
LINKEDIN_DAILY_PROFILE_VIEW_LIMIT=100
LINKEDIN_MESSAGE_DELAY_SECONDS=20
Payment Processing (Stripe)
STRIPE_SECRET_KEY=sk_test_your_stripe_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
STRIPE_MEETINGS_BOOKED_METER_ID=mtr_your_meter_id
# Fixed Plan Price IDs
STRIPE_PRICE_FIXED_2500=price_xxx
STRIPE_PRICE_FIXED_5000=price_xxx
STRIPE_PRICE_FIXED_7500=price_xxx
STRIPE_PRICE_FIXED_10000=price_xxx
# Performance Plan Price IDs
STRIPE_PRICE_PERFORMANCE_2500=price_xxx
STRIPE_PRICE_PERFORMANCE_5000=price_xxx
STRIPE_PRICE_PERFORMANCE_7500=price_xxx
STRIPE_PRICE_PERFORMANCE_10000=price_xxx
STRIPE_PRICE_PERFORMANCE_MEETINGS=price_xxx
# Channel Add-on Price IDs
STRIPE_PRICE_EMAIL_FIXED=price_xxx
STRIPE_PRICE_PHONE_FIXED=price_xxx
STRIPE_PRICE_LINKEDIN_FIXED=price_xxx
STRIPE_PRICE_EMAIL_PERFORMANCE=price_xxx
STRIPE_PRICE_PHONE_PERFORMANCE=price_xxx
STRIPE_PRICE_LINKEDIN_PERFORMANCE=price_xxx
Security & Monitoring
ENCRYPTION_KEY=your_32_byte_encryption_key
ENCRYPTION_SALT=your_salt_value
BUGSNAG_API_KEY=your_bugsnag_api_key
ENVIRONMENT=development # or staging, production
Application Settings
FRONTEND_URL=http://localhost:3000
REDIS_URL=redis://localhost:6379/0
PostgreSQL (if self-hosting)
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_password
POSTGRES_HOST=localhost
POSTGRES_DB=reachgenie
POSTGRES_PORT=5432
Running the Application
Development Mode
Using Python directly:
# Activate virtual environment
source venv/bin/activate
# Run FastAPI with auto-reload
uvicorn src.main:app --reload --host 0.0.0.0 --port 8000
# In separate terminal, start Redis
redis-server
# In another terminal, start Celery worker
celery -A src.celery_app.tasks worker --loglevel=info
# (Optional) Start Flower for Celery monitoring
celery -A src.celery_app.tasks flower --port=5555
Using Docker Compose:
docker compose up
Production Mode
- Build the Docker image:
docker compose build
- Start services:
docker compose up -d
- Set up reverse proxy (nginx example):
server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- Set up SSL with Let's Encrypt:
sudo certbot --nginx -d api.yourdomain.com
Accessing the Application
- API Documentation: http://localhost:8000/docs
- ReDoc Documentation: http://localhost:8000/redoc
- Flower Dashboard: http://localhost:5555 (admin/password)
- Health Check: http://localhost:8000/
Background Jobs & Cron Tasks
ReachGenie uses cron jobs for automated background processing. These scripts should be scheduled using crontab or a task scheduler.
Cron Schedule Configuration
Add these to your crontab (crontab -e):
# Process email queue every minute
* * * * * cd /path/to/backend && bash crons/process_email_queue.sh
# Process call queue every minute
* * * * * cd /path/to/backend && bash crons/process_call_queue.sh
# Process incoming emails every 5 minutes (replies, bounces)
*/5 * * * * cd /path/to/backend && bash crons/process_emails.sh
# Process email bounces every 10 minutes
*/10 * * * * cd /path/to/backend && bash crons/process_bounces.sh
# Send email reminders every hour
0 * * * * cd /path/to/backend && bash crons/send_reminders.sh
# Send call reminders every 2 hours
0 */2 * * * cd /path/to/backend && bash crons/send_call_reminders.sh
# Update call statistics daily at 2 AM
0 2 * * * cd /path/to/backend && bash crons/update_call_stats.sh
# Run scheduled campaigns every hour
0 * * * * cd /path/to/backend && bash crons/run_scheduled_campaigns.sh
# Populate campaign schedule daily at 1 AM
0 1 * * * cd /path/to/backend && bash crons/campaign_schedule_populator.sh
# Send campaign statistics email daily at 9 AM
0 9 * * * cd /path/to/backend && bash crons/send_campaign_run_stats_email.sh
Cron Job Descriptions
Email Queue Processor (process_email_queue.sh)
- Frequency: Every minute
- Purpose: Processes pending emails in the queue
- Features:
- Respects throttle limits (hourly/daily)
- Handles retries with exponential backoff
- Tracks email delivery status
- Updates email logs
Call Queue Processor (process_call_queue.sh)
- Frequency: Every minute
- Purpose: Processes pending calls in the queue
- Features:
- Respects business hours
- Initiates Bland AI calls
- Handles call failures and retries
- Updates call logs
Email Processor (process_emails.sh)
- Frequency: Every 5 minutes
- Purpose: Monitors inbox for replies and processes them
- Features:
- Detects email replies
- AI-powered response generation
- Updates conversation threads
- Detects meeting booking intent
Bounce Processor (process_bounces.sh)
- Frequency: Every 10 minutes
- Purpose: Processes email bounces and updates suppression list
- Features:
- Parses bounce notifications
- Automatically adds to do-not-email list
- Categorizes bounce types (hard/soft)
- Updates lead status
Email Reminder Sender (send_reminders.sh)
- Frequency: Every hour
- Purpose: Sends follow-up emails to non-responders
- Features:
- Checks reminder eligibility
- AI-generated contextual reminders
- Respects reminder limits
- Tracks reminder sequence
Call Reminder Sender (send_call_reminders.sh)
- Frequency: Every 2 hours
- Purpose: Follows up on unsuccessful calls
- Features:
- Identifies callback candidates
- Schedules retry attempts
- Respects call limits
- Different scripts for different call outcomes
Call Stats Updater (update_call_stats.sh)
- Frequency: Daily at 2 AM
- Purpose: Updates call analytics and statistics
- Features:
- Aggregates call metrics
- Calculates conversion rates
- Updates dashboard data
- Generates reports
Scheduled Campaign Runner (run_scheduled_campaigns.sh)
- Frequency: Every hour
- Purpose: Executes campaigns scheduled for specific times
- Features:
- Checks scheduled_at timestamps
- Triggers campaign execution
- Handles timezone conversions
- Prevents duplicate runs
Campaign Schedule Populator (campaign_schedule_populator.sh)
- Frequency: Daily at 1 AM
- Purpose: Pre-schedules campaign messages for optimal delivery
- Features:
- Analyzes best send times
- Creates message schedule
- Optimizes for time zones
- Balances sending load
Campaign Stats Emailer (send_campaign_run_stats_email.sh)
- Frequency: Daily at 9 AM
- Purpose: Sends performance summaries to users
- Features:
- Aggregates campaign metrics
- AI-generated insights
- Benchmark comparisons
- Actionable recommendations
Celery Background Tasks
Campaign Execution (run_campaign)
- Trigger: User initiates campaign
- Purpose: Asynchronous campaign processing
- Process:
- Fetch campaign and company details
- Retrieve eligible leads
- Generate personalized content for each lead
- Queue emails/calls for delivery
- Update campaign run status
Lead Upload Processing (process_leads)
- Trigger: CSV file upload
- Purpose: Async lead import and validation
- Process:
- Download CSV from storage
- Validate data format
- Check for duplicates
- Enrich with AI where possible
- Save to database
- Track skipped rows
Do Not Contact Processing (process_do_not_contact)
- Trigger: Bulk suppression list upload
- Purpose: Import bounce/unsubscribe lists
- Process:
- Parse CSV file
- Validate email format
- Add to suppression table
- Prevent duplicates
Integrations
OpenAI (Content Generation)
- Purpose: Email content and call script generation
- Models Used: GPT-4, GPT-3.5-turbo
- Use Cases:
- Personalized email composition
- Subject line generation
- Follow-up email crafting
- Call script personalization
- Response analysis
Anthropic Claude (Advanced AI)
- Purpose: Enhanced content generation and analysis
- Models Used: Claude 3 (Opus, Sonnet)
- Use Cases:
- Long-form content generation
- Complex personalization
- Strategic messaging
- Campaign summaries
Perplexity AI (Lead Enrichment)
- Purpose: Company and prospect research
- Use Cases:
- Company background research
- Industry analysis
- Pain point identification
- Recent news and events
- Technology stack detection
Bland AI (Voice Calls)
- Purpose: Automated AI-powered phone calls
- Features:
- Natural voice synthesis
- Real-time conversation
- Meeting booking via tools
- Call recording and transcription
- Sentiment analysis
- Webhook callbacks
- Integration Points:
/start-callendpoint for initiation- Webhook receiver for call updates
- Tool integration for calendar booking
Stripe (Payments & Subscriptions)
- Purpose: Subscription billing and metering
- Features:
- Trial management (14 days)
- Fixed plan subscriptions ($99-$399/month)
- Performance plan metering ($50/meeting)
- Channel add-ons ($49-$99/month)
- Usage-based billing
- Webhook event processing
- Events Handled:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
Cronofy (Calendar Integration)
- Purpose: Meeting scheduling automation
- Features:
- OAuth authentication
- Multi-calendar support (Google, Outlook, iCloud)
- Availability checking
- Event creation
- Meeting confirmations
- Flow:
- User connects calendar via OAuth
- System checks availability
- Prospect selects time slot
- Meeting auto-booked
- Both parties notified
Mailjet (Email Delivery)
- Purpose: Transactional and campaign email delivery
- Features:
- High deliverability rates
- Email tracking (opens, clicks)
- Bounce handling
- Template management
- Webhook events
- Use Cases:
- Campaign email delivery
- Welcome emails
- Verification emails
- Password reset
- System notifications
Unipile (LinkedIn Automation)
- Purpose: LinkedIn outreach automation
- Features:
- Account connection via hosted auth
- Connection request automation
- Automated messaging
- Profile viewing
- Message threading
- Rate limiting (80 invites/day, 100 views/day)
- Safety Features:
- Human-like delays
- Daily limit enforcement
- Activity randomization
Bugsnag (Error Monitoring)
- Purpose: Error tracking and alerting
- Features:
- Automatic error capture
- Stack trace analysis
- Release tracking
- User impact analysis
- Team notifications
Development Guide
Code Structure Principles
- Separation of Concerns: Routes handle HTTP, services contain business logic
- Async/Await: All I/O operations are asynchronous
- Type Hints: Pydantic models for request/response validation
- Error Handling: Comprehensive exception handling with Bugsnag integration
- Security: JWT authentication, password hashing, encrypted credentials
Adding a New Feature
- Define Pydantic Models (
src/models.py)
class NewFeatureRequest(BaseModel):
name: str
description: Optional[str] = None
class NewFeatureResponse(BaseModel):
id: UUID
name: str
created_at: datetime
- Create Database Functions (
src/database.py)
async def create_new_feature(name: str, description: str):
query = """
INSERT INTO new_features (name, description)
VALUES ($1, $2)
RETURNING *
"""
async with pg_pool.acquire() as conn:
row = await conn.fetchrow(query, name, description)
return dict(row)
- Add Business Logic (
src/services/new_feature_service.py)
class NewFeatureService:
async def process_feature(self, data: dict):
# Business logic here
return result
- Create Route (
src/routes/new_feature.py)
router = APIRouter(prefix="/api/new-features", tags=["New Features"])
@router.post("/", response_model=NewFeatureResponse)
async def create_feature(
request: NewFeatureRequest,
current_user: dict = Depends(get_current_user)
):
result = await create_new_feature(request.name, request.description)
return result
- Register Router (
src/main.py)
from src.routes.new_feature import router as new_feature_router
app.include_router(new_feature_router)
Testing
Run the test suite:
# Run all tests
pytest
# Run specific test file
pytest tests/test_auth.py
# Run with coverage
pytest --cov=src tests/
# Run with verbose output
pytest -v
Database Migrations
- Create migration file in
migrations/directory - Name it with timestamp:
YYYY-MM-DD-description.sql - Run migration:
psql -U postgres -d reachgenie -f migrations/2025-09-30-add-new-feature.sql
Debugging
Enable debug logging:
import logging
logging.basicConfig(level=logging.DEBUG)
Use Flower to monitor Celery:
# Access at http://localhost:5555
# Default credentials: admin/password
Check Redis queue:
redis-cli
> LLEN celery
> LRANGE celery 0 -1
Project Structure
backend/
├── src/
│ ├── main.py # FastAPI application entry point
│ ├── config.py # Configuration and settings
│ ├── models.py # Pydantic models
│ ├── database.py # Database operations
│ ├── auth.py # Authentication logic
│ ├── bland_client.py # Bland AI integration
│ ├── perplexity_enrichment.py # Lead enrichment
│ │
│ ├── routes/ # API route handlers
│ │ ├── accounts.py # Account management
│ │ ├── calendar.py # Calendar integration
│ │ ├── call_queues.py # Call queue management
│ │ ├── call_queue_status.py
│ │ ├── campaign_retry.py # Campaign retry logic
│ │ ├── checkout_sessions.py # Stripe checkout
│ │ ├── companies.py # Company CRUD
│ │ ├── do_not_email.py # Suppression list
│ │ ├── email_queues.py # Email queue management
│ │ ├── file_downloads.py # Template downloads
│ │ ├── linkedin.py # LinkedIn integration
│ │ ├── partner_applications.py
│ │ ├── skipped_rows.py # Upload error handling
│ │ ├── stripe_webhooks.py # Stripe webhooks
│ │ ├── subscriptions.py # Subscription management
│ │ ├── unipile_webhooks.py # LinkedIn webhooks
│ │ ├── upload_tasks.py # Async upload tracking
│ │ └── web_agent.py # Web voice agent
│ │
│ ├── services/ # Business logic layer
│ │ ├── advanced_reminders/
│ │ │ ├── behavioral_triggers.py
│ │ │ ├── dynamic_content.py
│ │ │ ├── enhanced_reminder_generator.py
│ │ │ └── reminder_strategies.py
│ │ ├── bland_calls.py # Call initiation
│ │ ├── call_generation.py # Script generation
│ │ ├── call_queue_processor.py
│ │ ├── campaign_schedule_populator.py
│ │ ├── campaign_stats_emailer.py
│ │ ├── campaigns.py # Campaign orchestration
│ │ ├── company_personalization_service.py
│ │ ├── email_generation.py # Email content generation
│ │ ├── email_open_detector.py
│ │ ├── email_queue_processor.py
│ │ ├── email_service.py # Email sending
│ │ ├── linkedin_campaign_processor.py
│ │ ├── linkedin_service.py
│ │ ├── partner_application_service.py
│ │ ├── perplexity_service.py
│ │ ├── stripe_service.py
│ │ └── subscriptions.py
│ │
│ ├── ai_services/ # AI integration layer
│ │ ├── anthropic_service.py
│ │ └── message_generation.py
│ │
│ ├── celery_app/ # Celery configuration
│ │ ├── __init__.py
│ │ ├── config.py
│ │ └── tasks/
│ │ ├── __init__.py
│ │ ├── process_do_not_contact.py
│ │ ├── process_leads.py
│ │ └── run_campaign.py
│ │
│ ├── scripts/ # Cron job scripts
│ │ ├── campaign_schedule_populator.py
│ │ ├── check_mailjet_config.py
│ │ ├── check_postgres_connection.py
│ │ ├── create_bland_web_agent.py
│ │ ├── enhanced_reminders/
│ │ ├── generate_campaign_summary_email.py
│ │ ├── generate_company_campaign_summary.py
│ │ ├── list_campaigns.py
│ │ ├── process_bounces.py
│ │ ├── process_call_queues.py
│ │ ├── process_email_queues.py
│ │ ├── process_emails.py
│ │ ├── run_email_processor.py
│ │ ├── run_scheduled_campaigns.py
│ │ ├── send_call_reminders.py
│ │ ├── send_campaign_run_stats_email.py
│ │ ├── send_reminders.py
│ │ ├── send_reminders_enhanced.py
│ │ ├── setup_stripe_products.py
│ │ ├── test_*.py # Various test scripts
│ │ └── update_call_stats.py
│ │
│ ├── utils/ # Utility functions
│ │ ├── calendar_utils.py # Calendar helpers
│ │ ├── email_utils.py # Email formatting
│ │ ├── encryption.py # Password encryption
│ │ ├── file_parser.py # CSV parsing
│ │ ├── llm.py # LLM utilities
│ │ ├── smtp_client.py # SMTP client
│ │ └── string_utils.py # String operations
│ │
│ ├── prompts/ # AI prompts
│ │ ├── company_info_prompt.py
│ │ └── company_insights_prompt.py
│ │
│ ├── templates/ # Email templates
│ │ └── email_templates.py
│ │
│ └── web/ # Web assets
│ └── tracker.png # Email tracking pixel
│
├── crons/ # Cron shell scripts
│ ├── campaign_schedule_populator.sh
│ ├── process_bounces.sh
│ ├── process_call_queue.sh
│ ├── process_email_queue.sh
│ ├── process_emails.sh
│ ├── run_scheduled_campaigns.sh
│ ├── send_call_reminders.sh
│ ├── send_campaign_run_stats_email.sh
│ ├── send_reminders.sh
│ └── update_call_stats.sh
│
├── docs/ # Documentation
│ ├── README.md
│ ├── architecture.md
│ ├── campaign_summary_email.md
│ ├── development.md
│ ├── email_ai_reply.md
│ ├── email_bounce_handling.md
│ ├── email_campaigns.md
│ ├── installation.md
│ ├── marketing_guide.md
│ ├── partnership_flow.md
│ ├── partnership_frontend_guide.md
│ ├── product_enrichment_guideline.md
│ ├── stripe-integration.md
│ ├── web_agent.md
│ └── workflows.md
│
├── migrations/ # Database migrations
│ └── *.sql
│
├── tests/ # Test suite
│ ├── test_auth.py
│ ├── test_campaigns.py
│ └── ...
│
├── .env.example # Environment template
├── .gitignore
├── docker-compose.yml # Docker orchestration
├── Dockerfile # Container definition
├── leads_fields.json # Lead CSV mapping
├── postgres_functions.sql # PostgreSQL functions
├── requirements.txt # Python dependencies
├── schema.sql # Database schema
└── README.md # This file
Key Services Explained
Campaign Execution Flow
- User creates campaign via API
- Campaign queued in Celery
- Worker picks up task
- Fetches eligible leads
- For each lead:
- AI enrichment (if needed)
- Content generation (email/script)
- Queue in Redis
- Queue processor sends/calls
- Track responses and engagement
- Trigger follow-ups based on rules
Email Processing Flow
- Email added to Redis queue
- Queue processor checks throttle limits
- SMTP client sends email
- Message-ID and References headers set for threading
- Email log created with tracking pixel
- IMAP monitor watches for replies
- AI generates contextual response
- Response sent and logged
Call Processing Flow
- Call added to Redis queue
- Queue processor checks business hours
- Script generated with AI
- Bland AI initiates call
- Real-time conversation with tools
- Calendar booking if interest shown
- Webhook receives call results
- Sentiment analysis and logging
Support & Contributing
For issues, questions, or contributions, please:
- Check existing documentation in
/docs - Review API documentation at
/docsendpoint - Submit issues with detailed reproduction steps
- Follow code style and testing requirements
Campaign Summary Email Feature
ReachGenie now includes a comprehensive Campaign Summary Email feature that provides customers with detailed reports on their campaign performance, prospect enrichment, and email management activities.
Features
- Detailed prospect enrichment information with examples
- Automated email management metrics (bounces and unsubscribes)
- Comprehensive campaign results with industry benchmark comparisons
- Next steps information and scheduling
Usage
Send a campaign summary email via API:
curl -X POST "https://api.reachgenie.com/api/campaigns/{campaign_id}/summary-email" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"recipient_email": "user@example.com"}'
For testing or manual generation, use the command-line script:
# Send the email
python -m src.scripts.generate_campaign_summary_email <campaign_id> <recipient_email>
# Save to file for testing
python -m src.scripts.test_campaign_summary <campaign_id> <recipient_email> --save-to-file
See the full documentation in docs/campaign_summary_email.md.
License
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
Commercial Use
For commercial use or if you need a commercial license, please contact: Ali Shaheen - ashaheen@workhub.ai
The AGPL-3.0 license requires that:
- Any modifications to the software must be made available under the same license
- If you run a modified version on a server, you must make the source code available to users
- Commercial deployments may require a separate commercial license
See the LICENSE file for full details.
Built with FastAPI, powered by AI, designed for scale.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reachgenie-0.1.0.tar.gz.
File metadata
- Download URL: reachgenie-0.1.0.tar.gz
- Upload date:
- Size: 211.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
511d3c7b82438886afe86ac601f6963bc27e003e8aed6e56cc2c8930bcd4ef9e
|
|
| MD5 |
3d8f482beae7aeabc425638d64b0d426
|
|
| BLAKE2b-256 |
d653cc6be7a59a00e7616c393861765074e3a1eed8ba2ccdd0a027ada56a2c88
|
File details
Details for the file reachgenie-0.1.0-py3-none-any.whl.
File metadata
- Download URL: reachgenie-0.1.0-py3-none-any.whl
- Upload date:
- Size: 123.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08c19f15858cdfbf0bb9b0777fdb97a70aa54f3af1561754c43a8092d24f48ba
|
|
| MD5 |
67021ae6665ecda130aea645d0402e4d
|
|
| BLAKE2b-256 |
dd49e801f53fa628e7cf4679767979559a38cdaa1687251653d9ac0699fbc207
|