You are here:
Add Custom Messaging Components to a Third-Party Messaging Channel
Customize the out-of-the-box Messaging surface so that an AI agent can render custom messaging components—such as forms—in legacy chat and third-party messaging channels, alongside the out-of-the-box response formats.
Required Editions
| View supported editions. | |
This article applies to:
|
Enhanced WhatsApp, Enhanced Facebook Messenger, Standard and Enhanced SMS, Enhanced Apple Messages for Business, Enhanced LINE, and Bring Your Own Channel |
This article doesn’t apply to:
|
Enhanced In-App Chat or Enhanced Web Chat channels |
Customize the out-of-the-box Messaging surface in Agentforce so that an AI agent can render custom
messaging components—such as forms—alongside the out-of-the-box response formats. You define a
custom AiSurface that replaces the file-based Messaging surface, preserve the
existing out-of-the-box response formats, and add a new AiResponseFormat entry for
each messaging component you want the agent to use.
When to Use Custom Messaging Components
Use custom messaging components when you serve customers through legacy Salesforce chat deployments or third-party messaging channels—such as WhatsApp, Apple Messages for Business, Facebook Messenger, or LINE—and you want the agent to return rich, interactive components.
The customizable Messaging surface preserves the out-of-the-box Messaging response formats
(MessagingChoices, MessagingChoicesWithImages,
MessagingRichLink, and MessagingTimePicker) and lets you
add new components on top of them.
Prerequisites
- Service Cloud messaging channel: Configure the appropriate Service Cloud messaging channel for legacy chat or your third-party channel before you set up the customizable messaging connection.
- Metadata API version: Use version 66.0 or later for retrieval and deployment.
- Existing agent: An Agentforce agent that uses the file-based messaging connection
(
SurfaceAction__Messaging). - Messaging component: A deployed messaging component (such as a form) whose ID or developer name you can reference in the response format.
How It Works
The default Messaging surface is delivered as a file-based surface
(SurfaceAction__Messaging) that ships with four out-of-the-box response formats.
To add a messaging component, replace the file-based surface with a customizable
AiSurface that references those same four response formats plus your new
custom format.
After deployment, the agent uses the out-of-the-box response formats for choices, rich links, and time pickers, and selects your custom format when its description and instructions match the customer’s request.
Set Up Custom Messaging Components
Organize your metadata files using this structure, and then complete the steps that follow.
metadataToDeploy/
├── package.xml
├── aiResponseFormats/
│ └── Messaging_Form_Messaging_Component.aiResponseFormat
├── aiSurfaces/
│ └── {CustomMessagingSurface}.aiSurface
└── genAiPlannerBundles/
└── {YourAgentDevName}.genAiPlannerBundleStep 1: Retrieve the Agent’s GenAiPlannerBundle
Retrieve your agent’s GenAiPlannerBundle through the Metadata API. Use this
package.xml for the retrieve.
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>*</members>
<name>GenAiPlannerBundle</name>
</types>
<version>66.0</version>
</Package>The retrieve returns the GenAiPlannerBundle for your agent.
metadataToDeploy/
└── genAiPlannerBundles/
└── {YourAgentDevName}.genAiPlannerBundleStep 2: Replace the File-Based Messaging Surface
In your GenAiPlannerBundle, find the plannerSurfaces entry
whose surface value is SurfaceAction__Messaging. Change
surface to a unique developer name for your customizable Messaging surface
(for example, CustomMessagingSurface). Leave surfaceType
set to Messaging.
<?xml version="1.0" encoding="UTF-8"?>
<GenAiPlannerBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<!-- Other agent configuration -->
<plannerSurfaces>
<adaptiveResponseAllowed>true</adaptiveResponseAllowed>
<callRecordingAllowed>false</callRecordingAllowed>
<surface>CustomMessagingSurface</surface>
<surfaceType>Messaging</surfaceType>
</plannerSurfaces>
</GenAiPlannerBundle>This change detaches the file-based Messaging surface and attaches your customizable Messaging surface in its place.
Step 3: Create the Customizable Messaging Surface
Create an aiSurfaces folder in your deployment bundle. Inside it, create a
file named {the_unique_dev_name_from_step_2}.aiSurface. The file’s developer
name must match the surface value you set in Step 2.
The customizable surface must include all four out-of-the-box Messaging response formats so that standard Messaging behavior continues to work.
<?xml version="1.0" encoding="UTF-8"?>
<AiSurface xmlns="http://soap.sforce.com/2006/04/metadata">
<description>Customizable Messaging connection</description>
<instructions>
<instruction>Do not use any of the SURFACE_ACTION__* response formats when none of the instructions below are met.</instruction>
<sortOrder>1</sortOrder>
</instructions>
<instructions>
<instruction>Do not use the below instructions when the response contains more than 10 choices.</instruction>
<sortOrder>2</sortOrder>
</instructions>
<instructions>
<instruction>Do not use any of the SURFACE_ACTION__Messaging* type formatting when the response contains only a single, text-only choice and does not include images or URLs.</instruction>
<sortOrder>3</sortOrder>
</instructions>
<masterLabel>Messaging</masterLabel>
<responseFormats>
<enabled>true</enabled>
<responseFormat>SurfaceAction__MessagingChoices</responseFormat>
</responseFormats>
<responseFormats>
<enabled>true</enabled>
<responseFormat>SurfaceAction__MessagingChoicesWithImages</responseFormat>
</responseFormats>
<responseFormats>
<enabled>true</enabled>
<responseFormat>SurfaceAction__MessagingRichLink</responseFormat>
</responseFormats>
<responseFormats>
<enabled>true</enabled>
<responseFormat>SurfaceAction__MessagingTimePicker</responseFormat>
</responseFormats>
<source>SurfaceAction__Messaging</source>
<surfaceType>Messaging</surfaceType>
</AiSurface>For each custom messaging component you want the agent to use, add a
responseFormats entry that references the developer name of your custom
AiResponseFormat.
<responseFormats>
<enabled>true</enabled>
<responseFormat>Messaging_Form_Messaging_Component</responseFormat>
</responseFormats>Step 4: Create the Custom AiResponseFormat
Create an aiResponseFormats folder. Inside it, create a file named
{FormatDevName}.aiResponseFormat for each custom messaging component.
This example defines a form messaging component. The input field references
a deployed messaging component by developer name (or ID) using the
MessageDefinition template schema. Set input_strategy to
use_template so that the
agent populates the template instead of generating raw JSON.
<?xml version="1.0" encoding="UTF-8"?>
<AiResponseFormat xmlns="http://soap.sforce.com/2006/04/metadata">
<description>A response action. Use this when the user wants to create a case. The user is presented with rich UI.</description>
<input>{"template":{"messageType":"FormMessage","id":"{{ uuid4() }}","form":{"formatType":"MessageDefinition","messageDefinitionNameOrId":"Create_Case_Form"}},"input_strategy":"use_template"}</input>
<instructions>
<instruction>Always use this response format to create a case.</instruction>
<sortOrder>1</sortOrder>
</instructions>
<masterLabel>Messaging Form Messaging Component</masterLabel>
</AiResponseFormat>Form Template Schema
Use this template schema for form messaging components. The input field on
the AiResponseFormat must be a single-line, JSON-encoded string. The
expanded version here is shown for readability only.
{
"template": {
"messageType": "FormMessage",
"id": "{{ uuid4() }}",
"form": {
"formatType": "MessageDefinition",
"messageDefinitionNameOrId": "Create_Case_Form"
}
},
"input_strategy": "use_template"
}| Field | Description |
|---|---|
template.messageType |
The messaging component type. Use FormMessage for form
components. |
template.id |
A unique identifier for the message. Use {{ uuid4() }} to
generate one at run time. |
template.form.formatType |
The reference type for the component. Use MessageDefinition to
reference a deployed messaging component. |
template.form.messageDefinitionNameOrId |
The ID or developer name of the deployed messaging component that the agent renders. Replace it with your component’s value. |
input_strategy |
Set to use_template so that the agent populates the template
instead of generating raw JSON. |
Step 5: Create the package.xml File
Create a package.xml file at the root of your deployment bundle that
declares all three metadata types.
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>*</members>
<name>AiResponseFormat</name>
</types>
<types>
<members>*</members>
<name>AiSurface</name>
</types>
<types>
<members>*</members>
<name>GenAiPlannerBundle</name>
</types>
<version>66.0</version>
</Package>Step 6: Deploy
Deploy the metadata with Salesforce CLI.
sf project deploy start --manifest metadataToDeploy/package.xmlYou can also deploy with your preferred Metadata API tool. If you deploy incrementally,
deploy AiResponseFormat entities before AiSurface entities,
because the surface references the response formats.



