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

# Web SDK

> 訪問者がウェブサイトから直接 AI エージェントと話せるようにします — 電話番号不要、アプリのダウンロード不要。

## Web SDK とは

Web SDK はウェブサイトに埋め込む小さなコードです。訪問者が「今すぐ話す」ボタンをクリックすると、ブラウザ内でマイクを使って OneInbox エージェントとのライブ音声会話が始まります。

ライブチャットウィジェットの音声版と考えてください。

**SDK が処理するもの：**

* ブラウザへのマイク許可のリクエスト
* リアルタイムの音声ストリーミング（双方向）
* 会話中のライブトランスクリプト表示
* ミュート、ミュート解除、ハングアップ

**チームがセットアップするもの：**

* OneInbox のエージェント（応答する AI）
* 通話を開始するサイト上のボタンまたはウィジェット

***

## クイックスタート — サイトへの最も簡単な追加方法

これが最速のパスです：公開可能なキー + Web SDK、バックエンド不要。

<Steps>
  <Step title="エージェントを作成する">
    通話に応答するエージェントを構築します — まだ作成していない場合は [クイックスタート](/guides/quickstart) を参照してください。その `id`（`agt_…`）を保存します。
  </Step>

  <Step title="公開可能なキーを作成する">
    [OneInbox ダッシュボード](https://oneinbox-dashboard.vercel.app) で **Settings → Publishable Keys** → **Create key** へ。このキーに許可するオリジンを入力します — 1 行に 1 つ：

    | 入力内容                                                    | 使うタイミング                                                         |
    | ------------------------------------------------------- | --------------------------------------------------------------- |
    | `https://yoursite.com`                                  | キーを特定のドメインに制限 — 他のオリジンからのリクエストは `403 ORIGIN_NOT_ALLOWED` で拒否される |
    | `https://yoursite.com` + `https://staging.yoursite.com` | 複数の特定ドメイン（本番 + ステージングなど）                                        |
    | `*` または空白                                               | すべてのオリジンを許可 — 開発中やドメインロックが不要な内部ツールに便利                           |

    キーをコピーします — `oi_pk_live_…` で始まります。

    <Warning>
      `*` を使用すると、どのウェブサイトでもあなたの公開可能なキーを使ってエージェントへの通話を開始できます。ローカルテストには問題ありませんが、本番稼働前に実際のドメインに制限してください。
    </Warning>
  </Step>

  <Step title="Web SDK をインストールする">
    ```bash theme={null}
    npm install @oneinbox/web-sdk
    ```
  </Step>

  <Step title="エージェントに接続する">
    公開可能なキーで SDK を初期化し、`start()` でエージェントの `id` を指定します：

    ```ts theme={null}
    import { OneInbox } from "@oneinbox/web-sdk";

    const oi = new OneInbox("oi_pk_live_…");
    await oi.start("agt_…");
    ```
  </Step>

  <Step title="サイトにボタンを追加する">
    `start()` の呼び出しを任意のボタンに接続します — 例えば「今すぐ話す」。訪問者がクリックすると、マイクを使ってブラウザ内でその場で通話が始まります。
  </Step>
</Steps>

以上です — サーバー不要、別途「通話を作成する」ステップも不要です。完全なイベント/コントロール API（ミュート、トランスクリプト、ハングアップなど）は以下の [Vanilla サンプル](#vanilla-example) と [React サンプル](#react-example) にあります。

***

## プロダクトへの組み込み方

訪問者が「通話する」をクリックすると：

1. ウェブサイトがサーバーに問い合わせます：*「この訪問者の通話を開始して」*
2. サーバーが OneInbox API 経由で通話を作成し、短命のアクセストークンを受け取ります
3. Web SDK がそのトークンを使って訪問者のブラウザをエージェントに接続します
4. 会話が始まります — ライブ、双方向の音声

サーバーが秘密の API キーを保持します。ブラウザは通話終了時に期限切れになる一時トークンのみを受け取ります — 訪問者に機密情報が漏洩しません。

***

## 2 つのパッケージ

| パッケージ                     | 使うタイミング                        |
| ------------------------- | ------------------------------ |
| `@oneinbox/web-sdk`       | プレーンな JavaScript または任意のフレームワーク |
| `@oneinbox/web-sdk-react` | React アプリ — すぐに使えるフックを提供       |

どちらも同じことをします。React パッケージは React に使いやすいパターンでコアをラップしたものです。

***

## インストール

```bash theme={null}
# Vanilla JavaScript / 任意のフレームワーク
npm install @oneinbox/web-sdk

# React
npm install @oneinbox/web-sdk-react @oneinbox/web-sdk react
```

各パッケージは自己完結型です — SDK は音声接続を処理するのに必要なすべてをバンドルしているため、他のコンパニオンパッケージのインストールは不要です。

***

## Vanilla サンプル

```ts theme={null}
import { OneInbox } from "@oneinbox/web-sdk";

const oi = new OneInbox("oi_pk_live_…");

// 通話中に起きることに反応する
oi.on("call-start",  ()  => showCallUI());
oi.on("call-end",    ()  => showIdleUI());
oi.on("transcript",  (t) => appendTranscript(t.role, t.text));  // ライブキャプション
oi.on("error",       (e) => showError(e.message));

// 通話を開始 — 訪問者の名前を渡してエージェントに挨拶させる
await oi.start("agt_…", { variables: { customer_name: "Sama" } });

// 通話中
oi.setMuted(true);   // 訪問者のマイクをミュート
oi.setMuted(false);  // ミュート解除

await oi.stop();     // ハングアップ
```

### リッスンできるイベント

| イベント                          | 意味                                 |
| ----------------------------- | ---------------------------------- |
| `call-start`                  | 通話が接続されました — アクティブな通話 UI を表示       |
| `call-end`                    | 通話が終了しました — アイドル状態に戻る              |
| `transcript`                  | 新しい発話行が聞こえました — キャプションまたはチャットログを更新 |
| `speech-start` / `speech-end` | 誰かが話し始めたまたは止めた — 発話インジケーターをアニメーション |
| `volume-level`                | 訪問者のマイクの現在の音量（0〜1）— マイクレベルバーを駆動    |
| `error`                       | 何かが間違っています — エラーメッセージを表示           |

### コントロール

| メソッド                               | 動作                                              |
| ---------------------------------- | ----------------------------------------------- |
| `oi.start(agentId, { variables })` | 通話を開始                                           |
| `oi.stop()`                        | 通話を終了                                           |
| `oi.setMuted(true / false)`        | 訪問者のマイクをミュートまたはミュート解除                           |
| `oi.isMuted()`                     | マイクが現在ミュートされている場合 `true` を返す                    |
| `oi.status`                        | 現在の状態：`idle`、`connecting`、`active`、または `ending` |

***

## React サンプル

```tsx theme={null}
import { OneInboxProvider, useOneInbox } from "@oneinbox/web-sdk-react";

// アプリの最上位で一度ラップする
function App() {
  return (
    <OneInboxProvider publishableKey="oi_pk_live_…">
      <CallWidget agentId="agt_…" />
    </OneInboxProvider>
  );
}

// プロバイダー内のどこでもフックを使用
function CallWidget({ agentId }) {
  const { start, stop, status, transcripts, isAgentSpeaking, isMuted, setMuted } = useOneInbox();
  const active = status === "active";

  return (
    <div>
      <button onClick={() => (active ? stop() : start(agentId))}>
        {active ? "Hang up" : "Talk to us"}
      </button>

      {active && (
        <button onClick={() => setMuted(!isMuted)}>
          {isMuted ? "Unmute" : "Mute"}
        </button>
      )}

      <p>{isAgentSpeaking ? "Agent is speaking…" : status}</p>

      {transcripts.map((t, i) => (
        <p key={i}><b>{t.role}:</b> {t.text}</p>
      ))}
    </div>
  );
}
```

`useOneInbox()` は通話 UI の構築に必要なすべてを提供します：

| 値                             | 内容                                             |
| ----------------------------- | ---------------------------------------------- |
| `status`                      | 現在の通話状態（`idle`、`connecting`、`active`、`ending`） |
| `transcripts`                 | これまでの会話のすべての行                                  |
| `isAgentSpeaking`             | エージェントが話している間 `true`                           |
| `isMuted`                     | 訪問者のマイクがミュートされている場合 `true`                     |
| `volume`                      | リアルタイムのマイクレベル（0〜1）                             |
| `error`                       | 最後のエラー（もしあれば）                                  |
| `start` / `stop` / `setMuted` | コントロール                                         |
