Bridge API
The Bridge API is the central orchestration layer connecting EspoCRM to all external services.
Overview
Directory Structure
bridge/
├── server.js # Express app entry point
├── package.json # Dependencies
├── Dockerfile # Container definition
│
├── config/
│ └── platforms.js # Platform configuration
│
├── helpers/
│ ├── ayrshare/ # Social media integration
│ │ ├── analytics.js # Fetch analytics
│ │ ├── comments.js # Comment management
│ │ ├── history.js # Post history
│ │ ├── schedule.js # Schedule posts
│ │ └── sync.js # Sync state
│ │
│ ├── boxcast/ # Boxcast integration
│ │ └── sync.js # Sync broadcasts
│ │
│ ├── bunny/ # CDN integration
│ │ ├── storage.js # Storage operations
│ │ └── upload.js # Upload handling
│ │
│ ├── captions/ # Caption generation
│ │ ├── burnCaptions.js
│ │ ├── captionPipeline.js
│ │ └── generateASS.js
│ │
│ ├── claude/ # AI analysis
│ │ ├── analyze-clips.js
│ │ ├── prompts.js
│ │ └── transcript-analysis.js
│ │
│ ├── cron/ # Scheduled jobs
│ │ └── collectAnalytics.js
│ │
│ ├── deepgram/ # Transcription
│ │ └── transcribe.js
│ │
│ ├── assemblyai/ # Transcription (alt)
│ │ └── transcribe.js
│ │
│ ├── espocrm/ # CRM integration
│ │ └── client.js # API client
│ │
│ ├── ffmpeg/ # Video processing
│ │ ├── compile.js
│ │ ├── extract.js
│ │ ├── filmstrip.js
│ │ └── waveform.js
│ │
│ ├── n8n/ # Workflow automation
│ │ └── triggerWorkflow.js
│ │
│ ├── postgres/ # Analytics database
│ │ ├── client.js # Connection pool
│ │ └── queries.js # Query functions
│ │
│ ├── stockmedia/ # Stock media APIs
│ │ ├── runway.js
│ │ ├── shutterstock.js
│ │ └── storyblocks.js
│ │
│ └── xserver/ # Platform automation
│ └── client.js # X server client
│
└── routes/
├── index.js # Route registration
├── analytics.js # Analytics endpoints
├── ayrshare.js # Ayrshare proxy
├── boxcast.js # Boxcast operations
├── broll.js # B-roll management
├── cdn.js # CDN operations
├── clips.js # Clip management
├── comments.js # Comment handling
├── webhooks.js # EspoCRM webhooks
└── xserver.js # X server proxyAPI Endpoints
Health Check
http
GET /healthResponse:
json
{
"ok": true,
"service": "mediamagic-bridge",
"timestamp": "2026-02-05T12:00:00.000Z"
}Webhooks
Receives events from EspoCRM entity changes:
| Endpoint | Trigger Event |
|---|---|
POST /webhooks/guest-created | GuestBooking created |
POST /webhooks/guest-updated | GuestBooking updated |
POST /webhooks/content-created | ContentProduction created |
POST /webhooks/content-updated | ContentProduction updated |
POST /webhooks/platform-created | PlatformPublish created |
POST /webhooks/platform-updated | PlatformPublish updated |
POST /webhooks/clip-created | Clip created |
POST /webhooks/clip-updated | Clip updated |
POST /webhooks/social-created | SocialPost created |
POST /webhooks/social-updated | SocialPost updated |
POST /webhooks/social-deleted | SocialPost deleted |
Ayrshare Proxy
| Method | Endpoint | Description |
|---|---|---|
POST | /ayrshare/schedule | Schedule a social post |
POST | /ayrshare/delete | Delete a scheduled post |
GET | /ayrshare/history | Get post history |
GET | /ayrshare/analytics | Get post analytics |
Analytics
| Method | Endpoint | Description |
|---|---|---|
GET | /analytics/social-metrics | Query social metrics |
GET | /analytics/followers | Get follower trends |
GET | /analytics/top-posts | Get top performing posts |
POST | /analytics/collect | Trigger analytics collection |
POST | /analytics/content-ingest | Ingest content metrics |
GET | /analytics/content-metrics | Query content metrics |
Boxcast
| Method | Endpoint | Description |
|---|---|---|
POST | /boxcast/create-broadcast | Create a broadcast |
POST | /boxcast/delete-broadcast | Delete a broadcast |
X Server Proxy
| Method | Endpoint | Description |
|---|---|---|
POST | /x/publish | Forward to x server |
POST | /x/ayrshare-create | Create via x server |
POST | /x/ayrshare-delete | Delete via x server |
GET | /x/status | Check x server status |
Platform Routes Configuration
Located in routes/webhooks.js:
javascript
const PLATFORM_ROUTES = {
'Rumble': {
livestream: '/rumble-create',
upload: '/rumble-episode'
},
'YouTube': {
livestream: '/youtube-create',
upload: null
},
'Boxcast': {
livestream: '/boxcast-livestream',
upload: '/boxcast-media-upload'
},
'Brighteon': {
livestream: '/brighteon-create',
upload: '/brighteon-upload'
},
'Odysee': {
livestream: '/odysee-create',
upload: '/odysee-upload'
},
// ... more platforms
};Cron Jobs
Analytics Collection
Runs every 6 hours to collect metrics from Ayrshare:
Environment Variables
The Bridge requires these environment variables:
env
# EspoCRM
ESPOCRM_SITE_URL=http://espocrm
ESPOCRM_API_KEY=your_api_key
# PostgreSQL
POSTGRES_HOST=postgres
POSTGRES_PASSWORD=your_password
# External Services
AYRSHARE_API_KEY=your_ayrshare_key
X_SERVER_URL=http://your-x-server:3001
N8N_WEBHOOK_BASE=https://your-n8n.com
# AI & Media
ANTHROPIC_API_KEY=your_claude_key
DEEPGRAM_API_KEY=your_deepgram_key
BUNNY_STORAGE_API_KEY=your_bunny_keyError Handling
The Bridge handles errors gracefully and updates EspoCRM with error details:
javascript
try {
const result = await xServerClient.publish(payload);
await espoClient.update('PlatformPublish', id, {
status: 'Published',
platformUrl: result.url,
platformId: result.id
});
} catch (error) {
await espoClient.update('PlatformPublish', id, {
status: 'Failed',
apiResponse: JSON.stringify(error.message)
});
}Extending the Bridge
Adding a New Route
- Create route file in
routes/:
javascript
// routes/myfeature.js
import express from 'express';
const router = express.Router();
router.post('/action', async (req, res) => {
// Implementation
});
export default router;- Register in
routes/index.js:
javascript
import myfeature from './myfeature.js';
router.use('/myfeature', myfeature);Adding a New Helper
- Create helper in
helpers/myservice/:
javascript
// helpers/myservice/client.js
export async function doSomething(params) {
// Implementation
}- Import and use in routes:
javascript
import { doSomething } from '../helpers/myservice/client.js';