통화 기능
걸려온 통화의 발신자 번호로 이어 걸기 (CallToken)
걸려온 통화가 이어지는 동안, 그 통화의 발신자 번호가 상대에게 표시되는 통화를 겁니다. Twilio callToken 과 같은 방식입니다.
걸려온 통화의 발신자 번호로 이어 걸기 (CallToken)
걸려온 통화가 이어지는 동안, 그 통화의 발신자 번호가 상대에게 표시되는 통화를 겁니다. Twilio callToken 과 같은 방식입니다.
걸려온 전화를 넘기는 착신전환입니다. 받는 쪽에는 걸려온 통화의 발신자 번호가 표시되지만, 발신번호를 그 번호로 바꿔 새로 거는 것이 아닙니다. 통신사에는 그 전화를 받은 번호(예: 070 번호)에서 전환된 통화로 전달되므로, 받는 장비에 따라 그 번호가 표시될 수도 있습니다.
1. 걸려온 통화에서 CallToken 받기
걸려온 통화의 웹훅 요청에 CallToken 이 실립니다.
CallId=CA7f3a9c0e21
From=01012345678
To=07012340001
Direction=inbound
CallToken=ctk_Q2FsbFRva2VuRXhhbXBsZTAxMjM0NTY32. 이어서 통화 걸기
CallToken 을 넣고, From 에는 걸려온 통화의 발신자 번호를 넣습니다. 이 값은 받는 쪽에 어떤 번호를 표시할지를 정합니다.
curl -X POST https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/calls \
-H "Authorization: Bearer $CLAWOPS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"To": "01098765432",
"From": "01012345678",
"CallToken": "ctk_Q2FsbFRva2VuRXhhbXBsZTAxMjM0NTY3",
"Url": "https://my-app.com/agent-leg"
}'이어 건 통화는 한국AI통신 기록·과금에서 걸려온 통화와 연결되지 않은 별개의 통화입니다. 두 통화를 잇는 것은 직접 구성합니다. 예를 들어 두 통화를 각각 <Connect><Stream> 으로 같은 서버에 붙여 오디오를 주고받습니다.
3. 이어 건 통화 끊기
상대가 거절했거나 더 필요 없으면 이어 건 통화만 끊습니다. 벨이 울리는 중이면 연결 전에 취소됩니다. 걸려온 통화는 그대로 유지됩니다.
curl -X POST https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/calls/CA9b10d44d2 \
-H "Authorization: Bearer $CLAWOPS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "Status": "completed" }'SIP 트렁크에서 쓰기
착신을 SIP 로 직접 받는 번호는 웹훅 대신 착신 INVITE 의 X-ClawOps-CallToken 헤더로 CallToken 을 받습니다. Twilio X-Twilio-CallToken 과 같은 방식입니다.
INVITE sip:07012340001@sbc.example.com SIP/2.0
From: <sip:01012345678@sip.claw-ops.com>;tag=...
X-ClawOps-CallToken: ctk_Q2FsbFRva2VuRXhhbXBsZTAxMjM0NTY3이어 걸 때는 SIP 트렁크 발신 INVITE 의 From 에 걸려온 통화의 발신자 번호를 넣고, 받은 헤더를 그대로 실어 보냅니다.
INVITE sip:01098765432@ac1a2b3c4d.sip.claw-ops.com SIP/2.0
From: <sip:01012345678@ac1a2b3c4d.sip.claw-ops.com>;tag=...
X-ClawOps-CallToken: ctk_Q2FsbFRva2VuRXhhbXBsZTAxMjM0NTY3LiveKit 을 쓰면 인바운드 트렁크의 headers_to_attributes 로 헤더를 참가자 속성으로 받고, CreateSIPParticipant 의 headers 로 돌려보냅니다. 속성은 벨이 울리는 단계부터 읽을 수 있습니다.
from livekit import api
# 1. 인바운드 트렁크 — X-ClawOps-CallToken 을 참가자 속성 clawops.callToken 으로
await lk.sip.create_inbound_trunk(api.CreateSIPInboundTrunkRequest(
trunk=api.SIPInboundTrunkInfo(
name="clawops-inbound",
numbers=["07012340001"],
headers_to_attributes={"X-ClawOps-CallToken": "clawops.callToken"},
),
))
# 2. 걸려온 통화의 참가자에서 토큰과 발신자 번호를 읽어 상담원에게 이어 걸기
caller = ... # 방에 들어온 SIP 참가자
await lk.sip.create_sip_participant(api.CreateSIPParticipantRequest(
sip_trunk_id=OUTBOUND_TRUNK_ID,
sip_call_to="01098765432",
sip_number=caller.attributes["sip.phoneNumber"], # 걸려온 통화의 발신자 번호
room_name=room,
participant_identity="agent",
headers={"X-ClawOps-CallToken": caller.attributes["clawops.callToken"]},
))SIP 발신에서 CallToken 을 쓸 수 없으면 다음 응답으로 거절합니다.
| 응답 | Reason | 뜻 |
|---|---|---|
| 403 | — | CallToken 없이 계정 번호가 아닌 From 으로 걸었음 |
| 403 | Q.850;cause=21;text="call token invalid" | 유효하지 않은 CallToken |
| 403 | Q.850;cause=21;text="call token expired" | 걸려온 통화가 이미 끊김 |
| 403 | Q.850;cause=21;text="from does not match call token" | From 이 걸려온 통화의 발신자 번호와 다름 |
사용 조건
CallToken은 통신사망으로 직접 걸려온 통화이면서 발신자가 국내 번호일 때만 실립니다. 그 외에는 파라미터가 오지 않습니다.- 번호의 수신 처리가 Voice URL(웹훅) 일 때만 실립니다. SIP 트렁크에서는 착신을 SIP 로 직접 받는 번호에만 실립니다.
- SIP 트렁크 자격증명에 발신번호를 지정했으면 SIP 발신에서 CallToken 을 쓸 수 없습니다.
- 걸려온 통화가 끊기면 더는 쓸 수 없습니다.
- 이어 건 통화도 계정의 동시통화 수에 들어갑니다. 걸려온 통화와 함께 2통이 동시에 진행됩니다.
- REST 발신은
Url로 거는 통화에만 쓸 수 있습니다. 수신 번호는 국내 번호만 가능합니다.
오류
| 상태 | code | 뜻 |
|---|---|---|
| 400 | call_token_invalid | 유효하지 않은 CallToken |
| 400 | call_token_from_mismatch | From 이 걸려온 통화의 발신자 번호와 다름 |
| 400 | call_token_mode_unsupported | Url 없이 사용함 |
| 409 | call_token_expired | 걸려온 통화가 이미 끊김 |
통화 전환 결과 (Transfer)
통화 조회 응답의 transferTo·transferStatus·transferDuration·transfers[] 전체 설명. 전환이 어느 경로에서 기록되는지, VoiceML Dial 결과와 무엇이 다른지, 다단계 전환은 어떻게 읽는지 안내합니다.
수신 통화 차단
받고 싶지 않은 수신 통화를 받지 않고 거절하는 방법. 수신 통화 차단 목록(계정 단위)·번호 표시제한 통화 거절(번호별)·VoiceML Reject 를 비교하고, 거절된 통화가 통화 기록과 Status Callback 에 어떻게 남는지 안내합니다.