fix(whatsapp-call): normalize request shape for Go media-server
CreateSessionRequest rejected every Rails call with HTTP 400 — the Go struct expects ice_servers[].urls as []string and account_id as string, but Rails was sending urls as a single string and account_id as an integer. - MediaServerClient#create_session now wraps scalar `urls` in an array and coerces account_id to a string before posting. Defensive normalization lives in the client so existing Call rows (whose meta was persisted in the old shape) keep working without a backfill. - Default ICE server literals in IncomingCallService#default_ice_servers and WhatsappCallsController#create_outbound_call_via_media_server updated to the correct `urls: [..]` shape going forward. Verified end-to-end via rails runner against a locally running media-server: create_session → generate_agent_offer → terminate all return 2xx for both incoming (with Meta SDP offer) and outgoing (server generates the offer for Meta) directions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
b7d8fcc156
commit
a31c91d371
@@ -201,7 +201,7 @@ class Api::V1::Accounts::WhatsappCallsController < Api::V1::Accounts::BaseContro
|
||||
call_id: "pending_#{SecureRandom.hex(8)}",
|
||||
direction: 'outgoing',
|
||||
sdp_offer: nil,
|
||||
ice_servers: [{ urls: 'stun:stun.l.google.com:19302' }],
|
||||
ice_servers: [{ urls: ['stun:stun.l.google.com:19302'] }],
|
||||
account_id: current_account.id
|
||||
)
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ class Whatsapp::IncomingCallService
|
||||
end
|
||||
|
||||
def default_ice_servers
|
||||
[{ urls: 'stun:stun.l.google.com:19302' }]
|
||||
[{ urls: ['stun:stun.l.google.com:19302'] }]
|
||||
end
|
||||
|
||||
def fix_sdp_setup(sdp)
|
||||
|
||||
@@ -5,7 +5,8 @@ class Whatsapp::MediaServerClient
|
||||
TIMEOUT = 10
|
||||
|
||||
def create_session(call_id:, direction:, sdp_offer:, ice_servers:, account_id: nil)
|
||||
body = { call_id: call_id, direction: direction, meta_sdp_offer: sdp_offer, ice_servers: ice_servers, account_id: account_id }.compact
|
||||
body = { call_id: call_id, direction: direction, meta_sdp_offer: sdp_offer,
|
||||
ice_servers: normalize_ice_servers(ice_servers), account_id: account_id&.to_s }.compact
|
||||
post('/sessions', body)
|
||||
end
|
||||
|
||||
@@ -110,4 +111,17 @@ class Whatsapp::MediaServerClient
|
||||
'Authorization' => "Bearer #{auth_token}"
|
||||
}
|
||||
end
|
||||
|
||||
# Go media server expects `urls` to always be an array of strings.
|
||||
# Accept legacy data that may have `urls` as a single string.
|
||||
def normalize_ice_servers(servers)
|
||||
return [] if servers.blank?
|
||||
|
||||
Array(servers).map do |srv|
|
||||
s = srv.respond_to?(:to_h) ? srv.to_h.transform_keys(&:to_s) : srv.stringify_keys
|
||||
urls = s['urls']
|
||||
s['urls'] = urls.is_a?(Array) ? urls : Array(urls).compact
|
||||
s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user