Monitor & Auto-Remediation System
This module provides real-time monitoring and automatic remediation for A2P SMS registrations.
Components
1. Status Checker (status-checker.ts)
Polls Twilio API for brand and campaign registration status.
import { checkBrandStatus, checkCampaignStatus } from './monitor';
const brandResult = await checkBrandStatus('BNxxxxx');
const campaignResult = await checkCampaignStatus('QExxxxx');
2. Webhook Handler (webhook-handler.ts)
Express router for receiving Twilio status callbacks.
import express from 'express';
import { webhookRouter } from './monitor';
const app = express();
app.use('/webhooks', webhookRouter);
Endpoints:
POST /webhooks/brand-status— Brand registration status changesPOST /webhooks/campaign-status— Campaign status changes
3. Polling Job (polling-job.ts)
BullMQ job that polls pending submissions every 30 minutes (fallback for webhooks).
import { startPollingJob, stopPollingJob } from './monitor';
// Start polling
await startPollingJob();
// Stop polling
await stopPollingJob();
4. Remediation Engine (remediation-engine.ts)
Automatically fixes common failure patterns.
Auto-fixed patterns:
- Business name mismatch (tries variations with Inc/LLC/Corp suffixes)
- Website not accessible (ensures https://, redeploys landing page)
- Insufficient opt-in description (adds TCPA-compliant language)
- Sample messages non-compliant (adds opt-out footer, removes prohibited content)
- Missing STOP/HELP keywords (adds standard keywords)
- Duplicate brand (reuses existing approved brand)
- Rate limited (exponential backoff)
import { remediateFailure } from './monitor';
await remediateFailure(submission, 'brand', 'business name mismatch');
5. Notifier (notifier.ts)
Sends status notifications via webhook and console.
import { sendNotification } from './monitor';
await sendNotification({
submissionId: 'abc123',
businessName: 'Example Corp',
status: 'brand_approved',
message: 'Brand registration approved!',
timestamp: new Date(),
}, 'https://your-webhook-url.com');
Environment Variables
# Twilio
TWILIO_ACCOUNT_SID=ACxxxxx
TWILIO_AUTH_TOKEN=xxxxx
# Redis (for BullMQ)
REDIS_HOST=localhost
REDIS_PORT=6379
# Notifications
NOTIFY_WEBHOOK_URL=https://your-webhook-url.com # Optional
Usage Example
import express from 'express';
import {
webhookRouter,
startPollingJob,
sendNotification
} from './monitor';
const app = express();
// Mount webhook routes
app.use(express.json());
app.use('/webhooks', webhookRouter);
// Start polling job
await startPollingJob();
// Server
app.listen(3000, () => {
console.log('Monitor system running on port 3000');
});
Integration Points
Database Queries (TODO)
The system expects these database functions to be implemented:
// Find submissions by status
await db.findSubmissions({ status: { $in: ['brand_pending', 'campaign_pending'] } });
// Find by Twilio SIDs
await db.findSubmissionByBrandSid(brandSid);
await db.findSubmissionByCampaignSid(campaignSid);
// Update submission
await db.updateSubmission(id, { status, failureReason, updatedAt });
Resubmission Workflow (TODO)
After remediation, trigger the appropriate workflow:
// Resubmit brand registration
await resubmitBrand(submissionId, modifiedInput);
// Resubmit campaign
await resubmitCampaign(submissionId, modifiedInput);
Notification Payloads
Webhook notifications follow this schema:
{
submissionId: string;
businessName: string;
status: SubmissionStatus;
message: string;
details?: string;
level: 'info' | 'success' | 'warning' | 'error';
timestamp: string; // ISO 8601
}
Logging
All components use pino for structured logging:
# View logs
pm2 logs a2p-monitor
# Filter by component
pm2 logs a2p-monitor | grep status-checker
pm2 logs a2p-monitor | grep remediation-engine
Testing
# Test webhook endpoint
curl -X POST http://localhost:3000/webhooks/brand-status \
-H "Content-Type: application/json" \
-H "X-Twilio-Signature: <signature>" \
-d '{
"BrandRegistrationSid": "BNxxxxx",
"Status": "APPROVED"
}'
# Test status checker
npm run test:status-checker
# Test remediation patterns
npm run test:remediation
Error Handling
- Max attempts exceeded → Marks submission as
manual_review - Unknown failure pattern → Marks submission as
manual_review - Remediation fails → Marks submission as
manual_review - Webhook signature invalid → Returns 403
- Rate limited → Applies exponential backoff
Monitoring
Track these metrics:
- Total submissions in each status
- Remediation success rate (by pattern)
- Average time to approval (brand, campaign)
- Manual review rate
- Webhook delivery success rate
Future Enhancements
- Database integration (MongoDB/PostgreSQL)
- Resubmission workflow integration
- Landing page deployment verification
- Machine learning for failure pattern detection
- Slack/Discord notification channels
- Metrics dashboard
- A/B testing for remediation strategies