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

# 웹 위젯 삽입

> 전화번호 없이 마케팅 또는 지원 사이트에 음성 에이전트를 추가합니다.

웹 위젯은 브라우저의 마이크를 사용하여 사이트 방문자가 에이전트와 클릭하여 통화하는 대화를 할 수 있게 합니다. 자체 [SDK 참조](/ko/widget/overview)가 있는 별도의 JavaScript / React SDK이며, 이 가이드에서는 위젯에 필요한 ThunderPhone 측 설정에 중점을 둡니다.

<Note>
  cURL 없이도 모두 수행할 수 있습니다. **웹 위젯** 대시보드 페이지
  (`/dashboard/web-widgets`)에서 위젯을 만들고, 모드와 에이전트를 설정하며,
  허용 도메인을 관리하고, 임베드 스니펫을 제공합니다.
</Note>

## 사전 요구 사항

<Steps>
  <Step title="에이전트 만들기">
    프롬프트와 음성을 위젯 세션에서 사용할 에이전트입니다.
    `widget_enabled: true`(기본값)로 설정합니다.
  </Step>

  <Step title="라우팅 모드 결정">
    * `mode="agent"` — 키당 하나의 고정 에이전트입니다. 가장 간단합니다.
    * `mode="webhook"` — 서버가 방문자별로 에이전트를 선택합니다.
      [`web.incoming` 웹훅](/ko/webhooks/call-incoming)을 통해 선택합니다. 로그인한 사용자, A/B 테스트 또는 페이지별 라우팅에 사용합니다.
  </Step>

  <Step title="허용 도메인 나열">
    공개 키는 오리진으로 제한됩니다. 위젯을 임베드할 모든 호스트 이름을
    지정해야 합니다. 로컬 개발 중에는 `localhost` / `127.0.0.1`이 항상
    허용됩니다.
  </Step>
</Steps>

## 공개 키 만들기

<CodeGroup>
  ```bash Static agent theme={null}
  curl -X POST https://api.thunderphone.com/v1/publishable-key \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name":            "Marketing site (prod)",
      "mode":            "agent",
      "agent_id":        12,
      "allowed_domains": ["example.com", "*.example.com"]
    }'
  ```

  ```bash Dynamic via webhook theme={null}
  curl -X POST https://api.thunderphone.com/v1/publishable-key \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name":            "Support (dynamic)",
      "mode":            "webhook",
      "webhook_url":     "https://example.com/thunderphone/widget-hook",
      "allowed_domains": ["support.example.com"]
    }'
  ```
</CodeGroup>

응답에는 `pk_live_...`로 시작하는 `key`가 포함됩니다. **공개 키는 설계상 공개됩니다** — 프런트엔드 번들에 안전하게 포함할 수 있습니다.
모든 필드는 [공개 키 참조](/api-reference/publishable-keys)를 확인합니다.

<Warning>
  `allowed_domains`에는 최소 하나의 항목이 포함되어야 합니다. `*.example.com`은
  하위 도메인(예: `api.example.com`)과 일치하지만, 루트 도메인과는 **일치하지
  않습니다**. `*` 또는 `*.*` 같은 루트 와일드카드는 거부됩니다.
</Warning>

## 사이트에 위젯 추가

다음 [위젯 SDK 문서](/ko/widget/overview)에서 세 가지 통합 옵션을 다룹니다.

<CardGroup cols={3}>
  <Card title="React 구성 요소" icon="react" href="/ko/widget/react">
    `<ThunderPhoneWidget publishableKey="pk_live_..." />`.
  </Card>

  <Card title="헤드리스 훅" icon="circle-nodes" href="/ko/widget/headless-hook">
    맞춤 UI용 `useThunderPhone()`.
  </Card>

  <Card title="CDN 스크립트 태그" icon="code" href="/ko/widget/cdn-script-tag">
    번들러를 사용하지 않는 사이트용 `ThunderPhone.mount({...})`.
  </Card>
</CardGroup>

세 옵션 모두 동일한 `publishableKey`를 받고, 마이크 버튼과 통화 중 오디오 요소를 렌더링합니다.

위젯 `context`는 12,000자로 잘립니다(일반적인 영어 텍스트 기준 약 3,400토큰). 또한 [프롬프트 크기 할증](/ko/guides/billing-and-topups)에 포함됩니다.

## 위젯 모드 웹훅

`mode="webhook"`인 경우 ThunderPhone은 세션이 시작될 때마다 `web.incoming` 페이로드와 함께 `webhook_url`을 호출합니다. 해당 방문자에게 실행할 에이전트 구성을 반환합니다. 전화 통화와 동일한 [응답 스키마](/ko/webhooks/call-incoming)를 따릅니다.

```json theme={null}
{
  "prompt":  "You are a VIP concierge for Jane Doe.",
  "voice":   "john",
  "product": "storm-base",
  "tools":   [ /* per-customer tools */ ]
}
```

자체 세션의 컨텍스트(어떤 고객이 탐색 중인지, 어떤 페이지에 있는지)를 프롬프트에 포함하고, 배포 단계별로 에이전트를 변경할 수 있습니다.

## 세션 관찰

위젯 세션은
[`GET /v1/calls`](/api-reference/calls#list-calls)에
`direction="widget"`으로 표시되며, 전화 통화와 동일한 트랜스크립트, 녹음, 평가 및
과금이 적용됩니다. `direction`으로 필터링하여 위젯 전용
대시보드를 구축합니다.

***

## 다음 단계

<CardGroup cols={2}>
  <Card title="위젯 SDK 레퍼런스" icon="window-maximize" href="/ko/widget/overview">
    React / hook / CDN 통합 세부 정보입니다.
  </Card>

  <Card title="통화별 동적 구성" icon="bolt" href="/ko/guides/dynamic-call-config">
    `mode="webhook"` 흐름을 처음부터 끝까지 구현합니다.
  </Card>

  <Card title="게시 가능 키 레퍼런스" icon="key" href="/api-reference/publishable-keys">
    키 리소스의 모든 필드입니다.
  </Card>

  <Card title="마이크 세션 API" icon="microphone" href="/api-reference/mic-sessions">
    위젯을 건너뛰고 맞춤 UI를 위해 LiveKit을 직접 구동합니다.
  </Card>
</CardGroup>
