Class: Webhooks::V1::SwitchvoxController

Inherits:
BaseController
  • Object
show all
Defined in:
app/controllers/webhooks/v1/switchvox_controller.rb

Overview

Webhook endpoint for Switchvox PBX Event Triggers.
https://sangomakb.atlassian.net/wiki/spaces/Switchvox/pages/391053382/Event+Triggers

Supported events:

  • On New Voicemail: Notifies when a voicemail is left
  • On Incoming Call: Notifies when a call arrives (future: screen pop)
  • On Call Hangup: Notifies when a call ends (future: analytics)

Switchvox sends form-encoded POST with variables like:
VM_MAILBOX=801
VM_DUR=45
VM_MSGNUM=123
VM_DATE=2025-01-21 14:30:00
CALLER_ID_NUMBER=+18005551234
CALLER_ID_NAME=John Doe
EVENT_TYPE=new_voicemail

Authentication:
Option 1: Shared secret token in URL query param
Option 2: IP whitelist (Switchvox server IP)

Test with:
curl -X POST "https://api.warmlyyours.me:3000/webhooks/v1/switchvox?token=YOUR_TOKEN"
-d "EVENT_TYPE=new_voicemail&VM_MAILBOX=801&VM_DUR=30&CALLER_ID_NUMBER=+18005551234"

Instance Method Summary collapse

Instance Method Details

#createObject

POST /webhooks/v1/switchvox



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/controllers/webhooks/v1/switchvox_controller.rb', line 32

def create
  # 1. VERIFY authentication (token or IP whitelist)
  unless valid_request?
    Rails.logger.warn "[Webhooks::V1::Switchvox] Unauthorized request from #{request.remote_ip}"
    return head :unauthorized
  end

  # 2. Determine event type
  event_type = determine_event_type
  Rails.logger.info "[Webhooks::V1::Switchvox] Received #{event_type} event from #{request.remote_ip}"

  # 3. INGEST to WebhookLog
  webhook_log = WebhookLog.ingest!(
    provider: 'switchvox',
    category: event_type,
    external_id: build_external_id(event_type),
    data: sanitized_params
  )

  # 4. ENQUEUE background job
  WebhookProcessorWorker.perform_async(webhook_log.id)

  Rails.logger.info "[Webhooks::V1::Switchvox] Created WebhookLog #{webhook_log.id}"

  # 5. RESPOND immediately
  # Switchvox Event Triggers parse the response with process_xml_response,
  # so we must return valid XML — JSON causes "Fatal Error XMLin" on the PBX.
  render xml: "<response><status>ok</status></response>"
end