Telephony and messaging
PULSE has three voice and messaging paths. All three are off until you configure them.
Outbound calls to leads (Asterisk)
Leads → Call (LeadService.CallLead) places a real phone call through a
self-hosted Asterisk PBX. There is no per-minute calling SaaS.
- PULSE asks Asterisk’s REST interface (ARI) to dial the lead into a dialplan context.
- That context runs
AudioSocket()back to PULSE’s audio listener. - PULSE transcribes the caller (Voxtral), answers with the sales agent, speaks the reply (piper), and streams it back.
| Variable | Meaning |
|---|---|
AUDIOSOCKET_ADDR | The TCP listener Asterisk connects to |
ASTERISK_ARI_URL, ASTERISK_ARI_USER, ASTERISK_ARI_PASSWORD | ARI access. Leave empty to keep outbound calls off. |
ASTERISK_ENDPOINT_PATTERN | The dial string, with {number} substituted |
ASTERISK_CONTEXT, ASTERISK_EXTENSION | The dialplan target that runs AudioSocket() |
ASTERISK_CALLER_ID | Outbound caller ID |
If ARI is configured and the audio listener cannot bind, the server refuses to start. Otherwise it would place calls it cannot carry: the lead would answer to silence. When ARI is not configured, a failed bind is only a warning.
Without ARI, CallLead returns outbound calling isn't configured — set up Asterisk and ..., naming the missing variables.
Browser voice calls
The app’s full-screen call view sends a WebRTC offer to /voice/webrtc/offer.
PULSE forwards it to the platform’s shared calling agent at CALLING_AGENT_URL,
which carries the audio. PULSE is only the authenticated signaling door.
When CALLING_AGENT_URL is unset, the offer is refused with HTTP 503 and
voice calling is not configured: CALLING_AGENT_URL is unset. PULSE’s own
local handler cannot decode audio, so it no longer pretends to connect.
PULSE_WEBRTC_SIGNALING_ONLY=true turns that local handler back on for
signaling tests only; the caller will not be heard.
Turn-based voice input (/voice/transcribe) needs only the Voxtral server
(VOXTRAL_REMOTE_URL). Both voice endpoints require a signed-in caller.
WhatsApp and SMS
PULSE accepts inbound WhatsApp and SMS messages from Twilio at
/twilio/message, and answers with its marketing personas: the same set it
offers over A2A.
- Every request must carry a valid Twilio signature (
TWILIO_AUTH_TOKEN). - Only senders who are contacts in PULSE’s HubSpot account may talk to it.
PULSE_WHATSAPP_USER_IDpicks whose HubSpot connection is used. The default is to deny. - The edge only generates text: analysis, content, strategy, research. It cannot create leads or campaigns or approve content. Those stay behind the signed-in gRPC API.
| Variable | Meaning |
|---|---|
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN | The Twilio account |
TWILIO_WHATSAPP_FROM, TWILIO_FROM_NUMBER | The WhatsApp sender and the SMS number |
PULSE_WHATSAPP_USER_ID | The user whose HubSpot contacts form the allowlist |