> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Salesforce

## Omówienie

Połącz agentów AI ElevenLabs z Salesforce CRM, aby uzyskać dostęp do danych klientów, zarządzać leadami i tworzyć szanse sprzedażowe. Ta integracja pozwala agentom pobierać istniejące rekordy klientów, tworzyć nowe leady i kontakty oraz wysyłać zapytania do obiektów Salesforce podczas rozmów.

## Możliwości

| Możliwość                   | Obsługa                                                                                                        |
| --------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Tryb zerowej retencji (ZRM) | Nieobsługiwany                                                                                                 |
| Załączniki w wyzwalaczach   | Nieobsługiwane — załączniki w przychodzących komentarzach do zgłoszeń i e-mailach nie są przekazywane agentowi |
| Załączniki w narzędziach    | Nieobsługiwane — narzędzia działają tylko na tekście                                                           |

## Konfiguracja

Ta integracja używa do uwierzytelniania **Salesforce OAuth 2.0 Client Credentials**. Musisz utworzyć w Salesforce External Client App.

#### Utwórz External Client App

1. Zaloguj się do organizacji Salesforce jako administrator
2. Przejdź do **Setup** > **External Client App Manager**
3. Kliknij **New External Client App**
4. Wypełnij pola **External Client App Name** (np. `ElevenLabs Agents`), **API Name** i **Contact Email**
5. W sekcji **API (Enable OAuth Settings)**:
   * Zaznacz **Enable OAuth** i **Enable Client Credentials Flow**
   * **Callback URL**: `https://api.elevenlabs.io/oauth/callback`
   * **OAuth Start URL**: `https://api.elevenlabs.io/oauth/start`
   * **Selected OAuth Scopes**: dodaj te zakresy:
     * **Full access (full)**
     * **Perform requests on your behalf at any time (refresh_token, offline_access)**
     * **Manage user data via api**
6. Kliknij **Create**
7. Na stronie aplikacji otwórz kartę **Settings**, przejdź do **OAuth Settings** i kliknij **Consumer Key and Secret**
8. Skopiuj **Consumer Key** i **Consumer Secret** — będą potrzebne do uwierzytelniania

#### Skonfiguruj OAuth Client Credentials flow

> **Warning**
>
> Client Credentials Flow jest zalecany w integracjach serwer-serwer, które nie wymagają interakcji
> użytkownika. Upewnij się, że administrator Salesforce włączył ten przepływ.

1. W External Client App kliknij **Edit**
2. Zaznacz **Enable Client Credentials Flow** — pojawi się pole **Run As**
3. W polu **Run As** ustaw konto administratora lub dedykowane konto usługi — określa ono uprawnienia do wszystkich wywołań API
4. W polu **Permitted Users** ustaw **Admin approved users are pre-authorized**
5. Kliknij **Save**

Użytkownik **Run As** określa uprawnienia do wszystkich wywołań API. Wybierz użytkownika z profilem System Administrator lub profilem niestandardowym, który ma dostęp do API i uprawnienia do obiektów potrzebnych agentowi (Contact, Lead, Account itd.). W rekordzie użytkownika musi być zaznaczone uprawnienie **API Enabled**.

#### Znajdź swoją domenę Salesforce

Domena Salesforce jest wymagana do wywołań API.

**Metoda 1: Sprawdź obecny adres URL**

Po zalogowaniu do Salesforce sprawdź pasek adresu w przeglądarce:

* **Lightning Experience**: `https://acme.lightning.force.com/`
* **My Domain**: `https://acme.my.salesforce.com/`

**Metoda 2: Setup > Company Information**

Przejdź do **Setup** > **Company Information** i znajdź adres URL **My Domain** lub informacje o organizacji.

**Metoda 3: Setup > Domain Management**

Przejdź do **Setup** > **Domain Management** > **My Domain**. Domena będzie widoczna u góry strony.

**Popularne formaty domen:**

* `https://acme.my.salesforce.com` (My Domain)
* `https://acme.lightning.force.com` (Lightning)
* `https://acme.develop.my.salesforce.com` (Sandbox)

> **Note**
>
> Użyj pełnej domeny bez końcowego ukośnika.

#### Połącz w ElevenLabs

W ustawieniach integracji ElevenLabs wpisz **nazwę hosta instancji** Salesforce (np. `acme.my.salesforce.com`), **Client ID** (Consumer Key) i **Client Secret** (Consumer Secret).

## Film demonstracyjny

> **Note**
>
> Ta prezentacja używa starszych narzędzi webhook. Jeśli używasz natywnej integracji Salesforce, narzędzia
> konfigurują się automatycznie — ręczne ustawianie webhooków nie jest potrzebne.

## Jak to działa

#### Przegląd

#### Pierwsze zapytanie klienta

Agent zbiera informacje o kliencie i zadaje odpowiednie pytania, aby poznać jego potrzeby biznesowe i obecne wyzwania.

#### Wyszukiwanie danych klienta

Agent sprawdza istniejące rekordy za pomocą `salesforce_search_records`, aby znaleźć kontakty, konta lub leady. Pobiera pełne dane przez `salesforce_get_record` i wykorzystuje je do personalizacji rozmowy.

#### Kwalifikacja leada

Jeśli klient jest nowy, agent zbiera dane kontaktowe, ocenia potrzeby biznesowe i określa odpowiedni proces sprzedaży lub przekierowanie.

#### Tworzenie rekordu

Agent tworzy odpowiedni rekord (lead, kontakt lub szansę) za pomocą `salesforce_create_record`, potwierdza jego utworzenie klientowi i wyjaśnia kolejne kroki.

#### Szczegółowy prompt systemowy

```text
# Personality

You are a helpful sales assistant responsible for managing customer relationships and creating records in Salesforce using the available tools. Be friendly, professional, and consultative in your approach.

# Environment

You operate in a sales setting via voice or chat interface, where you engage with potential customers to gather information, check for existing CRM data, and create Salesforce records when necessary.

# Tone

Begin by asking about the customer's business needs and current challenges.

Then, ask relevant qualification questions to understand their requirements, one question at a time, and wait for their response before proceeding.

Once you have basic information about the customer, say you will check for any existing records in the system.

Use any existing information to personalize the conversation and avoid asking for data you already have.

When discussing opportunities, always reference them by name (e.g., "Q1 Enterprise Deal") rather than by ID.

# Goal

After checking existing records, qualify the customer by gathering:
- Company name and size
- Industry and business type
- Current challenges and pain points
- Budget and timeline information
- Decision-making authority

Once you have qualified the customer, gather the following contact details:
- Full name and job title
- Business email address (ensure it's formatted correctly)
- Phone number
- Company name and address

Read the email back to the customer to confirm accuracy.

Once all information is confirmed, explain that you will create a record in our system.

Create the appropriate record (Lead, Contact, or Opportunity) using the `salesforce_create_record` tool.

Thank the customer and explain the next steps in the sales process.

# Guardrails

- Always check for existing records before creating new ones.
- If the customer asks to proceed, do so with the existing information.
- Qualify leads appropriately based on their responses.
- Do not discuss topics outside of business solutions and sales.
- Always maintain professional communication.
- Protect customer privacy and handle data securely.

# Tools

- Call `salesforce_search_records` to look for existing contacts, accounts, or leads (always include Name fields and human-readable information in your SOQL queries).
- If found, call `salesforce_get_record` to get detailed information about the existing record.
- Use `salesforce_create_record` to generate Leads, Contacts, or Opportunities after qualification.
```

> **Tip**
>
> Autoryzacją narzędzi można zarządzać przez Workplace Auth Connections, które automatycznie odświeżają tokeny.
> Narzędzia zwracają czytelne dla człowieka nazwy i opisy zamiast technicznych identyfikatorów, aby
> poprawić jakość rozmów.

## Konfiguracja narzędzi

Dostępne są trzy narzędzia webhook: `salesforce_search_records`, `salesforce_get_record` i `salesforce_create_record`. Skonfiguruj autoryzację każdego z nich za pomocą Workplace Auth Connection.

### Autoryzacja — połączenie Workplace OAuth2

#### Przejdź do Workplace Auth Connections

W panelu ElevenLabs przejdź do **Agents** > **Workplace Auth Connections** i kliknij **Add Auth**.

#### Skonfiguruj połączenie Salesforce

Wypełnij poniższe pola dla integracji Salesforce:

**Connection Name**: `Salesforce CRM`

**Client ID**

* Twój Consumer Key z External Client App
* Przykład: `3MVG9JJlvRU3L4pRiOu8pQt5xXB4xGZGm0yW...`

**Client Secret**

* Twój Consumer Secret z External Client App
* Przykład: `1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF...`

**Token URL**

* Punkt końcowy tokenu OAuth w domenie Salesforce
* Format: `https://{domain}.my.salesforce.com/services/oauth2/token`
* Przykład: `https://acme.my.salesforce.com/services/oauth2/token`

**Scopes (optional)**

* Zakresy OAuth dostępu do Salesforce API
* Zalecane: `full, api, refresh_token`
* Pozostaw puste, aby użyć domyślnych zakresów z External Client App

**Extra Parameters (JSON)**

* Dodatkowe parametry OAuth dla twojej konfiguracji
* Przykład dla Client Credentials flow:

```json
{
  "grant_type": "client_credentials"
}
```

#### Utwórz połączenie autoryzacji

Kliknij **Create auth connection**, aby dodać konfigurację.

#### Użyj w konfiguracji narzędzi

Gdy połączenie będzie działać, zapisz je i wskaż w konfiguracji narzędzi webhook w sekcji **Authentication**.

> **Tip**
>
> Workplace Auth Connections automatycznie odświeżają tokeny, więc nie musisz zarządzać nimi ręcznie.

### Konfiguracje narzędzi webhook

Dodaj Workplace Auth Connection (OAuth2) do każdego narzędzia w sekcji **Authentication**. Skorzystaj z poniższych kart, aby sprawdzić konfigurację każdego narzędzia.

#### salesforce_search_records

**Nazwa:** salesforce_search_records
**Opis:** Wyszukuje istniejące rekordy w Salesforce za pomocą zapytań SOQL. Zawsze zwraca czytelne dla człowieka informacje, w tym nazwy, a nie tylko identyfikatory.
**Metoda:** GET
**URL:** `https://acme.my.salesforce.com/services/data/v58.0/query/?q={soql_query}`

**Nagłówki:**

* **Content-Type:** `application/json`

**Parametry zapytania:**

* **q:** Ciąg zapytania SOQL (np. "SELECT Id, Name, Email FROM Contact WHERE Email = '[example@email.com](mailto:example@email.com)'")

**JSON narzędzia:**

```json
{
  "type": "webhook",
  "name": "salesforce_search_records",
  "description": "Searches for existing records in Salesforce using SOQL queries. Always returns human-readable names and details, not just IDs.",
  "api_schema": {
    "url": "https://acme.my.salesforce.com/services/data/v58.0/query/",
    "method": "GET",
    "path_params_schema": [],
    "query_params_schema": [
      {
        "id": "q",
        "type": "string",
        "description": "SOQL query string to search for records. Always include Name fields and other human-readable information. Example: SELECT Id, Name, Email, Phone, Company FROM Contact WHERE Email = 'customer@example.com'. For Opportunities, include: SELECT Id, Name, StageName, Amount, CloseDate, Account.Name FROM Opportunity",
        "dynamic_variable": "",
        "constant_value": "",
        "required": true,
        "value_type": "llm_prompt"
      }
    ],
    "request_body_schema": null,
    "request_headers": [
      {
        "type": "value",
        "name": "Content-Type",
        "value": "application/json"
      }
    ]
  },
  "response_timeout_secs": 30,
  "dynamic_variables": {
    "dynamic_variable_placeholders": {}
  }
}
```

#### salesforce_get_record

**Nazwa:** salesforce_get_record
**Opis:** Pobiera szczegółowe informacje o konkretnym rekordzie Salesforce.
**Metoda:** GET
**URL:** `https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/{record_id}`

**Nagłówki:**

* **Content-Type:** `application/json`

**Parametry ścieżki:**

* **object_type:** Typ obiektu Salesforce (Contact, Lead, Account itd.)
* **record_id:** Unikalny identyfikator rekordu Salesforce

**JSON narzędzia:**

```json
{
  "type": "webhook",
  "name": "salesforce_get_record",
  "description": "Retrieves detailed information about a specific Salesforce record.",
  "api_schema": {
    "url": "https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/{record_id}",
    "method": "GET",
    "path_params_schema": [
      {
        "id": "object_type",
        "type": "string",
        "description": "The Salesforce object type (Contact, Lead, Account, Opportunity, etc.)",
        "dynamic_variable": "",
        "constant_value": "",
        "required": true,
        "value_type": "llm_prompt"
      },
      {
        "id": "record_id",
        "type": "string",
        "description": "The unique Salesforce record ID obtained from search results",
        "dynamic_variable": "",
        "constant_value": "",
        "required": true,
        "value_type": "llm_prompt"
      }
    ],
    "query_params_schema": [],
    "request_body_schema": null,
    "request_headers": [
      {
        "type": "value",
        "name": "Content-Type",
        "value": "application/json"
      }
    ]
  },
  "response_timeout_secs": 30,
  "dynamic_variables": {
    "dynamic_variable_placeholders": {}
  }
}
```

#### salesforce_create_record

**Nazwa:** salesforce_create_record
**Opis:** Tworzy nowy rekord w Salesforce.
**Metoda:** POST
**URL:** `https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/`

**Nagłówki:**

* **Content-Type:** `application/json`

**Parametry ścieżki:**

* **object_type:** Typ obiektu Salesforce do utworzenia (Lead, Contact, Account itd.)

**Parametry treści:**

* **Dynamiczny obiekt JSON** zawierający pola i wartości rekordu

**JSON narzędzia:**

```json
{
  "type": "webhook",
  "name": "salesforce_create_record",
  "description": "Creates a new record in Salesforce (Lead, Contact, Account, Opportunity, etc.)",
  "api_schema": {
    "url": "https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/",
    "method": "POST",
    "path_params_schema": [
      {
        "id": "object_type",
        "type": "string",
        "description": "The Salesforce object type to create (Lead, Contact, Account, Opportunity, etc.)",
        "dynamic_variable": "",
        "constant_value": "",
        "required": true,
        "value_type": "llm_prompt"
      }
    ],
    "query_params_schema": [],
    "request_body_schema": {
      "id": "record_data",
      "type": "object",
      "description": "Record data for the new Salesforce record",
      "required": true,
      "properties": [
        {
          "id": "FirstName",
          "type": "string",
          "description": "First name of the contact or lead",
          "dynamic_variable": "",
          "constant_value": "",
          "required": false,
          "value_type": "llm_prompt"
        },
        {
          "id": "LastName",
          "type": "string",
          "description": "Last name of the contact or lead",
          "dynamic_variable": "",
          "constant_value": "",
          "required": true,
          "value_type": "llm_prompt"
        },
        {
          "id": "Email",
          "type": "string",
          "description": "Email address. Must be properly formatted: user@domain.com",
          "dynamic_variable": "",
          "constant_value": "",
          "required": true,
          "value_type": "llm_prompt"
        },
        {
          "id": "Phone",
          "type": "string",
          "description": "Phone number of the contact or lead",
          "dynamic_variable": "",
          "constant_value": "",
          "required": false,
          "value_type": "llm_prompt"
        },
        {
          "id": "Company",
          "type": "string",
          "description": "Company name (required for Lead object)",
          "dynamic_variable": "",
          "constant_value": "",
          "required": false,
          "value_type": "llm_prompt"
        },
        {
          "id": "Title",
          "type": "string",
          "description": "Job title of the contact or lead",
          "dynamic_variable": "",
          "constant_value": "",
          "required": false,
          "value_type": "llm_prompt"
        },
        {
          "id": "Industry",
          "type": "string",
          "description": "Industry of the lead's company",
          "dynamic_variable": "",
          "constant_value": "",
          "required": false,
          "value_type": "llm_prompt"
        },
        {
          "id": "Description",
          "type": "string",
          "description": "Additional notes or description about the lead/contact",
          "dynamic_variable": "",
          "constant_value": "",
          "required": false,
          "value_type": "llm_prompt"
        }
      ]
    },
    "request_headers": [
      {
        "type": "value",
        "name": "Content-Type",
        "value": "application/json"
      }
    ]
  },
  "response_timeout_secs": 30,
  "dynamic_variables": {
    "dynamic_variable_placeholders": {}
  }
}
```

## Popularne obiekty Salesforce

| Obiekt          | Cel                                                             | Popularne pola                                               |
| --------------- | --------------------------------------------------------------- | ------------------------------------------------------------ |
| **Lead**        | Potencjalni klienci, którzy nie zostali jeszcze zakwalifikowani | FirstName, LastName, Email, Phone, Company, Industry, Status |
| **Contact**     | Zakwalifikowane osoby powiązane z kontami                       | FirstName, LastName, Email, Phone, AccountId, Title          |
| **Account**     | Organizacje lub firmy                                           | Name, Type, Industry, Phone, BillingAddress                  |
| **Opportunity** | Trwające transakcje sprzedażowe                                 | Name, StageName, Amount, CloseDate, AccountId                |
| **Case**        | Zgłoszenia do obsługi klienta                                   | Subject, Description, Status, Priority, ContactId            |

## Typowe zapytania SOQL

Użyj tych zapytań SOQL jako punktu wyjścia przy dostosowywaniu promptu systemowego agenta. Wszystkie zapytania zwracają informacje czytelne dla człowieka, a nie techniczne identyfikatory:

### Wyszukiwanie kontaktów po adresie e-mail

```sql
SELECT Id, Name, Email, Phone, Title, Account.Name, Account.Type FROM Contact WHERE Email = 'customer@example.com'
```

### Wyszukiwanie leadów po adresie e-mail lub numerze telefonu

```sql
SELECT Id, Name, Email, Phone, Company, Industry, Status, LeadSource, Title FROM Lead WHERE Email = 'customer@example.com' OR Phone = '+1234567890'
```

### Wyszukiwanie kont po nazwie

```sql
SELECT Id, Name, Type, Industry, Phone, BillingCity, BillingState, Website FROM Account WHERE Name LIKE '%Company Name%'
```

### Wyszukiwanie ostatnich szans sprzedaży

```sql
SELECT Id, Name, StageName, Amount, CloseDate, Account.Name, Account.Type, Owner.Name, Description FROM Opportunity WHERE CreatedDate = THIS_MONTH
```

### Wyszukiwanie szans sprzedaży według konta

```sql
SELECT Id, Name, StageName, Amount, CloseDate, Probability, NextStep, Owner.Name FROM Opportunity WHERE Account.Name LIKE '%Company Name%'
```

## Testowanie integracji

Po skonfigurowaniu External Client App i połączeniu integracji przetestuj ją przed wdrożeniem na produkcji:

1. **Wyszukiwanie**: Poproś agenta o wyszukanie istniejących kontaktów.
2. **Tworzenie rekordów**: Niech agent utworzy nowego leada lub kontakt.
3. **Pobieranie danych**: Sprawdź, czy agent może pobierać szczegółowe informacje o kliencie.

## Wyzwalacz komentarza do sprawy: odpowiedzi e-mail dla Email-to-Case

Jeśli włączono wyzwalacz **Salesforce Case Comment** (automatyczną odpowiedź agenta na sprawy Service Cloud), odpowiedzi na sprawy z co najmniej jedną przychodzącą wiadomością e-mail są wysyłane do klienta jako prawdziwe wiadomości e-mail w tym samym wątku — a nie tylko jako wewnętrzny komentarz do sprawy. Zależy to od tego, czy sprawa ma przychodzącą wiadomość e-mail, a nie od wartości listy wyboru **Origin** sprawy. Dlatego działa poprawnie również wtedy, gdy organizacja używa własnej wartości Origin, takiej jak „Email - Returns”, zamiast dosłownego „Email”. Sprawy bez przychodzącej wiadomości e-mail nadal są publikowane jako publiczny komentarz do sprawy, bez zmian. Wszystkie adresy dodane do DW w oryginalnej wiadomości klienta są też automatycznie dodawane do DW odpowiedzi, tak jak przy opcji „Odpowiedz wszystkim” użytej przez ludzkiego agenta — z wyjątkiem adresów routingu Email-to-Case organizacji, które są celowo wykluczone z DW, aby odpowiedź nie została ponownie pobrana przez Email-to-Case i nie uruchomiła agenta na jego własnej wiadomości.

Wysyłanie odpowiedzi e-mail wymaga dodatkowej konfiguracji poza tą potrzebną tylko do komentarzy do spraw:

* Profil lub Permission Set użytkownika **Run As** musi mieć włączone uprawnienie systemowe **Send Email** (`Setup` > `Users` > `Profiles`, w sekcji System Permissions), oprócz uprawnienia **API Enabled**, które jest już wymagane przez integrację.
* Ustawienie **Email Deliverability** organizacji (`Setup` > `Email` > `Deliverability`) musi zezwalać na zewnętrzną pocztę e-mail — środowiska Sandbox mają domyślnie ograniczone ustawienie, które po cichu blokuje wychodzącą pocztę.
* Jeśli odpowiedzi mają być wysyłane z aliasu wsparcia zamiast z własnej skrzynki użytkownika Run As, ustaw w wyzwalaczu pole **Org-Wide Email Address Id** na Id **Organization-Wide Email Address** (`Setup` > `Organization-Wide Addresses` > kliknij adres > skopiuj Id z URL). Pozostaw je puste, aby wysyłać z własnego adresu użytkownika Run As.
* Ustaw w wyzwalaczu pole **Email-to-Case Routing Address(es)** na adresy Email-to-Case organizacji (oddzielone przecinkami, jeśli jest ich więcej niż jeden, `Setup` > `Email-to-Case`). Bez tego integracja próbuje odgadnąć adres routingu na podstawie wiadomości klienta (jej adresu `To`), co nie uwzględnia przypadków, w których adres routingu był dodany tylko do DW, a nie był głównym odbiorcą — dodanie go ponownie do DW w odpowiedzi w takiej sytuacji uruchomiłoby agenta na jego własnej wiadomości.

Jeśli organizacja klienta nie ma tego skonfigurowanego, błąd wysyłania e-maila powoduje publikację publicznego komentarza do sprawy, więc odpowiedź nigdy nie zniknie bez śladu — ale klient nie otrzyma jej e-mailem, dopóki powyższe ustawienia nie zostaną skonfigurowane.

## Kwestie bezpieczeństwa

* Używaj endpointów HTTPS dla wszystkich wywołań API.
* Upewnij się, że w Salesforce skonfigurowano odpowiednie zabezpieczenia na poziomie pól.
* Uprawnienia użytkownika Run As określają, do jakich danych ma dostęp integracja — odpowiednio je ogranicz.
* Regularnie audytuj dostęp do API i jego użycie.

## Przydatne linki

* [Dokumentacja Salesforce REST API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/)
* [Dokumentacja języka zapytań SOQL](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/)
* [External Client Apps i OAuth 2.0](https://help.salesforce.com/s/articleView?id=sf.connected_app_overview.htm)
* [Najlepsze praktyki bezpieczeństwa Salesforce](https://help.salesforce.com/s/articleView?id=sf.security_overview.htm)