gigafibre-fsm/apps/ops/src/api/sms.js
louispaulb 4693bcf60c feat: telephony UI, performance indexes, Twilio softphone, lazy-load invoices
- Add PostgreSQL performance indexes migration script (1000x faster queries)
  Sales Invoice: 1,248ms → 28ms, Payment Entry: 443ms → 31ms
  Indexes on customer/party columns for all major tables
- Disable 3CX poller (PBX_ENABLED flag, using Twilio instead)
- Add TelephonyPage: full CRUD UI for Routr/Fonoster resources
  (trunks, agents, credentials, numbers, domains, peers)
- Add PhoneModal + usePhone composable (Twilio WebRTC softphone)
- Lazy-load invoices/payments (initial 5, expand on demand)
- Parallelize all API calls in ClientDetailPage (no waterfall)
- Add targo-hub service (SSE relay, SMS, voice, telephony API)
- Customer portal: invoice detail, ticket detail, messages pages
- Remove dead Ollama nginx upstream

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 13:59:59 -04:00

33 lines
1.3 KiB
JavaScript

/**
* Send SMS via n8n webhook → Twilio.
* n8n handles Twilio auth + logs to ERPNext automatically.
*
* @param {string} phone - Phone number (e.g. +15145551234)
* @param {string} message - SMS body
* @param {string} customer - Customer ID (e.g. C-LPB4 or C-10000000034941) — logged as Communication in ERPNext
* @param {object} [opts] - Extra options
* @param {string} [opts.reference_doctype] - Link to specific doctype (default: Customer)
* @param {string} [opts.reference_name] - Link to specific record
* @returns {Promise<{ok: boolean, message: string, sid?: string}>}
*/
const N8N_WEBHOOK_URL = 'https://n8n.gigafibre.ca/webhook/sms-send'
export async function sendTestSms (phone, message, customer, opts = {}) {
const payload = { phone, message, customer }
if (opts.reference_doctype) payload.reference_doctype = opts.reference_doctype
if (opts.reference_name) payload.reference_name = opts.reference_name
const res = await fetch(N8N_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
if (!res.ok) {
const err = await res.text().catch(() => 'Unknown error')
throw new Error('SMS failed (' + res.status + '): ' + err)
}
const data = await res.json()
if (data.ok === false) throw new Error(data.message || 'SMS send error')
return data
}