> This is a page from the ElevenLabs documentation. For an index of the documentation, fetch https://elevenlabs.io/docs/llms.txt.

# Voximplant

> **Warning**
>
> Integracja z Voximplant jest dostępna w ograniczonym zakresie i włączana osobno dla każdego obszaru roboczego. Przed przekierowaniem ruchu klientów skontaktuj się z opiekunem ElevenLabs.

## Omówienie

Integracja z Voximplant łączy rozmowę w scenariuszu VoxEngine bezpośrednio z agentem w
ElevenAgents przez WebSocket, używając Voximplant Media Streams. Voximplant obsługuje telefonię:
wybiera lub odbiera połączenie i decyduje, co dzieje się potem. ElevenAgents prowadzi
rozmowę. Nie potrzebujesz trunku SIP ani oprogramowania pośredniego.

Połączenia przychodzące i wychodzące działają tak samo: po połączeniu rozmowy scenariusz otwiera jedno
połączenie WebSocket na rozmowę z ElevenLabs. Gdy rozmowa się kończy, ElevenLabs wysyła do scenariusza pojedyncze
zdarzenie decyzji, które określa, czy przekazać dzwoniącego człowiekowi, rozłączyć połączenie czy uznać je za
przekroczone czasowo.

## Jak działa integracja

1. Twój scenariusz VoxEngine odbiera połączenie przychodzące lub wykonuje wychodzące.
2. Scenariusz otwiera WebSocket do punktu końcowego ElevenLabs dla twojego agenta i uwierzytelnia się
   kluczem API ElevenLabs jako tokenem bearer.
3. Scenariusz uruchamia strumień mediów za pomocą `call.sendMediaTo()`, przekazując dowolne `customParameters`.
   ElevenLabs zamienia każdy parametr w zmienną dynamiczną i odpowiada własnym `start`.
4. Voximplant i ElevenLabs wymieniają 16-bitowy liniowy dźwięk PCM o częstotliwości 8 kHz w komunikatach `media`.
5. Gdy rozmowa się kończy, ElevenLabs wysyła resztę ostatniej wypowiedzi agenta, jedno
   niestandardowe zdarzenie `elevenlabs-decision` i komunikat `stop`. Scenariusz zamyka wtedy WebSocket
   i wykonuje działanie zgodne z decyzją.

## Wymagania

Zanim zaczniesz, upewnij się, że masz:

1. Konto Voximplant z aplikacją, numerem telefonu lub możliwością wykonywania połączeń wychodzących oraz uprawnieniami do
   edycji scenariuszy.
2. Obszar roboczy ElevenLabs z włączoną integracją Voximplant.
3. Agenta ElevenLabs i osobny klucz API.

## Konfiguracja ElevenLabs

#### Utwórz lub wybierz agenta

Utwórz agenta w ElevenAgents. Ustaw mu pierwszą wiadomość, jeśli ma zacząć mówić od razu po
połączeniu. Formaty audio są ustawiane przez integrację, więc skonfigurowane formaty agenta nie są używane
w rozmowach Voximplant.

#### Włącz Zakończ połączenie

W **Agent → Tools → System tools** włącz **End call**, aby agent mógł zakończyć rozmowę.
Powód podany przez agenta przy kończeniu połączenia jest wysyłany do scenariusza wraz z decyzją.

#### Dodaj regułę przekazania Voximplant (opcjonalnie)

Aby agent mógł przekazać dzwoniącego człowiekowi, dodaj mu narzędzie systemowe **Transfer to number** z
regułą przekazania, której konfiguracja dostawcy to `voximplant`. Reguła nie ma miejsca docelowego:
rozmowa kończy się decyzją `transfer-to-agent`, a dzwoniącego przekierowuje twój scenariusz. Reguły przekazania
konfiguruje się przez API. Dodaj narzędzie przez `PATCH` na agencie:

```bash
curl -X PATCH "https://api.elevenlabs.io/v1/convai/agents/agent_7101k5zvyjhmfg983brhmhkd98n6" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "conversation_config": {"agent": {"prompt": {"built_in_tools": {
      "end_call": {"type": "system", "name": "end_call", "description": "",
                   "params": {"system_tool_type": "end_call"}},
      "transfer_to_number": {
        "type": "system", "name": "transfer_to_number", "description": "",
        "params": {
          "system_tool_type": "transfer_to_number",
          "transfers": [],
          "transfer_rules": [{
            "condition": "the caller asks to speak with a human",
            "provider_configs": [
              {"type": "voximplant", "config": {"type": "voximplant_handoff"}}
            ]
          }]
        }
      }
    }}}}
  }'
```

Wyślij pełny obiekt `built_in_tools` agenta, w tym narzędzia, które już ma, takie jak `end_call`.
Opcja, którą agent odsyła, to stały token `voximplant`, więc wystarczy jedna reguła Voximplant na narzędzie.
Numery telefonów i identyfikatory URI SIP skonfigurowane dla innych dostawców nie są dostępne w rozmowach Voximplant.

> **Note**
>
> Reguły przekazania są ustawieniem zarządzanym przez API. Konfiguruj i aktualizuj narzędzie **Transfer to number**
> agenta, który z nich korzysta, przez API, jak wyżej; edytor narzędzi w panelu działa z
> listą przekazań dla poszczególnych numerów.

#### Utwórz osobny klucz API

Utwórz klucz API w tym samym obszarze roboczym co agent i ogranicz jego zakres do ElevenAgents. Aby akceptować
połączenia tylko z Voximplant, ogranicz dozwolone adresy IP klucza do serwerów mediów Voximplant,
które Voximplant podaje pod adresem
`https://api.voximplant.com/getMediaResources?with_mediaservers`.

#### Zanotuj adres URL WebSocket

Scenariusz łączy się z adresem URL zawierającym ID twojego agenta:

| Środowisko        | URL                                                                                                               |
| ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| Domyślne          | `wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6`                    |
| Rezydencja danych | `wss://api.<region>.residency.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6` |

Aby przypiąć gałąź agenta, dodaj `?branch_id=<branch_id>`.

> **Info**
>
> Jeśli twoje konto ElevenLabs działa w izolowanym środowisku rezydencji, zastąp `<region>` swoim
> kodem regionu. Dostępne regiony znajdziesz w [rezydencji danych](/docs/pl/overview/administration/data-residency).

## Konfiguracja Voximplant

#### Utwórz aplikację

W [panelu Voximplant](https://manage.voximplant.com/applications) otwórz **Applications**
i kliknij **Create application**. Nadaj jej nazwę, na przykład `elevenlabs-agent`, a następnie kliknij
**Create**.

![Voximplant: Utwórz aplikację](/docs/_fern-files/_img/29af341fa0a32eaaab444ade8305208121487413c5868597386a973b14fe4fe7.webp)

#### Zapisz klucz API jako sekret

W aplikacji otwórz **Secrets** i kliknij **Add secret**. Nazwij go `ELEVENLABS_API_KEY`, wklej
klucz API utworzony dla obszaru roboczego agenta w polu **Value** i kliknij **Add secret**.
Scenariusz odczytuje go przez `VoxEngine.getSecretValue()`, więc klucz nigdy nie pojawia się w kodzie scenariusza.

![Voximplant: Dodaj sekret](/docs/_fern-files/_img/ecf8be823bbc15b263e3f4838684a78de3a3594704be0055b443d15ab93e1485.webp)

#### Utwórz scenariusz

Otwórz **Scenarios**, kliknij **Create scenario**, nazwij go `elevenlabs_agent`, wklej kod poniżej,
zastąp ID agenta w `ELEVENLABS_URL` i kliknij **Save**. Odbiera on połączenie przychodzące, przesyła je
strumieniowo do agenta i wykonuje działanie zgodne z decyzją po zakończeniu rozmowy. W przypadku połączenia wychodzącego otwórz
WebSocket w procedurze obsługi `CallEvents.Connected` wykonanego połączenia.

```javascript maxLines=0
const ELEVENLABS_URL =
  "wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6";

VoxEngine.addEventListener(AppEvents.CallAlerting, ({ call }) => {
  call.answer();
  let decision = null;

  const ws = VoxEngine.createWebSocket(ELEVENLABS_URL, {
    headers: [
      {
        name: "Authorization",
        value: `Bearer ${VoxEngine.getSecretValue("ELEVENLABS_API_KEY")}`,
      },
    ],
  });

  ws.addEventListener(WebSocketEvents.OPEN, () => {
    call.sendMediaTo(ws, {
      encoding: WebSocketAudioEncoding.PCM16_8KHZ,
      customParameters: { customer_name: "Ana", task_id: "task-7" },
    });
    ws.sendMediaTo(call);
  });

  ws.addEventListener(WebSocketEvents.MESSAGE, ({ text }) => {
    const message = JSON.parse(text);
    if (message.customEvent === "elevenlabs-decision") {
      decision = message.payload;
      Logger.write(`ElevenLabs decision: ${JSON.stringify(decision)}`);
    }
  });

  ws.addEventListener(WebSocketEvents.CLOSE, (e) => {
    Logger.write(`ElevenLabs socket closed: code=${e.code} reason=${e.reason}`);
    if (decision?.action === "transfer-to-agent") {
      // Route the caller to a human here, for example with VoxEngine.callPSTN().
      call.say("Connecting you to an agent.", { language: VoiceList.Amazon.en_US_Joanna });
      call.addEventListener(CallEvents.PlaybackFinished, () => call.hangup());
      return;
    }
    call.hangup();
  });

  call.addEventListener(CallEvents.Disconnected, () => {
    ws.close();
    VoxEngine.terminate();
  });
});
```

![Voximplant: scenariusz w edytorze](/docs/_fern-files/_img/d2e26165f57cae40fc01e8de28052fef09b2f98bd90c0e1a8779423715f61e2e.webp)

#### Przekieruj połączenia do scenariusza

Otwórz **Routing**, kliknij **Create rule**, nadaj jej nazwę i przypisz scenariusz `elevenlabs_agent`.
Domyślny wzorzec `.*` wysyła każde połączenie do aplikacji przez scenariusz;
zawęź go do numeru telefonu, jeśli aplikacja obsługuje także inne połączenia. Aby przekierować numer telefonu,
przypisz go do aplikacji w sekcji **Numbers**.

![Voximplant: Utwórz regułę](/docs/_fern-files/_img/bc6830b7dcd66dc0b59595456b1197bdcbb9174f15778da7ba9655ba4b93936e.webp)

#### Wykonaj połączenie testowe

Możesz zadzwonić do aplikacji z przeglądarki bez numeru telefonu:

1. Otwórz **Users**, kliknij **Create user** i utwórz użytkownika z hasłem.

   ![Voximplant: Nowy użytkownik](/docs/_fern-files/_img/4754c9234588fd0caa336e1168e207b265557dc4e6a12b1cf8bced1275b8bae6.webp)

2. W **Routing** kliknij **Test tools**, a potem **Softphone**. Zaloguj się jako ten użytkownik, zezwól na
   dostęp do mikrofonu, wpisz dowolny cel i zadzwoń. Agent odbierze połączenie swoją pierwszą wiadomością.

3. Po zakończeniu połączenia otwórz **Call history**. Przy każdym połączeniu widnieje odcinek WebSocket obok
   samego połączenia. Kliknij **View log**, aby zobaczyć sesję.

   ![Voximplant: Historia połączeń](/docs/_fern-files/_img/4e2416ad3587bb320300173cf679f7c5d7a5e545550b0a647062a79866dac40c.webp)

   Dziennik pokazuje decyzję wysłaną przez ElevenLabs, zamknięcie WebSocket i kolejne działanie
   scenariusza. W tym przykładzie dzwoniący poprosił o rozmowę z człowiekiem, więc decyzja to `transfer-to-agent`
   z powodem podanym przez agenta.

   ![Voximplant: Dziennik sesji ze zdarzeniem elevenlabs-decision
   event](/docs/_fern-files/_img/f8b4602fa02cfd3c417557377aaa5dd66e2e88a67e7adf4cb037ccae1840f45c.webp)

> **Warning**
>
> Działaj na podstawie zdarzenia `elevenlabs-decision`, a nie `MEDIA_ENDED`. Voximplant wywołuje `MEDIA_ENDED` po
> około sekundzie bez audio z ElevenLabs, co może zdarzyć się w trakcie rozmowy.

## Zmienne dynamiczne

Każdy klucz w `customParameters` staje się zmienną dynamiczną o tej samej nazwie. Wartości, które nie są
ciągami znaków, są zamieniane na tekst, na przykład `true` staje się `"true"`. `customParameters` może być
obiektem lub ciągiem zakodowanym w JSON. Klucze zaczynające się od `system__` lub `integration__` są zastrzeżone i
są pomijane.

## Zdarzenia decyzji

Gdy rozmowa się kończy, ElevenLabs wysyła dokładnie jedną decyzję przed komunikatem `stop`:

```json
{ "customEvent": "elevenlabs-decision", "payload": { "action": "terminate", "reason": "under_18" } }
```

| `action`            | Kiedy jest wysyłana                                                                                                                                                                | `reason`                                                          |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `transfer-to-agent` | Agent wywołał **Transfer to number** z regułą przekazania Voximplant.                                                                                                              | Powód przekazania podany przez agenta.                            |
| `timeout`           | Przekroczono czas rozmowy z powodu ciszy lub po ostatniej wiadomości agenta, albo agent zakończył połączenie po 15 sekundach ciszy dzwoniącego, nie licząc czasu, gdy agent mówił. | Komunikat o przekroczeniu czasu lub powód podany przez agenta.    |
| `terminate`         | Agent zakończył połączenie przez **End call** albo rozmowa zakończyła się normalnie.                                                                                               | Powód podany przez agenta przy **End call**, jeśli został podany. |
| `unexpected`        | Rozmowa zakończyła się z powodu błędu.                                                                                                                                             | Opis błędu.                                                       |

Jeśli scenariusz najpierw wyśle `stop` lub zamknie WebSocket, na przykład ponieważ dzwoniący się rozłączył,
ElevenLabs nie wyśle decyzji.

## Audio

Voximplant i ElevenLabs wymieniają w obu kierunkach 16-bitowy monofoniczny liniowy dźwięk PCM o częstotliwości 8 kHz. ElevenLabs
nadaje dźwięk agenta niemal w czasie rzeczywistym, więc gdy dzwoniący przerwie agentowi, odtworzy się jeszcze najwyżej około
0,4 sekundy przerwanej odpowiedzi.

## Błędy uwierzytelniania

ElevenLabs zamyka WebSocket kodem `1008` i powodem `bad auth token`, gdy
brakuje nagłówka `Authorization` lub jest nieprawidłowy, klucz API jest nieważny albo niedozwolony z adresu IP
nawiązującego połączenie, klucz należy do innego obszaru roboczego albo użytkownik klucza nie ma dostępu do
agenta z włączonym uwierzytelnianiem.

## Ograniczenia i nieobsługiwane funkcje

* Narzędzia klienta i narzędzie systemowe **Play keypad touch tone** nie są obsługiwane. **Transfer to
  number** działa tylko przez regułę przekazania Voximplant; to scenariusz decyduje, dokąd
  trafia dzwoniący.
* Nadpisania konfiguracji, takie jak inna pierwsza wiadomość, nie mogą być przekazywane ze scenariusza;
  można przekazywać tylko zmienne dynamiczne.
* Wyniki zbierania danych nie są wysyłane do scenariusza. Użyj do tego
  [webhooka po rozmowie](/docs/pl/eleven-agents/workflows/post-call-webhooks).