Addons
The Clientra CRM addon system allows extending core functionality with optional modules. Addons are installed as self-contained packages in the /public/addons/ directory and loaded dynamically after the main application initializes.
Addon Architecture
Directory Structure
addon.json Schema
{
"slug": "meta-ads",
"name": "Meta Ads Integration",
"version": "1.2.0",
"description": "Facebook and Instagram lead ads integration",
"author": "Clientra",
"requires": "1.0.0",
"permissions": ["admin"],
"sidebar": {
"label": "Meta Ads",
"icon": "📱",
"route": "meta-ads",
"section": "Integrations"
},
"database_tables": [
"meta_accounts",
"meta_form_mappings",
"meta_lead_queue",
"meta_settings",
"meta_webhook_logs"
]
}
Loading Mechanism
Addons are loaded after the main application initializes:
- On startup,
app.jscallsapi.listAddons()to get enabled addons - For each enabled addon, a
<script>tag is injected loading/addons/{slug}/addon.js - The addon's
addon.jsregisters itself with the app, adds sidebar links, and registers routes - Database tables are created/migrated on first activation via the Addons admin page
Meta Ads Integration
Slug: meta-ads | Page: MetaAds.js
Integrates with Facebook and Instagram Lead Ads to automatically import leads into the CRM. Uses the Meta Webhooks API to receive real-time lead notifications.
Features
- Multiple Meta ad account management
- Per-form field mapping (Meta lead fields → CRM lead fields)
- Real-time webhook listener for new leads
- Lead queue with manual or automatic processing
- Campaign attribution preserved on imported leads
- Webhook event log for debugging
- Per-account enable/disable toggle
- Lead source statistics by campaign and date
Setup Guide
Go to developers.facebook.com, create a new app of type "Business", and add the "Lead Ads Retrieval" product.
From your Meta App dashboard, copy the App ID and App Secret. Generate a Page Access Token for the Facebook Page connected to your lead ads.
Navigate to Meta Ads → Settings and enter your App ID, App Secret, and Page Access Token. Set the Webhook Verify Token to a secure random string.
Webhook URL: https://yourdomain.com/webhooks/meta-leads.php Verify Token: (your random string from Meta Ads settings)
In your Meta App, go to Webhooks, subscribe to leadgen events on your Page. Enter the Webhook URL and Verify Token from the previous step.
In Meta Ads → Form Mappings, map each Meta lead form's fields to the corresponding CRM lead fields (name, phone, email, etc.).
Lead Queue Processing
Incoming Meta leads are stored in the meta_lead_queue table. They can be processed:
- Manually: Review leads in the Meta Ads page and click "Process Queue"
- Automatically: Set up a cron job to call
?action=meta_process_queueperiodically
# Process Meta lead queue every 5 minutes via cron
*/5 * * * * curl -s -b "clientra_session=SESSION_TOKEN" \
"https://yourdomain.com/api.php?action=meta_process_queue" \
-X POST > /dev/null 2>&1
Wasabi Cloud Storage
Slug: wasabi-storage | Page: StorageManager.js
Replaces local file storage with Wasabi S3-compatible cloud storage. Provides a file management interface and migration tool for moving existing uploads to the cloud.
Features
- S3-compatible API (Wasabi, AWS S3, Cloudflare R2)
- Transparent file upload redirect (no code changes needed in pages)
- Browser-based file manager with folder view
- One-click migration from local storage to Wasabi
- Storage usage statistics
- Per-bucket access control
Setup Guide
Sign up at wasabi.com, create a storage bucket, and generate an Access Key and Secret Key with appropriate permissions.
In Settings → Storage, change "Storage Type" to wasabi and enter your credentials.
| Setting | Example |
|---|---|
| Storage Type | wasabi |
| Wasabi Bucket | clientra-uploads |
| Wasabi Region | us-east-1 |
| Access Key | your_access_key |
| Secret Key | your_secret_key |
| Endpoint | https://s3.wasabisys.com |
Use the "Test Connection" button in Settings to verify your credentials work. A successful test confirms the CRM can upload and retrieve files.
In the Storage Manager page, use the "Migrate to Wasabi" tool to upload all existing local files to your bucket. This preserves all file paths and updates database references.
API & Webhooks Addon
Slug: api-webhooks
Provides REST API access with API key authentication and outbound webhook subscriptions. Designed for third-party integrations.
Features
- API key management (create, revoke, usage limits)
- OAuth 2.0 client registration for trusted applications
- Rate limiting tiers (requests per minute)
- Outbound webhook subscriptions per event type
- API request logging with response codes
Rate Limiting Tiers
| Tier | Requests/min | Description |
|---|---|---|
| Free | 30 | Basic read access |
| Standard | 120 | Full CRUD access |
| Premium | 600 | High-volume integrations |
Webhook Events
| Event | Trigger |
|---|---|
lead.created | New lead added to CRM |
lead.updated | Lead status or details changed |
deal.won | Deal moved to Won stage |
deal.lost | Deal moved to Lost stage |
property.created | New property listed |
contact.created | New contact added |
Creating Custom Addons
You can create custom addons to extend Clientra CRM with your own features. Here's the minimal structure needed:
Minimum File Structure
addon.js Structure
// public/addons/my-addon/addon.js (function() { // 1. Define your page class class MyAddonPage { render() { return ` <div class="page"> <div class="page-header"> <div> <h1 class="page-title">My Addon</h1> </div> </div> <div class="card"> <p>My addon content here</p> </div> </div> `; } init() { // Called when the page is navigated to } } // 2. Register with the app if (window.app) { // Add sidebar link window.app.addSidebarLink({ label: 'My Addon', icon: '🔌', route: 'my-addon', section: 'Addons' }); // Register page route window.router.addRoute('my-addon', () => { const page = new MyAddonPage(); document.getElementById('app').innerHTML = page.render(); page.init(); }); } })();
Adding PHP API Endpoints
<?php // public/addons/my-addon/addon.php // Handles: /api.php?action=my_addon_action // api.php discovers and includes addon PHP files // Your action is dispatched from the main switch statement case 'my_addon_data': // Authenticate (always check session) if (!$_SESSION['user_id']) { http_response_code(401); exit(json_encode(['success' => false])); } // Query your addon's tables $stmt = $pdo->prepare("SELECT * FROM my_addon_data WHERE user_id = ?"); $stmt->execute([$_SESSION['user_id']]); echo json_encode([ 'success' => true, 'data' => $stmt->fetchAll() ]); break;
/public/addons/{slug}/, then go to the Addons page in Clientra CRM and click "Activate". The system will run any database migrations and enable the addon.