limited-planet-15554
02/20/2026, 3:05 AMtall-airline-16756
02/20/2026, 3:05 AMtall-airline-16756
02/20/2026, 3:05 AMcreate_sip_participant
◦ 목적: 새 통화를 걸어 새로운 SIP 참가자를 LiveKit 룸에 추가합니다.
◦ 동작: 지정한 전화번호로 아웃바운드 콜을 시작하고, 상대가 응답하면 그 참가자가 룸에 참여합니다.
◦ 주요 파라미터: sip_trunk_id, sip_call_to, room_name, participant_identity, 등.
◦ 사용 예: 룸안에 아직 없던 외부 번호를 호출해서 새 참가자를 만들고 싶을 때 사용합니다.
• transfer_sip_participant
◦ 목적: 이미 룸에 있거나 통화 중인 기존 SIP 참가자를 다른 번호(또는 SIP 대상으로)로 전송(transfer)합니다.
◦ 동작: SIP REFER 같은 메커니즘으로 현재 세션을 다른 대상에게 이전하고, 기존 세션은 종료됩니다.
◦ 주요 파라미터: room_name, participant_identity, transfer_to.
◦ 사용 예: 통화 중인 상담원을 외부 번호로 콜백/콜전달 하거나, 현재 통화를 다른 라인으로 연결하고 싶을 때 사용합니다.
◦ 참고: SIP 트렁크 공급자에서 SIP REFER 전송을 허용해야 제대로 동작합니다.
핵심 차이 요약:
• create_sip_participant = 새 통화를 "생성"해서 룸에 참가자 추가
• transfer_sip_participant = 이미 있는 통화를 "전송(이동)"해서 다른 번호로 연결
더 도와드릴 부분이 있을까요? 예를 들어 사용하려는 시나리오(아웃바운드 콜, 통화 중 전달 등)를 알려주시면 어떤 API를 써야 할지 구체적으로 추천드릴게요.
Sources: Agents telephony integration | LiveKit Documentation | SIP Lifecycle Management Agent | LiveKit Documentationlimited-planet-15554
02/20/2026, 3:09 AMtransfer_sip_participant 으로는 상대방과 전화가 연결되었는지까지의 여부를 알수는 없는데, create_sip_participant 으로는 가능한것 같아.
그러면 create_sip_participant 으로 전화를 걸고 연결에 성공한후 세션을 끝내버리면 두명에게 연결된 전화가 끊어질까?tall-airline-16756
02/20/2026, 3:09 AMlimited-planet-15554
02/20/2026, 3:10 AMtransfer_sip_participant 으로 성공 여부를 별도로 확인하는 로직을 추가하는 방법이 있어?tall-airline-16756
02/20/2026, 3:11 AMsip.callStatus 모니터링 (권장)
◦ sip.callStatus 값이 `active`로 바뀌면 전달이 성공(수신자가 통화를 받음)한 것으로 판단할 수 있습니다.
◦ 값 예시: dialing, ringing, active, hangup, automation 등.
◦ 구현 포인트: transfer_sip_participant 호출 후 해당 참가자에 대한 participant_attributes_changed 이벤트를 수신하여 상태 변화를 확인하세요.
1. participant_disconnected 이벤트로 원래 참가자 종료 확인
◦ 전달이 성공하면 원래 SIP 참가자(룸에 있던 쪽)가 룸에서 제거됩니다. `participant_disconnected`가 발생하면 전달이 완료됐을 가능성이 높습니다.
◦ 주의: 단순한 종료(hangup)와 구분해야 하므로 `sip.callStatus`와 함께 보면 더 정확합니다.
1. participant_connected 이벤트로 전송 대상의 새 참가자 연결 확인
◦ 전달 대상이 같은 룸에 새 SIP 참가자로 들어오는 구성이라면 participant_connected 이벤트로 수신 여부를 확인할 수 있습니다.
1. API 호출 예외 처리로 초기 요청 실패 감지
◦ transfer_sip_participant 호출 자체가 실패하면 예외가 발생하므로, 이 경우는 즉시 전달 시도 자체가 실패한 것으로 처리합니다. 다만 호출 성공은 전달 시도만 의미하며 실제 연결 성공은 위 이벤트로 확인해야 합니다.
추가 고려사항 및 구현 팁:
• SIP 트렁크 설정: SIP REFER(transfer) 기능이 트렁크 쪽에서 활성화되어 있어야 합니다. 트렁크 공급자에서 전송 허용 설정이 필요합니다(예: Twilio의 PSTN Transfer 활성화 등).
• 타이밍: 전달 과정에서 상태 변화가 순차적으로(예: dialing → ringing → active → hangup) 발생할 수 있으니, 상태 전환 로직을 꼼꼼히 처리하세요.
• 안정성: 이벤트를 기반으로 판단하므로, 상태 변화가 오지 않거나 타임아웃이 발생하는 경우(예: 전달 대기 시간이 지나면 실패로 처리)에 대한 타임아웃/재시도 정책을 두는 것이 좋습니다.
• 알림/연동: 성공/실패 상태를 외부 시스템(Webhook, DB 업데이트, 알림 등)에 전파하면 운영상 유용합니다.
간단한 예시(파이썬, 이벤트 핸들러 아이디어):
@ctx.room.on("participant_attributes_changed")
def on_attributes_changed(changed_attributes, participant):
if participant.kind != rtc.ParticipantKind.PARTICIPANT_KIND_SIP:
return
if 'sip.callStatus' in changed_attributes:
status = changed_attributes['sip.callStatus']
if status == 'active':
# 전달 성공 처리
elif status == 'hangup':
# 전달 실패/종료 처리
원하시면 제가 도와드릴 수 있는 추가 항목:
• 현재 사용 중인 SIP 트렁크(예: Twilio 등)와 설정을 알려주시면 REFER 활성화 여부 및 추가 설정 팁을 드릴게요.
• sip.callStatus 기반으로 구체적 타임아웃/재시도 로직 예시 코드를 원하시면 제공해 드릴게요.
어떤 방식으로 구현할 계획이신가요? (예: 이벤트 기반 알림 전송, DB에 상태 기록, 사용자에게 실시간 피드백 등) 그러면 더 구체적으로 맞춰서 도와드릴게요.
Sources: Agents telephony integration | LiveKit Documentation | SIP Lifecycle Management Agent | LiveKit Documentationlimited-planet-15554
02/20/2026, 3:16 AMtransfer_sip_participant 로 전화를 걸면, 즉 API가 성공하면 상대방과의 통화가 실제로 연결되기 전에 "participant_disconnected" 이벤트가 발생되고 session이 끝나버리는데, participant_attributes_changed 이벤트로 상대방과 실제 통화가 연결되었는지 알수가 있어?tall-airline-16756
02/20/2026, 3:16 AMsip.callStatus 변경을 모니터링하면 실제로 전달 대상이 전화를 받아 통화가 연결된(active) 시점을 감지할 수 있습니다.
• 다만 transfer_sip_participant 호출 직후에 원래 참가자가 룸에서 끊어지는(participant_disconnected) 것은 정상일 수 있으며, 이것만으로는 전달 성공(상대가 받음)을 보장하지 않습니다. `sip.callStatus == 'active'`를 확인해야 실제 연결로 판단할 수 있습니다.
이유와 동작 흐름
• `transfer_sip_participant`는 LiveKit에서 기존 참가자 세션을 외부로 REFER(전송)하도록 요청합니다. API 호출 성공은 “전송 요청을 보냈다”는 의미이지, 상대가 수신하여 통화가 성사되었다는 보장은 아닙니다.
• 전송을 시작하면 원래 룸에 있던 참가자는 즉시 제거될 수 있습니다(예: 룸의 세션 종결이나 참가기지 제거). 따라서 `participant_disconnected`가 먼저 오더라도 전달 대상의 연결 성공 여부는 별도로 확인해야 합니다.
• 전달 대상의 실제 연결 상태는 SIP 관련 참가자 속성(sip.callStatus)로 보고됩니다. 값이 `active`가 되면 상대가 통화를 수락하여 연결된 것입니다.
구현 권장 방법(실무 팁)
1. transfer 요청은 try/except로 감싸 초기 실패를 즉시 감지
2. transfer 후에는 다음 이벤트들을 조합해서 판단
◦ `participant_disconnected`: 원래 참가자(전달 대상이 아닌 쪽)가 룸에서 나갔음을 알림 — 전달 진행의 한 부분
◦ `participant_attributes_changed`에서 sip.callStatus 검사:
▪︎ active → 전달 대상이 실제로 받았음(성공)
▪︎ `ringing`/`dialing` → 아직 응답 전
▪︎ hangup → 전달 실패 또는 수신자가 거부했음
◦ (가능하면) `participant_connected`: 전달 대상이 새 참가자로 들어오는 경우 이를 통해 추가 확인 가능
1. 타임아웃/재시도 정책: 만약 `sip.callStatus`가 일정 시간 내에 `active`로 바뀌지 않으면 실패로 처리하고 재시도하거나 로그/알림을 남기세요.
2. SIP 트렁크 설정 확인: 트렁크 제공자가 REFER를 제대로 처리하도록 설정되어 있어야 sip.callStatus 업데이트가 정확하게 들어옵니다.
간단한 이벤트 핸들러 예시(Python 스타일)
@ctx.room.on("participant_attributes_changed")
def on_attributes_changed(changed_attributes, participant):
if participant.kind != rtc.ParticipantKind.PARTICIPANT_KIND_SIP:
return
if 'sip.callStatus' in changed_attributes:
status = changed_attributes['sip.callStatus']
if status == 'active':
# 전달 성공: 상대방과 실제 연결됨
elif status == 'hangup':
# 전달 실패 또는 거부
주의사항
• 일부 SIP 공급자나 설정에서는 REFER로 전송 후 상태 업데이트가 제대로 전달되지 않을 수 있습니다. 이 경우에는 트렁크 공급자 설정(예: Twilio의 PSTN Transfer 등)을 확인해야 합니다.
• 이벤트 순서가 환경에 따라 달라질 수 있으므로(예: `participant_disconnected`가 먼저), 판단 로직은 복수의 신호(속성 변화 + 연결/종료 이벤트 + 타임아웃)를 조합하도록 설계하세요.
원하시면:
• 현재 사용 중인 SIP 트렁크(예: Twilio 등)와 transfer 시 발생하는 실제 이벤트 로그(타임스탬프 포함)를 알려주시면, 어떤 이벤트 순서가 발생하는지 보고 더 구체적으로 실패/성공 판별 로직을 함께 설계해 드릴게요.limited-planet-15554
02/20/2026, 3:22 AMtall-airline-16756
02/20/2026, 3:22 AMtransfer_sip_participant 호출 후 곧바로 `sip.callStatus == 'hangup'`이 나오는 상황에 대해 답드릴게요.
간단 결론
• 불가능하다고 단정할 수는 없습니다. 그러나 "즉시 'hangup'이 나오는" 현상은 일반적으로 SIP 트렁크나 전달(REFER) 처리 흐름에서 상태 업데이트가 제대로 오지 않거나, 전달 과정에서 수신 쪽에서 즉시 끊음(또는 거부)이 발생했음을 뜻합니다. 따라서 원천 문제를 확인해야 합니다.
가능한 원인과 확인/해결 방법
1. SIP 트렁크가 REFER(transfer) 상태 업데이트를 전달하지 않음
◦ 일부 제공자는 REFER 이후의 콜 진행상태(ringing/active)를 LiveKit으로 전달하지 않습니다. 이 경우 LiveKit은 전달 시도 후 곧바로 기존 세션을 정리하고 `hangup`을 보낼 수 있습니다.
◦ 조치: 트렁크 공급자(예: Twilio 등)의 "PSTN Transfer" 같은 설정이 켜져 있는지 확인하세요. 공급자 로그에서 REFER 이후 상태 이벤트가 발생하는지 확인해 주세요.
1. 전달 대상(수신자)이 즉시 거부하거나 회선 문제로 빠르게 종료됨
◦ 전송 대상이 바로 거부(버튼 눌러 끊음)하거나 벨소리가 울리지 못하고 종료되는 경우 `hangup`이 빠르게 옵니다.
◦ 조치: 전달 대상 번호로 직접 수동 호출 테스트를 해보거나, 공급자 로그에서 해당 콜의 SIP 흐름(100 Trying, 180 Ringing, 200 OK, BYE 등)을 확인하세요.
1. LiveKit 이벤트/속성 업데이트 지연 또는 누락
◦ LiveKit은 SIP 상태를 participant attributes로 노출하지만, 일부 이벤트가 누락되거나 순서가 섞일 수 있습니다.
◦ 조치: 전달 시 타임스탬프가 있는 로그를 남겨 transfer 요청, participant_disconnected, `participant_attributes_changed`의 발생 순서를 비교하세요.
1. REFER 타입(콜드/웜)과 구현 차이
◦ 어떤 트렁크는 콜드(콜을 끊고 전송) 스타일로 처리해서 기존 참가자 종료가 빠르게 발생할 수 있습니다.
◦ 조치: 트렁크 문서에서 REFER 동작(콜 유지 vs 즉시 종료)을 확인하거나, 다른 REFER 모드가 가능한지 확인하세요.
권장 진단 절차 (우선순위)
1. transfer 요청 직후의 LiveKit 로그(타임스탬프 포함)와 SIP 트렁크 로그를 확보해 비교하세요.
2. 트렁크 공급자 콘솔에서 해당 콜의 SIP 메시지 흐름을 확인(100/180/200/BYE 등).
3. 트렁크에서 REFER 후 상태 이벤트(180/200)가 LiveKit으로 전송되는지 확인.
4. 단순 재현: 동일 번호로 일반 아웃바운드(create_sip_participant) 호출했을 때의 SIP 흐름과 비교해 차이를 보세요.
5. 임시 대안: 전달 성공 여부를 보장하려면, 전송 대신 먼저 `create_sip_participant`로 대상에 전화를 걸어 `wait_until_answered=True`로 확인한 뒤(상대 연결 확인) 룸 내부 로직으로 브리지/연결을 전환하는 패턴을 고려해보세요.
제가 도와드릴 수 있는 것
• 현재 사용 중인 SIP 트렁크 공급자(예: Twilio 등)와, transfer 시의 LiveKit 로그 또는 트렁크의 SIP 로그 일부(타임스탬프, 상태 코드)를 공유해 주시면, 발생 원인을 함께 분석해 드릴게요.
• 또는 create_sip_participant 기반의 우회 패턴(먼저 통화 연결 확인 후 룸으로 합류) 예시 코드를 원하시면 제공해 드리겠습니다.
원하시면 지금 가지고 계신 로그의 핵심 타임스탬프/상태 라인(개인 정보/전화번호는 마스킹)만 붙여 보내주세요. 함께 살펴보고 원인 좁혀드릴게요.