Skip to content
Telephony and messaging

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.

  1. PULSE asks Asterisk’s REST interface (ARI) to dial the lead into a dialplan context.
  2. That context runs AudioSocket() back to PULSE’s audio listener.
  3. PULSE transcribes the caller (Voxtral), answers with the sales agent, speaks the reply (piper), and streams it back.
VariableMeaning
AUDIOSOCKET_ADDRThe TCP listener Asterisk connects to
ASTERISK_ARI_URL, ASTERISK_ARI_USER, ASTERISK_ARI_PASSWORDARI access. Leave empty to keep outbound calls off.
ASTERISK_ENDPOINT_PATTERNThe dial string, with {number} substituted
ASTERISK_CONTEXT, ASTERISK_EXTENSIONThe dialplan target that runs AudioSocket()
ASTERISK_CALLER_IDOutbound 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.

Outbound cold calling is regulated. Consent, calling hours, do-not-call lists, and recording disclosure are the operator’s responsibility.

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_ID picks 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.
VariableMeaning
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKENThe Twilio account
TWILIO_WHATSAPP_FROM, TWILIO_FROM_NUMBERThe WhatsApp sender and the SMS number
PULSE_WHATSAPP_USER_IDThe user whose HubSpot contacts form the allowlist