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

# Salesforce

> Install the Yotel for Salesforce managed package and push Contacts/Leads into Yotel campaigns from inside the CRM.

"Yotel for Salesforce" is our managed package on AppExchange. Once
installed, Salesforce users can push Contacts and Leads into a
running Yotel dialer campaign with a single click from the record
page.

<Info>
  The AppExchange listing is currently in security review. Until it's
  live, installs are via direct package URL (contact
  [support@yotel.in](mailto:support@yotel.in)).
</Info>

## What's in the package

| Component                    | What it does                                                       |
| ---------------------------- | ------------------------------------------------------------------ |
| Auth Provider                | OIDC client config — Salesforce runs the OAuth dance against Yotel |
| Named Credential `Yotel_API` | Apex reaches Yotel via `callout:Yotel_API/...` — no tokens in code |
| Permission Set `Yotel User`  | Assign to any user who'll use the integration                      |
| Apex classes                 | `YotelClient`, `Campaigns`, `Leads`, `Calls` — typed wrappers      |
| "Push to Yotel" LWC          | Quick action on Contact + Lead record pages                        |

## Install

### 1. Install the managed package

Click the install link from the AppExchange listing (or the direct
URL from support). Choose "Install for All Users" unless your
compliance policy requires gated access.

### 2. Register Yotel as a Connected App tenant

In the Yotel dashboard:

1. Settings → [Connected Apps](https://app.yotel.in/settings/connected-apps)
2. **Register client** → name: "My Salesforce Org"
3. Copy the generated `client_id` and `client_secret` — the secret is
   shown once

### 3. Configure the Auth Provider

In Salesforce:

1. Setup → Auth. Providers → **Yotel** → Edit
2. Replace `__YOTEL_CLIENT_ID__` with your `client_id`
3. Replace `__YOTEL_CLIENT_SECRET__` with your `client_secret`
4. Save

### 4. Authenticate the Named Credential

1. Setup → Named Credentials → **Yotel API**
2. Click **Authenticate**
3. Salesforce redirects to Yotel's `/oauth/authorize` consent screen
4. Review the scopes, click **Allow**
5. You're redirected back with a green "Authenticated" indicator

### 5. Assign the Permission Set

Setup → Permission Sets → **Yotel User** → Manage Assignments →
assign to all users who'll use the integration.

### 6. Add "Push to Yotel" to record pages

1. Navigate to a Contact → gear icon → **Edit Page** (Lightning App
   Builder)
2. Drag the **Push to Yotel** Lightning Web Component onto the page
3. Save and activate
4. Repeat for the Lead object

## Usage

On any Contact or Lead:

1. Select a running Yotel campaign from the dropdown
2. Click **Push to Yotel**
3. You'll see a toast with the Yotel `lead_id`

Yotel's dialer will pick up the lead in its next dial cycle (within
seconds for predictive campaigns, when the agent clicks Next for
preview campaigns).

Metadata attached to the Yotel lead:

```json theme={null}
{
  "source": "salesforce",
  "sfdc_id": "003xx000004EfGhIJK"
}
```

## Using Apex directly

For custom integrations — batch Apex, triggers, flows — call the
Apex wrappers yourself:

```apex theme={null}
// Push a Contact when a Salesforce Campaign member is added
trigger PushNewCampaignMembers on CampaignMember (after insert) {
    YotelClient client = new YotelClient();
    String yotelCampaignId = 'c-from-custom-settings';

    for (CampaignMember cm : Trigger.new) {
        if (cm.ContactId == null) continue;
        Leads.LeadInput input = new Leads.LeadInput();
        input.phone = [SELECT Phone FROM Contact WHERE Id = :cm.ContactId].Phone;
        input.metadata = new Map<String, Object>{
            'source' => 'sfdc_campaign',
            'sfdc_campaign_id' => cm.CampaignId
        };
        Leads.create(client, yotelCampaignId, input);
    }
}
```

See the [`sdks/salesforce`](https://github.com/kamal-zetta/dialer/tree/main/sdks/salesforce)
source for the full Apex API surface.

## Troubleshooting

**Auth Provider shows `invalid_client`:**

* You pasted the wrong `client_secret`, or the one whose secret was
  rotated. Register a new client in Connected Apps and retry.

**Named Credential stuck on "Authenticating…":**

* Your Salesforce org is likely on the "My Domain" URL that isn't
  whitelisted. Make sure the registered `redirect_uri` exactly matches
  what Salesforce emits (Setup → Auth. Providers → Yotel → "Callback
  URL" field).

**`callout:Yotel_API` returns 401:**

* Token expired and refresh failed. Re-authenticate the Named
  Credential. If this happens frequently, increase the refresh
  cadence on your side or contact support.

**"No running campaigns" in the LWC picker:**

* The LWC filters to `status == running`. Start a campaign from the
  Yotel dashboard first. Drafts and archived campaigns are
  intentionally hidden.

## Security notes

* Tokens are stored server-side in Salesforce's Named Credentials —
  never reach client devices, never appear in Apex source.
* The package uses `with sharing` on all classes, so record-level
  sharing rules apply.
* FLS hardening (`WITH USER_MODE` on SOQL) is planned for the next
  release when we bump to API 60+.
