---
title: "Upota verkkowidget"
description: "Lisää puheagentti markkinointi- tai tukisivustollesi yhdellä skriptitunnisteella — kävijät voivat puhua sille suoraan selaimesta ilman puhelinnumeroa."
---

Verkkowidget antaa sivustosi kävijöille selaimen mikrofonia hyödyntävän klikkaa ja puhu -keskustelun tekoälyagentin kanssa. Se on erillinen JavaScript- / React-SDK omalla [SDK-viitteellään](/fi/widget/overview) — tässä oppaassa keskitytään widgetin tarvitsemaan ThunderPhone-puolen määritykseen.

<Note>
  Voit tehdä kaiken tämän ilman cURLia: **Verkkowidgetit**-hallintapaneelin
  sivulla (`/dashboard/web-widgets`) luot widgetin, määrität sen tilan
  ja agentin, hallitset sallittuja verkkotunnuksia ja saat upotuskoodin.
</Note>

## Vaatimukset

<Steps>
  <Step title="Luo agentti">
    Agentti, jonka kehote ja ääni ohjaavat widget-istuntoa. Aseta
    `widget_enabled: true` (oletusarvo).
  </Step>
  <Step title="Valitse reititystila">
    - `mode="agent"` — yksi staattinen agentti avainta kohden. Yksinkertaisin vaihtoehto.
    - `mode="webhook"` — palvelimesi valitsee agentin kävijäkohtaisesti
      [`web.incoming`-webhookin](/fi/webhooks/call-incoming) kautta. Käytä tätä
      kirjautuneille käyttäjille, A/B-testeihin tai sivukohtaiseen reititykseen.
  </Step>
  <Step title="Luettele sallitut verkkotunnukset">
    Määritä jokainen isäntänimi, johon widget upotetaan. Selaimet lähettävät
    sivun alkuperän jokaisen istuntopyynnön mukana, joten luettelo estää avaimesi
    toimimisen, jos joku kopioi sen toiselle sivustolle. Tämä ei ole
    todennus: selaimen ulkopuolinen komentosarja voi lähettää minkä tahansa `Origin`-
    otsakkeen. `localhost` ei ole automaattisesti sallittu tuotannossa; jos haluat
    testata paikallisesti tuotanto-APIa vasten, lisää `localhost` luetteloon.
  </Step>
  <Step title="Valitse selaimen ohitukset">
    Päätä, mitkä istuntoasetukset sivusi voi lähettää. Uudet avaimet eivät hyväksy
    mitään; katso [Selaimen ohitukset](#browser-overrides).
  </Step>
</Steps>

## Luo julkaistava avain

<CodeGroup>
```bash Static agent
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"],
    "allowed_overrides": ["context"]
  }'
```

```bash Dynamic via webhook
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>

Vastaus sisältää `pk_live_...`-alkuisen `key`-avaimen. **Julkaistavat
avaimet ovat julkisia tarkoituksella** — ne voi sisällyttää turvallisesti
käyttöliittymäpakettiisi. Katso kaikki kentät [julkaistavien avainten viitteestä](/api-reference/publishable-keys).

<Warning>
  `allowed_domains`-kentässä on oltava vähintään yksi merkintä. `*.example.com`
  vastaa aliverkkotunnuksia (esim. `api.example.com`), mutta **ei** paljasta
  verkkotunnusta. Paljaat jokerimerkit, kuten `*` tai `*.*`, hylätään.
</Warning>

## Lisää widget sivustollesi

Kolme integraatiovaihtoehtoa käsitellään
[widgetin SDK-dokumentaatiossa](/fi/widget/overview):

<CardGroup cols={3}>
  <Card title="React-komponentti" icon="react" href="/fi/widget/react">
    `<ThunderPhoneWidget publishableKey="pk_live_..." />`.
  </Card>
  <Card title="Headless-hook" icon="circle-nodes" href="/fi/widget/headless-hook">
    `useThunderPhone()` mukautetuille käyttöliittymille.
  </Card>
  <Card title="CDN-skriptitunniste" icon="code" href="/fi/widget/cdn-script-tag">
    `ThunderPhone.mount({...})` sivustoille, jotka eivät käytä bundleria.
  </Card>
</CardGroup>

Kaikki kolme hyväksyvät saman `publishableKey`-arvon ja renderöivät
mikrofonipainikkeen sekä puhelun aikaisen äänielementin.

## Selaimen ohitukset

Widget voi lähettää sivulta neljä istuntokohtaista asetusta:

| Asetus | Widgetin prop | Mitä se muuttaa |
|---------|-------------|-----------------|
| `context` | `context` | Sivun teksti, joka lisätään agentin kehotteeseen viitteeksi |
| `variables` | ei mitään (vain raaka `POST /v1/widget/session`) | Kehotteen `{{variable}}`-paikkamerkkien arvot |
| `voice` | `voice` | Agentin ääni tässä istunnossa |
| `language` | `language` | Kieli, jolla istunto alkaa |

Julkaistava avaimesi on julkinen, joten kuka tahansa, jolla se on, voi lähettää nämä
asetukset, myös skriptistä, joka teeskentelee verkkotunnustasi. Kukin asetus on
siksi pois käytöstä, kunnes sallit sen avaimessa: valitse se kohdassa **Selaimen
ohitukset**, kun luot tai muokkaat widgetiä hallintapaneelissa, tai määritä
`allowed_overrides`
[Julkaistavien avainten API:n](/api-reference/publishable-keys) kautta. Salli vain se,
mitä sivusi todella lähettää.

Istuntopyyntö, joka sisältää asetuksen, jota avain ei salli,
epäonnistuu virheellä `400` ja nimeää asetuksen:

```json
{
  "error": "override_not_allowed",
  "fields": ["voice"],
  "message": "This publishable key does not allow the browser to set `voice`. ..."
}
```

Tarkistus koskee molempia tiloja. Webhook-tilassa sallittu asetus
välitetään myös `web.incoming`-webhookiisi (`context` saapuu nimellä
`website_context`). Ennen tämän asetuksen käyttöönottoa luodut avaimet sallivat kaikki
neljä asetusta, joten olemassa olevat upotukset toimivat edelleen; poista käytöstä ne, joita et käytä.

Widgetin `context` katkaistaan 12 000 merkkiin (noin 3 400 tokenia
tyypillistä englanninkielistä tekstiä), ja se lasketaan mukaan
[kehotteen koon lisämaksuun](/fi/guides/billing-and-topups).
Agenttia ohjeistetaan käsittelemään sitä sivun sisältönä, ei ohjeina.

## Widget-tilan webhookit

Kun `mode="webhook"`, ThunderPhone kutsuu `webhook_url`-osoitettasi jokaisen
istunnon alkaessa `web.incoming`-payloadilla. Palauta agentin määritys,
jonka haluat suorittaa kyseiselle kävijälle — se noudattaa samaa
[vastausskeemaa](/fi/webhooks/call-incoming) kuin puhelut:

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

Voit yhdistää omaa istuntoasi koskevan kontekstin (mitä asiakasta selataan,
millä sivulla hän on) kehotteeseen ja vaihtaa agentteja käyttöönoton mukaan.

## Tarkastele sessioita

Widget-sessiot näkyvät
[`GET /v1/calls`](/api-reference/calls#list-calls)-päätepisteessä, kun
`direction="widget"` — niillä on sama transkriptio, tallenne, arviointi ja
laskutus kuin puheluilla. Suodata `direction`-kentän mukaan luodaksesi vain widgeteille tarkoitetun
hallintapaneelin.

---

## Seuraavat vaiheet

<CardGroup cols={2}>
  <Card title="Widget SDK -viite" icon="window-maximize" href="/fi/widget/overview">
    React-/hook-/CDN-integroinnin tiedot.
  </Card>
  <Card title="Dynaaminen puhelukohtainen määritys" icon="bolt" href="/fi/guides/dynamic-call-config">
    Toteuta `mode="webhook"`-virtaus päästä päähän.
  </Card>
  <Card title="Julkaistavien avainten viite" icon="key" href="/api-reference/publishable-keys">
    Avainresurssin kaikki kentät.
  </Card>
  <Card title="Mikrofonisessioiden API" icon="microphone" href="/api-reference/mic-sessions">
    Ohita widget; käytä LiveKitiä suoraan mukautetuissa käyttöliittymissä.
  </Card>
</CardGroup>
