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 changes
  • POST /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