From 14fecbb3e1819104a1d4cb30ba45c8ffd2d688ed Mon Sep 17 00:00:00 2001 From: legop3 Date: Sun, 14 Jun 2026 02:36:51 -0400 Subject: [PATCH] auto answer --- README.md | 11 ++++++----- sipcord-bridge/src/transport/sip/mod.rs | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 126cbb5..cb53be4 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,9 @@ means `DISCORD_OUTBOUND_SIP_HOST=192.168.0.25`. Discord-originated calls dial the requested extension directly by default. The bridge also attaches common auto-answer headers (`Call-Info: -;answer-after=0` and `Alert-Info: Ring Answer`) to Discord-originated -outbound calls so auto-answer phones can behave more like FreePBX intercom -targets. +;answer-after=0` and `Alert-Info: ;info=Ring Answer`) +to Discord-originated outbound calls, and appends `intercom=true` to the SIP +URI, so auto-answer phones can behave more like FreePBX intercom targets. Create a `docker-compose.yml`: @@ -215,8 +215,9 @@ Behavior: - The bridge dials the requested extension through the configured PBX target. - It dials the requested extension directly, for example `sip:1101@192.168.0.25:5060;transport=udp`. -- Discord-originated outbound calls also include common auto-answer headers so - phones configured for that behavior can answer immediately. +- Discord-originated outbound calls also include auto-answer headers and append + `intercom=true` to the SIP URI so phones configured for that behavior can + answer immediately. - When the SIP side answers, the phone call is connected to the Discord voice channel where the command was run. diff --git a/sipcord-bridge/src/transport/sip/mod.rs b/sipcord-bridge/src/transport/sip/mod.rs index 824cab5..4e48c0c 100644 --- a/sipcord-bridge/src/transport/sip/mod.rs +++ b/sipcord-bridge/src/transport/sip/mod.rs @@ -530,8 +530,20 @@ fn make_outbound_call( ) -> Result { unsafe { use self::ffi::pj_str::make_string_hdr; + let outbound_uri = if auto_answer { + if sip_uri.contains("intercom=true") { + sip_uri.to_string() + } else if let Some((base, params)) = sip_uri.split_once(';') { + format!("{base};intercom=true;{params}") + } else { + format!("{sip_uri};intercom=true") + } + } else { + sip_uri.to_string() + }; + let uri = - std::ffi::CString::new(sip_uri).map_err(|source| SipCallError::InvalidString { + std::ffi::CString::new(outbound_uri).map_err(|source| SipCallError::InvalidString { field: "sip_uri", source, })?; @@ -565,7 +577,8 @@ fn make_outbound_call( call_info as *mut ::pjsua::pj_list_type, ); - let alert_info = make_string_hdr(pool, c"Alert-Info", "Ring Answer") + let alert_info = + make_string_hdr(pool, c"Alert-Info", ";info=Ring Answer") .map_err(|_| SipCallError::MakeCall(-1))?; ::pjsua::pj_list_insert_before( &mut msg_data_ptr.hdr_list as *mut _ as *mut ::pjsua::pj_list_type,