> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryvox.co/llms.txt
> Use this file to discover all available pages before exploring further.

# 실시간 통화 모니터링

> 진행 중인 통화를 대시보드에서 지켜보고 상담사에게 넘기거나, 내 웹 앱에서 들을 수 있어요.

**기록** 페이지의 **통화** 탭에서 진행 중인 통화의 대화를 실시간으로 보고 상담사에게 넘길 수 있어요. 대시보드 밖의 내 웹 앱에서는 SDK로 같은 통화의 음성과 대화 내용을 받아요.

![통화 상세의 실시간 모니터링 중 표시, 에이전트·유저 파형, 실시간으로 쌓이는 대화](https://mintcdn.com/fleek/hvr7jJEKme0RvuLR/images/screens/operate/monitor/live-monitoring/live-sheet.webp?fit=max\&auto=format\&n=hvr7jJEKme0RvuLR\&q=85\&s=5d71944621f76c926c31d33908c66b49)

## 진행 중인 통화 지켜보기

[통화 기록](https://docs.tryvox.co/docs/operate/monitor/history.md)의 **연결 종료 사유** 컬럼에 **통화 중** 배지가 붙은 행을 여세요. 상세 위쪽에 **실시간 모니터링 중** 표시와 **에이전트**·**유저** 파형이 움직이고, **대화**에 발화와 도구 호출이 쌓여요.

워크스페이스 멤버 누구나 실시간 상세를 볼 수 있어요. [개인정보 마스킹](https://docs.tryvox.co/docs/build/security/pii-protection.md)은 통화가 끝난 뒤 적용돼서 진행 중에는 원문이 보여요.

## 통화 당겨받기

상담사가 직접 받아야 할 통화는 상담사 전화로 바로 넘기세요. 에이전트에 통화 전환 도구가 없어도 돼요.

**1. 당겨받기 누르기**

**통화 중** 배지가 붙은 전화 통화를 열고 **당겨받기**를 누르세요. 웹 통화 테스트는 당겨받을 수 없어요.

**2. 전환 대상과 전환 타입 고르기**

**전환 대상**에 상담사 전화번호나 SIP 주소를 넣고 **전환 타입**을 고르세요. 기본값은 **안내 후 전환**이에요. 상담사 전화기에 보일 번호는 **발신표기번호**에서 정해요.

![통화 전환 창의 전환 대상, 전환 타입, 발신표기번호](https://mintcdn.com/fleek/hvr7jJEKme0RvuLR/images/screens/operate/monitor/live-monitoring/pickup-dialog.webp?fit=max\&auto=format\&n=hvr7jJEKme0RvuLR\&q=85\&s=38e07101e4f2b244e7536185d2e61333)

**3. 전환하기**

**전환**을 누르면 고객에게 "상담원을 연결해 드리겠습니다. 잠시만 기다려 주세요."라는 안내가 나가고 상담사 전화가 울려요. **안내 후 전환**은 상담사에게 대화 요약을 먼저 전하고, 상담사가 30초 안에 받지 않으면 에이전트가 응대를 이어가요.

외부 시스템에서 넘기려면 [API로 진행 중 통화 넘기기](https://docs.tryvox.co/docs/build/tools/builtin/transfer-call.md#api로-진행-중-통화-넘기기)를 보세요.

## 내 앱에서 통화 듣기

상담사 CRM이나 관제 화면처럼 대시보드 밖에서 통화를 들을 때 써요. 내 서버가 접속 정보를 받아 브라우저에 넘기면 브라우저가 SDK로 들어요. 추가 요금은 없어요.

### 서버에서 접속 정보 받기

통화가 속한 워크스페이스의 [서버용 키](https://docs.tryvox.co/docs/workspace/api-keys.md)(`sk_`)로 듣기 API를 호출하세요. 통화 ID는 [`call_started` 웹훅](https://docs.tryvox.co/docs/operate/monitor/webhooks/schema#call_started)의 `call.call_id`예요. 서버용 키는 서버에만 두고, 들어도 되는 사용자인지 확인한 뒤 응답의 `connection`만 브라우저에 넘기세요.

```js 서버 (Node.js) theme={null}
app.post("/api/calls/:callId/listen", async (req, res) => {
  // 이 사용자가 이 통화를 들어도 되는지 먼저 확인하세요.
  const response = await fetch(
    `https://client-api.tryvox.co/v3/calls/${req.params.callId}/listen`,
    {
      method: "POST",
      headers: { Authorization: `Bearer ${process.env.VOX_API_KEY}` },
    },
  );
  if (!response.ok) {
    res.status(response.status).end();
    return;
  }
  const { connection } = await response.json();
  res.json({ connection });
});
```

전체 필드와 오류는 [진행 중 통화 듣기 요청 API](https://docs.tryvox.co/api-reference/v3/calls/진행-중-통화-듣기-요청.md)에 있어요.

### 브라우저에서 듣기

받은 `connection`을 그대로 SDK에 넘기세요. 브라우저가 소리 재생을 막으면 버튼을 보여 주고, 사용자가 누를 때 `startAudio()`를 부르세요.

```js JavaScript theme={null}
import { CallMonitor } from "@vox-ai/client";

const { connection } = await fetch(`/api/calls/${callId}/listen`, {
  method: "POST",
}).then((response) => response.json());

const monitor = await CallMonitor.start({
  connection,
  onMessage: (message) => {
    if (message.isFinal) console.log(`${message.source}: ${message.text}`);
  },
  onAudioPlaybackChange: (canPlayAudio) => {
    playButton.hidden = canPlayAudio;
  },
  onDisconnect: () => console.log("듣기가 끝났어요"),
});

playButton.onclick = () => monitor.startAudio();
```

```tsx React theme={null}
import { useCallMonitor } from "@vox-ai/react";

export function CallListener({ callId }: { callId: string }) {
  const monitor = useCallMonitor({
    onDisconnect: () => console.log("듣기가 끝났어요"),
  });

  const listen = async () => {
    const { connection } = await fetch(`/api/calls/${callId}/listen`, {
      method: "POST",
    }).then((response) => response.json());
    await monitor.start({ connection });
  };

  return (
    <div>
      <button
        onClick={() => listen().catch((error) => console.error(error))}
        disabled={monitor.status !== "disconnected"}
      >
        듣기
      </button>
      {!monitor.canPlayAudio && (
        <button onClick={() => monitor.startAudio()}>소리 켜기</button>
      )}
      <button onClick={() => monitor.stop()}>그만 듣기</button>
      <ul>
        {monitor.messages.map((message) => (
          <li key={message.id}>
            {message.source}: {message.text}
          </li>
        ))}
      </ul>
    </div>
  );
}
```

* **두 사람의 음성과 대화 내용을 받아요.** 메시지의 `source`가 `"agent"`면 에이전트, `"user"`면 고객이에요.
* **통화에는 드러나지 않아요.** 마이크를 쓰지 않고, 고객과 에이전트에게 듣는 사람이 보이지 않아요.
* **10분 안에 시작하세요.** `connection`은 발급 10분 뒤(`expires_at`)부터 쓸 수 없어요.
* **통화가 끝나면 1\~2초 뒤 듣기도 끝나요.** 이때 `onDisconnect`가 불려요.

옵션과 메서드 전체는 [JavaScript](https://docs.tryvox.co/docs/sdk/javascript.md#진행-중인-통화-듣기)와 [React](https://docs.tryvox.co/docs/sdk/react.md#진행-중인-통화-듣기)에 있어요.

## 문제가 생겼을 때

> [accordion] 통화가 있는데 듣기 API가 404를 돌려줘요
>
> 그 통화가 속한 워크스페이스의 서버용 키로 다시 요청하세요. 상위 워크스페이스의 키로는 하위 워크스페이스의 통화를 들을 수 없어요.

> [accordion] 듣기를 시작했는데 소리가 들리지 않아요
>
> 버튼 클릭 같은 사용자 동작 안에서 startAudio()를 부르세요. 브라우저는 사용자가 화면을 누르기 전까지 소리 재생을 막을 수 있어요.

> [accordion] 듣기 시작이 CONNECTION\_EXPIRED나 CALL\_ENDED 오류로 끝나요
>
> CONNECTION\_EXPIRED면 서버에서 connection을 새로 받아 다시 시작하고, CALL\_ENDED면 [통화 기록](https://docs.tryvox.co/docs/operate/monitor/history.md)에서 그 통화를 보세요. 발급 10분이 지난 connection이나 이미 끝난 통화는 들을 수 없어요.

## 관련 문서

* [통화 기록](https://docs.tryvox.co/docs/operate/monitor/history.md): 끝난 통화를 찾고 검토하기
* [JavaScript](https://docs.tryvox.co/docs/sdk/javascript.md#진행-중인-통화-듣기): `CallMonitor`로 브라우저에서 통화 듣기
* [React](https://docs.tryvox.co/docs/sdk/react.md#진행-중인-통화-듣기): `useCallMonitor` 훅으로 통화 듣기
* [통화 전환](https://docs.tryvox.co/docs/build/tools/builtin/transfer-call.md): 전환 방식 비교
* [API 키](https://docs.tryvox.co/docs/workspace/api-keys.md): 서버용 키를 만들고 보관하기


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.