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

# Send your first iMessage from Salesforce

> End-to-end walkthrough — open a Lead, send a message, watch the reply land back on the record.

A hands-on walkthrough that takes you from an installed package to a
verified round-trip iMessage in under ten minutes. Run this in a
sandbox or Developer Edition Org first.

## What You'll Do

* Send an outbound iMessage from a Lead record using the
  `chertConversation` Lightning component.
* Confirm the send wrote a `Chert_Message__c` row with the correct
  `Direction__c` and `Chert_Message_Id__c`.
* Receive a reply on the recipient device and watch it appear on the
  same record.

## Before You Begin

| Requirement                      | How to verify                                                                                                                                                        |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Sandbox or Developer Edition Org | A scratch org or partner Developer Edition works. Don't run this in production on day one.                                                                           |
| Package installed                | From Setup, enter **Installed Packages** (for 2GP) or check that Apex classes prefixed `Chert` exist. See [Install](/salesforce/onboard).                            |
| Tenant credentials configured    | `Chert_Tenant.Default` Custom Metadata holds non-empty `Tenant_Slug__c`, `Signing_Secret__c`, and `Ingest_Token__c`. See [Configuration](/salesforce/configuration). |
| Permission Set assigned          | The user running the tutorial holds **Chert Messaging User**.                                                                                                        |
| Lead Record Page activated       | `Lead_Record_Page_Chert` is the active record page for your profile.                                                                                                 |
| Recipient device                 | A phone or Mac you can read iMessage on. iMessage must be enabled on that device.                                                                                    |

<Note>
  Outbound calls leave Salesforce and hit the live Chert messaging
  service. The send is real. Use a phone number you control as the
  recipient.
</Note>

## Step 1: Open a Test Lead

<Steps>
  <Step title="Open any Lead record">
    From the App Launcher, open **Sales**, click **Leads**, and pick a
    Lead. If your sandbox is empty, click **New** and create one named
    `Tutorial Lead` with a recipient mobile number you control.
  </Step>

  <Step title="Confirm MobilePhone is set in E.164 format">
    The component reads `Lead.MobilePhone`. Set it to the recipient's
    number in E.164 format — for example, `+14155551234`. If
    `MobilePhone` is empty, paste the number into the field and save.
  </Step>

  <Step title="Locate the Chert Conversation pane">
    Scroll the right rail. The **Chert Conversation** Lightning
    component appears with an empty thread and a message composer at
    the bottom. If it's missing, the Lead Record Page is not active
    for your profile — see [Configuration](/salesforce/configuration#lightning-record-pages).
  </Step>
</Steps>

## Step 2: Send Your First Message

<Steps>
  <Step title="Type a short test message">
    Use something obvious so you can spot it on the recipient device,
    e.g. `Tutorial test from Salesforce`.
  </Step>

  <Step title="Click Send">
    The component disables the composer for the duration of the
    callout. On success, the message renders in the conversation
    thread with a timestamp and an outbound chevron.
  </Step>

  <Step title="Inspect the response">
    `chertConversation` calls `ChertSendIMessage` under the hood. The
    invocable returns `messageId` and `duplicate`. The message ID is
    persisted to `Chert_Message__c.Chert_Message_Id__c` on the row
    inserted in the next step.
  </Step>
</Steps>

<Tip>
  If Send returns an error, open Setup → **Apex Jobs** and the
  **Debug Logs** for your user. Most first-send failures trace to a
  missing or stale `Signing_Secret__c` value.
</Tip>

## Step 3: Verify in Salesforce

<Steps>
  <Step title="Open the Chert Messages related list">
    From the Lead record, scroll to the **Chert Messages** related
    list. A new `Chert_Message__c` row appears.
  </Step>

  <Step title="Confirm the field values">
    Click into the row. You should see:

    | Field                 | Expected value                                                            |
    | --------------------- | ------------------------------------------------------------------------- |
    | `Direction__c`        | `outbound`                                                                |
    | `Text__c`             | The message body you typed                                                |
    | `Sent_At__c`          | A timestamp within the last few seconds                                   |
    | `Chert_Message_Id__c` | A non-empty Chert-side message ID                                         |
    | `Delivered__c`        | `false` initially; flips to `true` once the recipient device acknowledges |
  </Step>

  <Step title="Cross-reference Setup Audit Trail">
    Optional but recommended in a regulated Org. From Setup, enter
    **Setup Audit Trail**. The send is not itself an audited Setup
    event, but Permission Set assignments and metadata changes from
    install are visible here.
  </Step>
</Steps>

## Step 4: Receive a Reply

<Steps>
  <Step title="Reply from the recipient device">
    On the iMessage thread on your phone or Mac, send a short reply
    back to the Chert phone line — for example, `got it`.
  </Step>

  <Step title="Wait for the inbound POST">
    Chert posts the reply to your Org's `ChertInboundRest` resource.
    Delivery is typically under five seconds.
  </Step>

  <Step title="Refresh the Lead record">
    The conversation pane updates on next load. The `Chert Messages`
    related list shows a new row with `Direction__c = inbound` and
    `Text__c` matching what the recipient sent.
  </Step>

  <Step title="Confirm the dedup behavior">
    If the same inbound message replays (Chert retries on 5xx), the
    second POST is detected by `Chert_Message_Id__c` uniqueness and
    is treated as a no-op. No duplicate row.
  </Step>
</Steps>

## Verify Yourself

Answer these to confirm you've internalized the round-trip. The
answers are linked into the reference docs.

1. **Which Apex action does `chertConversation` invoke to send a
   message?** ([Configuration](/salesforce/configuration#wiring-chertsendimessage-into-a-flow))
2. **Which custom object stores the per-message audit row, and what
   field captures the Chert-side message ID?**
   ([Architecture](/salesforce/architecture))
3. **Where is the HMAC signing secret stored, and which Apex class
   reads it at send time?** ([Security](/salesforce/security))
4. **What's the dedup window for an `idempotencyKey`, and what
   `duplicate` value should Flow logic treat as success?**
   ([Limits and Considerations](/salesforce/limits#idempotency))
5. **Which Permission Set must a user hold to send through
   `ChertSendIMessage`, and what object grants does it carry?**
   ([Configuration](/salesforce/configuration#permission-set--chert-messaging-user))

## Next

<CardGroup cols={3}>
  <Card title="Architecture" icon="diagram-project" href="/salesforce/architecture">
    Component map and the synchronous-versus-asynchronous call graph.
  </Card>

  <Card title="Security" icon="shield" href="/salesforce/security">
    Trust boundary, HMAC signature format, and inbound verification.
  </Card>

  <Card title="Limits and Considerations" icon="gauge-high" href="/salesforce/limits">
    Governor math, edition fit, and platform-feature compatibility.
  </Card>
</CardGroup>
