📥 Inbound Module
📖 Overview
The Inbound module manages lead capture and routing from multiple sources including web forms, landing pages, third-party integrations, and custom webhooks. It provides campaign management, lead tracking, automated contact creation, and integration with InstaSites/InstaReports for automated prospect outreach.
File Path: internal/api/v1/inbound/
Key Capabilities
- Multi-Source Lead Capture: Forms, webhooks, API, integrations
- Campaign Management: Create and configure lead capture campaigns
- Lead Tracking: Track lead source, freshness, assignment
- Auto-Contact Creation: Automatically create CRM contacts/businesses from leads
- InstaReport/InstaSite Integration: Auto-generate reports/sites for new leads
- Webhook Routing: Forward leads to external systems
- Lead Filtering: Filter by date, type, integration, rep assignment
- Lead Analytics: Track conversion rates and lead quality
🗄️ Collections Used
inbound.leads-data
- Purpose: Store captured leads with source tracking
- Key Fields:
account_id(ObjectId) - Owner accountuser_id(ObjectId) - Assigned user/repcampaign_id(ObjectId) - Source campaigncontact_id(ObjectId) - Created CRM contacttype(String) - Lead type ('form', 'webhook', 'api')freshness(String) - 'new', 'contacted', 'qualified', 'converted'integration(String) - Source integration namedata(Object) - Captured form/webhook datainstasite(ObjectId) - Generated instasite referenceinstareport(ObjectId) - Generated instareport referencebuild_failed(Object) - InstaReport/Site build error infocreated_at(Date)
inbound.campaigns
- Purpose: Campaign configuration and settings
- Key Fields:
account_id(ObjectId)name(String) - Campaign nameintegration(String) - 'instasite_forms', 'instareport_forms', 'webhook', etc.instasite_template_id(ObjectId) - Auto-generate instasite templateinstareport_template_id(ObjectId) - Auto-generate report templateadd_person_or_business(String) - 'person' | 'business'webhook_url(String) - Forward leads to external URLfields_mapping(Object) - Map form fields to CRM fieldsauto_assign_rules(Array) - Lead assignment rulesstatus('active' | 'paused')
inbound.widget-data
- Purpose: Embeddable form widget configuration
- Key Fields:
campaign_id(ObjectId)widget_code(String) - Generated embed codestyling(Object) - Form appearance settingsthank_you_message(String)
crm.contacts
- Operations: Create (auto-create from leads)
- Usage: Store lead data as CRM contacts
🏗️ Architecture
inbound/
├── Controllers/
│ ├── leads.js # Lead CRUD operations
│ ├── campaigns.js # Campaign management
│ ├── webhooks.js # Webhook handlers
│ ├── reports.js # Analytics/reporting
│ └── auth.js # API authentication
├── Models/
│ ├── leads-data.js # Lead queries
│ ├── widget-data.js # Widget configuration
│ └── campaign-data.js # Campaign queries
├── Providers/ # External integrations
└── Routes/ # API endpoints
🔄 Data Flow
Lead Capture Flow
sequenceDiagram
participant Form as Web Form
participant API as Inbound API
participant Campaign as Campaign Logic
participant CRM as CRM Module
participant Insta as Insta Services
participant Webhook as External Webhook
Form->>API: POST /webhooks/:campaign_id
API->>Campaign: Validate campaign active
Campaign-->>API: Campaign config
API->>CRM: Create contact/business
CRM-->>API: contact_id
API->>API: Create lead record
alt InstaReport Campaign
API->>Insta: Generate InstaReport
Insta-->>API: instareport_id
else InstaSite Campaign
API->>Insta: Generate InstaSite
Insta-->>API: instasite_id
end
alt Webhook Configured
API->>Webhook: POST lead data
Webhook-->>API: Acknowledgment
end
API->>Campaign: Auto-assign to rep
API-->>Form: 200 Success + Thank you message
InstaReport/Site Rebuild Flow
flowchart TD
A[Lead with build_failed flag] --> B{Check Integration Type}
B -->|instasite_forms| C[Verify OneBalance Credit]
B -->|instareport_forms| D[Verify OneBalance Credit]
C --> E[Generate InstaSite]
D --> F[Generate InstaReport]
E --> G{Build Success?}
F --> G
G -->|Yes| H[Update lead: Remove build_failed, Add instasite/report ID]
G -->|No| I[Keep build_failed flag, Log error]
H --> J[Return Success]
I --> K[Return Error to User]
🔧 Core Functions
Lead Management
File: Controllers/leads.js
listAllLeads(req, res)
Retrieve leads with filtering and pagination.
Query Parameters:
startdate,enddate- Date range filterfreshness- Lead status filtertype- Lead type filterintegration- Integration source filterreps- Assigned rep filtersearchtext- Full-text searchsort_by,order- Sortingpage,limit- Pagination
Returns:
{
success: true,
data: [
{
_id: ObjectId,
account_id: ObjectId,
campaign_id: { name, integration },
contact_id: ObjectId,
type: 'form',
freshness: 'new',
data: { ... }, // Captured form data
created_at: Date,
instasite: ObjectId,
instareport: ObjectId
}
],
pagination: { ... }
}
rebuildFromLead(req, res)
Re-attempt InstaSite/InstaReport generation for failed builds.
Business Logic:
// Check for build failure
if (!lead.build_failed?.message) {
throw error('No failed build associated');
}
// Verify campaign type
if (!['instasite_forms', 'instareport_forms'].includes(campaign.integration)) {
throw error('Not an insta-type campaign');
}
// Verify OneBalance credits
await verifyBalance({ event: 'instasite', account, quantity: 0 });
// Retry build
const buildResponse = await instasite(account_id, owner, [business_id], template_id);
// Update lead
await leadsDataModel.update(
{ _id: lead._id },
{ $unset: { build_failed: 1 }, instasite: buildResponse[0].instasite },
);
deleteLeads(req, res)
Bulk delete leads.
Parameters:
body.leads(Array[ObjectId]) - Lead IDs to deletequery.deleteall(Boolean) - Delete all leads for account
Campaign Management
File: Controllers/campaigns.js
createCampaign(req, res)
Create new lead capture campaign.
Required Fields:
name(String)integration(String)add_person_or_business('person' | 'business')
Optional:
instasite_template_id(ObjectId)instareport_template_id(ObjectId)webhook_url(String)fields_mapping(Object)auto_assign_rules(Array)
updateCampaign(req, res)
Update campaign configuration.
toggleCampaignStatus(req, res)
Activate/pause campaign.
Webhook Handling
File: Controllers/webhooks.js
receiveLead(req, res)
Webhook endpoint for external lead submissions.
Endpoint: POST /webhooks/:campaign_id
Processing:
- Validate campaign exists and is active
- Parse webhook payload based on campaign configuration
- Map fields to CRM contact structure
- Create contact/business in CRM
- Create lead record
- Trigger InstaReport/Site generation if configured
- Forward to external webhook if configured
- Assign to rep based on rules
- Return success response
🔀 Integration Points
- CRM Module - Auto-create contacts/businesses from leads
- InstaSites - Auto-generate microsites for leads
- InstaReports - Auto-generate reports for leads
- OneBalance - Verify credits before InstaReport/Site generation
- External Webhooks - Forward leads to third-party systems
- Email Notifications - Notify reps of new lead assignments
📊 Analytics & Reporting
Available Metrics:
- Lead Volume (by source, date, campaign)
- Conversion Rates (by freshness status)
- Response Times (time to contact)
- Campaign Performance (leads per campaign)
- Rep Performance (leads assigned/converted per rep)
- Integration Performance (leads by source integration)
⚠️ Important Notes
- 🔒 Campaign Security: Campaign IDs in webhook URLs must be non-guessable
- 💰 Credit Verification: InstaReport/Site generation checks OneBalance before proceeding
- 🔄 Rebuild Safety: Failed builds can be retried without creating duplicate contacts
- 📧 Duplicate Prevention: Check existing contacts before creating new ones
- 🎯 Assignment Rules: Auto-assignment follows round-robin or rule-based logic
- 📊 Data Retention: Leads retained indefinitely for audit trail
Last Updated: 2025-10-08
Module Path:internal/api/v1/inbound/