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

# Salesforce Webhooks Apex Package

This runbook walks a **Salesforce administrator** through installing the allGood Webhooks package in your org. When you finish, your org will send Lead and Contact changes to allGood automatically.

It takes about 15 minutes.

## Prerequisites

You should have received from allGood:

* **The package files**
  * `allgood_sfdc_package__v<version>.zip` — use this for a **first-time install**.
  * `allgood_sfdc_package__v<version>__upgrade.zip` — use this if your org **has had a previous version** of allGood webhooks; it also removes obsolete components from the old version.
* **One or more Webhook URLs**\
  They look like `https://webhook.allgoodhq.app/abc123`.
* **Optionally, an API key for each webhook**

<Note>
  Not sure which package file to use? If allGood webhooks have ever been
  installed in this org, use the `__upgrade` file. Otherwise use the plain file.
</Note>

You will also need:

* **A Salesforce login** with the **System Administrator** profile
* **Permission to deploy metadata** and edit Custom Metadata

<Note>
  The package only adds new components (a configuration type, a few Apex
  classes, and triggers on Lead and Contact). It does not modify existing
  fields, layouts, or data.
</Note>

## Install the package

You can install with [Workbench](https://workbench.developerforce.com) (no extra software) or the Salesforce CLI. Workbench is the simplest for most admins.

<Steps>
  <Step id="log-in-to-workbench" title="Log in to Workbench">
    Go to **[https://workbench.developerforce.com](https://workbench.developerforce.com)**.

    Under **Environment**, choose **Production** (or **Sandbox** if installing into a sandbox), accept the terms, and log in with your admin credentials.
  </Step>

  <Step id="open-the-deploy-page" title="Open the Deploy page">
    In the Workbench menu, go to **migration** → **Deploy**.
  </Step>

  <Step id="choose-the-package-file" title="Choose the package file">
    Click **Choose File** and select the package file from "Prerequisites" — plain for a first-time install, `__upgrade` if a previous version was installed.
  </Step>

  <Step id="set-the-deployment-options" title="Set the deployment options">
    Check these options:

    * **Rollback On Error** — so a failure leaves your org untouched.
    * **Test Level**: `RunLocalTests` — required when deploying to Production.
    * **Ignore Warnings** — **only when deploying the `__upgrade` file**. Leave it unchecked for the plain first-time-install file.

    <Accordion title="Why the `__upgrade` file needs &#x22;Ignore Warnings&#x22;">
      The `__upgrade` file removes obsolete components left by older versions, and that cleanup list intentionally names components that may not be present in your org. Salesforce treats a "not found" deletion as a *warning*; without **Ignore Warnings**, that warning fails the whole deploy. Enabling it lets those skips pass while still deleting whatever obsolete components are present.

      Real problems still fail the deploy, and **Rollback On Error** keeps it all-or-nothing. The plain first-time-install file performs no deletions, so it does not need this option.
    </Accordion>
  </Step>

  <Step id="deploy-and-wait" title="Deploy and wait for success">
    Click **Next**, then **Deploy**.

    Wait for the status to show **Succeeded**. The package's automated tests run during the deployment and must pass — this is expected and takes a minute or two.
  </Step>
</Steps>

<Accordion title="Using the Salesforce CLI instead">
  If your team uses the Salesforce CLI, unzip the package and deploy the metadata folder. Add `--ignore-warnings` only for the `__upgrade` package:

  ```bash theme={null}
  # First-time install (plain package)
  sf project deploy start --metadata-dir <unzipped-plain-folder> \
    --test-level RunLocalTests --target-org <your-org>

  # Upgrade (removes obsolete components)
  sf project deploy start --metadata-dir <unzipped-upgrade-folder> \
    --test-level RunLocalTests --ignore-warnings --target-org <your-org>
  ```
</Accordion>

## Configure your webhooks

Each webhook is one **configuration record**. Create one per object you want to send (Lead, Contact, or both); you can also create several for the same object if allGood gave you more than one URL.

<Steps>
  <Step id="open-custom-metadata-types" title="Open Custom Metadata Types">
    In Salesforce, go to **Setup**, then search for and open **Custom Metadata Types**.
  </Step>

  <Step id="manage-configuration-records" title="Manage the configuration records">
    Next to **allGood Webhook Configuration**, click **Manage Records**.
  </Step>

  <Step id="create-a-configuration-record" title="Create a configuration record">
    Click **New** and fill in the fields:

    | Field                     | What to enter                                                              |
    | ------------------------- | -------------------------------------------------------------------------- |
    | **Label** / **Name**      | Any name you like, e.g. `Lead Webhook` (Name auto-fills)                   |
    | **Target SObject**        | `Lead` or `Contact`                                                        |
    | **Webhook URL**           | The full URL allGood gave you, e.g. `https://webhook.allgoodhq.app/abc123` |
    | **API Key**               | The API key allGood gave you (leave blank if none)                         |
    | **Update Trigger Fields** | Comma-separated field API names that should send an update (see below)     |
    | **Include Fields**        | Optional: comma-separated extra field API names to add to the payload      |
    | **Is Active**             | Check this to turn the webhook on                                          |
  </Step>

  <Step id="save-and-repeat" title="Save and repeat">
    Click **Save**. Repeat for each object / URL.
  </Step>
</Steps>

### About "Update Trigger Fields"

This controls which **edits** send a webhook. Only changes to the fields you list here trigger an update event — this avoids sending a webhook on every unrelated edit.

* Recommended for **Lead**: `Status, Email, Phone, Company`
* Recommended for **Contact**: `Email, Phone, LastName, Status`

<Warning>
  If you leave **Update Trigger Fields** blank, edits never send a webhook. New
  records (inserts) always send a webhook regardless of this field.
</Warning>

## Verify it works

<Steps>
  <Step id="check-is-active" title="Check the configuration is active">
    Make sure the configuration record you created has **Is Active** checked.
  </Step>

  <Step id="create-a-test-record" title="Create a test record">
    Create a new test **Lead** (or Contact). This should send an "insert" webhook.
  </Step>

  <Step id="edit-a-trigger-field" title="Edit a trigger field">
    Edit one of the **Update Trigger Fields** on that record (e.g. change the Lead's Status). This should send an "update" webhook.
  </Step>

  <Step id="confirm-the-events-arrived" title="Confirm the events arrived">
    Confirm with allGood that the events arrived, **or** check inside Salesforce:

    * **Setup** → **Apex Jobs** — you should see a recently completed `WebhookService` future job.
    * **Setup** → **Debug Logs** — enable logging for your user, repeat the test, and look for the outbound request and its HTTP response status.
  </Step>
</Steps>

## Reference

* **What is sent**\
  The record's standard fields (plus any **Include Fields** you list) as a JSON POST, with a `Metadata` section describing the event (object, insert vs. update, and the previous values on an update). The API key, if set, is sent as a bearer token.
* **Reliability**\
  Each event is delivered asynchronously and retried up to 3 times.
* **Security**\
  All traffic is HTTPS to allGood-owned domains, which are pre-approved by the package (Remote Site Settings). The API key is sent in the standard `Authorization` header.

## Turning it off

* **Pause one webhook**: uncheck **Is Active** on its configuration record.
* **Pause everything**: uncheck **Is Active** on all configuration records.
* **Full uninstall**: remove the Apex triggers (`LeadTrigger`, `ContactTrigger`), then the Apex classes and the configuration type, via Setup or a destructive deployment.

For anything else, contact [allGood support](mailto:support@allgoodhq.com).

## Troubleshooting

<AccordionGroup>
  <Accordion title="No webhook sent at all">
    Confirm a configuration record exists for that object and **Is Active** is
    checked.
  </Accordion>

  <Accordion title="Nothing happens on edits">
    The edited field isn't in **Update Trigger Fields**. Add it (or set the
    recommended list).
  </Accordion>

  <Accordion title="Insert works, update doesn't">
    **Update Trigger Fields** is blank — add the fields that should trigger
    updates.
  </Accordion>

  <Accordion title="allGood reports 401 / 403">
    The **API Key** is missing or wrong — re-enter the key allGood provided.
  </Accordion>

  <Accordion title="Error mentioning an unsupported URL or callout not allowed">
    The **Webhook URL** must be the exact allGood URL (it must begin with
    `https://webhook.allgoodhq.app`). Re-paste the URL allGood gave you.
  </Accordion>

  <Accordion title="Deploy failed with &#x22;No ApexClass named ... found&#x22; (or similar &#x22;not found&#x22;)">
    You deployed the `__upgrade` file without **Ignore Warnings** — re-deploy
    with it checked.
  </Accordion>

  <Accordion title="Deployment failed for another reason">
    Re-run with **Rollback On Error** checked; capture the error and send it to
    allGood support.
  </Accordion>
</AccordionGroup>
