📊 InstaReports Module
📖 Overview
The InstaReports module provides automated SEO and social media report generation for client businesses. It generates professional, white-labeled PDF reports covering Google My Business performance, social media presence, online reviews, and website SEO metrics. Reports can be sent via email/SMS and are fully customizable with agency branding.
File Path: internal/api/v1/instareports/
Key Features
- Automated Report Generation: Create SEO/social reports with single click
- Multi-Business Processing: Bulk generate reports from CSV uploads
- White-Label Branding: Custom agency logos, colors, and messaging
- Multi-Channel Delivery: Email, SMS, and web link sharing
- Template System: Pre-configured report templates (SEO, Social, Combined)
- Queue Processing: Background job queue for report generation
- Industry Benchmarks: Compare client metrics against industry averages
- Tracking: Monitor report views and engagement
🗄️ Collections Used
instareports
- Purpose: Store generated report metadata and status
- Model:
shared/models/instareports.js - Key Fields:
account_id(ObjectId) - Owner agency accountcreated_by(ObjectId) - User who created reportparent_account(ObjectId) - Parent agency (for sub-accounts)status(String) - 'QUEUED', 'GENERATING', 'COMPLETED', 'FAILED', 'CANCELLED'type(String) - Template ID (e.g., 'seo_report', 'social_report')template_id(ObjectId) - Report template referencedetails.business_info(Object) - Client business datadetails.configs(Object) - Report configurationdetails.notifications(Object) - Email/SMS settingsfile_url(String) - Generated PDF URL (S3/Wasabi)public_url(String) - Shareable web view URLcreated(Date) - Generation timestamp
instareports.queue
- Purpose: Queue for background report generation
- Key Fields:
account_id(ObjectId)type('instareport' | 'csv_instareport')template_id(ObjectId)reference_id(ObjectId) - Links toinstareportsdocumentdetails(Object) - Business info and report settingsprocess_errors(Array) - Error messages if generation failstries(Number) - Retry attemptsstatus('pending' | 'processing' | 'completed' | 'failed')
instareports.additional-information
- Purpose: Store recipient tracking and notification settings
- Key Fields:
instareport_id(ObjectId) - Parent reportaccount_id(ObjectId)recipients(Array) - Person contact IDs with notification preferencesinstareport_created_at(Date)
Recipient Structure:
{
id: ObjectId, // Person contact ID
email: {
enabled: Boolean,
sent_at: Date,
opened_at: Date
},
sms: {
enabled: Boolean,
sent_at: Date
},
viewed: Boolean, // Has accessed report
last_viewed_at: Date
}
instareports.industry-average
- Purpose: Industry benchmark data for report comparisons
- Key Fields:
industry(String) - Industry categorymetrics(Object) - Average scoreslast_updated(Date)
Supported Industries:
- Active Life, Arts & Entertainment, Automotive, Beauty & Spas, Education, Event Planning & Services, Financial Services, Food, Health & Medical, Home Services, Hotels & Travel, Professional Services, Real Estate, Restaurants, Shopping, and more (24 total)
crm.contacts
- Operations: Read (business and person contact lookup)
- Usage: Retrieve business details and person recipients
yext.publishers.logo
- Purpose: Publisher logos for social media report sections
- Usage: Display platform branding in reports
🏗️ Architecture
instareports/
├── Services/
│ ├── instareport.js # Core report generation
│ ├── create-business.js # CSV business import
│ ├── csv-to-json.js # CSV parsing
│ ├── generateFileBuffer.js # File handling
│ └── utils.js # Helper functions
├── Controllers/
│ ├── InstareportsController.js # API handlers
│ └── ...
└── Routes/ # API endpoints
🔄 Data Flow
Single Report Generation
sequenceDiagram
participant User
participant API as InstaReports API
participant DB as MongoDB
participant Queue as Queue Manager
participant Generator as Report Generator
participant Storage as S3/Wasabi
participant Notify as Notification Service
User->>API: POST /instareports (business_id, template_id)
API->>DB: Create instareports document (status: QUEUED)
API->>DB: Create instareports.queue job
API->>DB: Create additional-information record
DB-->>API: Report IDs
API-->>User: 201 Created
Queue->>DB: Poll for pending jobs
DB-->>Queue: Queue job
Queue->>Generator: Start report generation
Generator->>Generator: Fetch business data (GMB, Social, SEO)
Generator->>Generator: Apply industry benchmarks
Generator->>Generator: Generate PDF with branding
Generator->>Storage: Upload PDF
Storage-->>Generator: file_url
Generator->>DB: Update instareports (status: COMPLETED, file_url)
alt Email/SMS Enabled
Generator->>Notify: Send notifications to recipients
Notify->>DB: Update sent_at timestamps
end
CSV Bulk Upload
flowchart TD
A[User Uploads CSV] --> B[Parse CSV]
B --> C{Validate Rows}
C -->|Valid| D[Create CRM Contacts]
C -->|Invalid| E[Collect Errors]
D --> F{Contact Creation Success?}
F -->|Yes| G[Queue InstaReport Job]
F -->|No| E
G --> H[Process Queue]
E --> I[Return Error Report]
H --> J{All Reports Generated?}
J -->|Yes| K[Mark CSV Job Complete]
J -->|No| L[Retry Failed Jobs]
L --> M{Max Retries?}
M -->|Yes| N[Mark as Failed]
M -->|No| H
🔧 Core Functions
saveInstareportQueue(queue, data)
Creates a new InstaReport with associated queue job and additional information.
Parameters:
{
queue: {
uid: ObjectId, // Creator user ID
account_id: ObjectId, // Owner account
parent_account: ObjectId,
template_id: String // Report template
},
data: {
con: { // Business contact
id, name, email, phone, website, address,
social: { facebook },
industry: String
},
people: [ // Recipients
{
id: ObjectId,
email: { enabled: Boolean },
sms: { enabled: Boolean },
viewed: false
}
],
notifications: {
email: { enabled: Boolean },
sms: { enabled: Boolean }
},
configs: Object // Custom report settings
}
}
Process:
- Create
instareportsdocument with statusQUEUED - Create
instareports.additional-informationwith recipients - Create
instareports.queuejob for background processing - Return success confirmation
saveQueueData(queue)
Processes CSV bulk upload queue.
Process:
- Download CSV from S3/Wasabi using
queue.details.key - Parse CSV to JSON via
csvToJson() - Validate business data (name, phone/email, address required)
- Create CRM contacts for valid businesses via
CreateBusiness() - For each successfully created contact:
- Extract person contacts from
con.people - Call
saveInstareportQueue()to queue report
- Extract person contacts from
- Collect all errors (CSV validation errors + contact creation errors)
- Update CSV queue with error report
- Mark queue job as completed
Error Handling:
- Invalid CSV rows collected and returned to user
- Contact creation failures logged
- Individual report queue failures don't block entire batch
- CSV queue tracks
triescount for retries
🎨 Report Templates
Available Templates:
- SEO Report: Website audit, keyword rankings, backlinks, page speed
- Social Media Report: Facebook, Instagram, Twitter presence and engagement
- GMB Report: Google My Business insights, reviews, photos, posts
- Combined Report: Full-spectrum digital presence audit
Template Configuration:
{
template_id: 'seo_report',
branding: {
logo_url: String,
primary_color: String,
secondary_color: String,
agency_name: String
},
sections: [
'overview',
'website_audit',
'keyword_rankings',
'backlink_analysis',
'recommendations'
],
custom_message: String,
include_industry_benchmarks: Boolean
}
📊 Report Content
Data Sources
- Google My Business: Reviews, ratings, posts, photos, Q&A
- Website SEO: Meta tags, headings, schema markup, load time
- Social Media: Follower counts, engagement rates, post frequency
- Online Reviews: Aggregated ratings from multiple platforms
- Citations: NAP consistency across directories
Metrics Calculated
- Overall Score (0-100): Weighted aggregate of all sections
- SEO Score: On-page optimization, technical SEO
- Social Score: Presence and engagement across platforms
- Review Score: Rating average and review volume
- Comparison to Industry Average: Percentile ranking
🔀 Integration Points
- CRM Module - Business and person contact lookup
- Queue Manager - Background report generation
- Email Service (SendGrid) - Report delivery via email
- SMS Service (Twilio) - Report delivery via SMS
- File Storage (S3/Wasabi) - PDF storage and public URL generation
- OneBalance - Credit verification before report generation
⚠️ Important Notes
- 💰 Credit System: Each report consumes 1 InstaReport credit from OneBalance
- 🔄 Queue Processing: Reports generated asynchronously (5-15 minutes)
- 📧 Delivery Tracking: Email open and SMS delivery tracked per recipient
- 🎨 White-Label: Agency branding embedded in PDF watermark and footer
- 📊 Data Freshness: Report data cached for 24 hours to reduce API costs
- 🔒 Public URLs: Generated with secure tokens, expire after 90 days
- 📈 Industry Benchmarks: Updated monthly from aggregated data
📈 Performance Considerations
- Batch Processing: CSV uploads processed in background queue
- Rate Limiting: External API calls (GMB, Facebook) throttled to prevent bans
- Caching: Business data cached to avoid redundant API calls
- Retry Logic: Failed reports retried up to 3 times before marking as failed
- Storage Optimization: PDFs compressed before upload to S3
Last Updated: 2025-10-08
Module Path:internal/api/v1/instareports/
Primary Service:Services/instareport.js(1361 lines)