Messaging Channel Integration
What This Page Covers
This is a horizontal integration pattern, not a connector for any one product. It explains:
- How a customer-built Flow turns inbound messages from any messaging system into REDA AI conversations
- How a custom outbound Apex tool lets the agent send replies back through that same system
- How to configure the agent so it understands it’s talking through a messaging channel rather than the standard Salesforce UI
Specific connectors — for example REDA Connect for WhatsApp/SMS, or third-party gateways — ship as separate extension packages. Each one is built on top of the pattern described here.
The Two-Sided Bridge
Every messaging integration is two halves:
| Direction | What you build | What REDA AI gives you |
|---|---|---|
| Inbound — user’s message arrives in Salesforce | A record-triggered or platform-event-triggered Flow that fires when your messaging app stores the inbound message in Salesforce. | The Send Message to REDA AI Agent Flow invocable. The Flow calls it with the user’s text and a record context; the invocable returns the agent’s reply synchronously. |
| Outbound — agent’s reply leaves Salesforce | A custom Apex Class tool that knows how to post a message through your messaging system (REST, Platform Event, callout, or Salesforce DML on a messaging-app object). | The agent’s tool framework discovers the tool and invokes it during the conversation. You write the body of the executor; the platform handles invocation, validation and audit. |
Inbound: From Message to Agent
The invocable
REDA AI exposes an invocable Apex action that any Flow can call. It takes the user’s message, a record for context, and returns the agent’s reply.
| Input | Required | Purpose |
|---|---|---|
agentName | Yes | The Agent Id of the agent that should handle this message. |
recordId | Yes | A Salesforce record providing context (e.g. the messaging-app conversation record, the matched Contact, or the related business record). |
objectName | Yes | API name of the context record’s object. |
message | Yes | The user’s inbound text. |
conversationId | Optional | Pass the previous response’s conversationId to keep multi-turn context across messages. |
autoExecuteActions | Optional | When true, the agent’s pending actions are executed in the same call instead of waiting for a confirmation card. |
automatedSource | Optional | Free-text label (e.g. the Flow’s name) recorded on the conversation for audit. |
fileContentVersionId | Optional | A ContentVersion Id when the inbound message includes an attachment to be processed. |
createIncidentOnError | Optional | When true, errors raise an Incident Log record for monitoring. |
The invocable returns the agent’s reply synchronously:
| Output | Purpose |
|---|---|
success | Boolean — whether the call completed without errors. |
response | The agent’s reply text. This is what you send back to the user through your messaging system. |
conversationId | Pass back on the next inbound message to maintain multi-turn context. |
creditsUsed | Credits consumed by this turn. |
actionResultsJson | JSON results of any actions auto-executed in this turn. |
isAsync / asyncRequestId | For heavy work the platform may route processing to async. When isAsync is true, the final reply is delivered after polling the async request. |
errorMessage | Populated when success is false. |
Wiring the inbound Flow
-
Trigger on inbound event
Most messaging integrations store inbound messages as Salesforce records (or publish a Platform Event). A record-triggered Flow on that object — or a platform-event Flow on that event — is the entry point.
-
Resolve context record
Decide which Salesforce record represents the conversation: the messaging-app record itself, the matched Contact/Lead, or a related business record (Case, Opportunity, etc.). Pass its Id and object name to the invocable.
-
Look up conversation
Store the
conversationIdreturned from the previous call on a field of the conversation record (or the contact). On every inbound message, retrieve and pass it back so REDA AI keeps the multi-turn context. -
Call the invocable
The invocable runs synchronously. The Flow waits for the agent’s reply.
-
Send reply
Take
responsefrom the invocable’s output and post it back through your messaging system — usually by inserting an outbound-message record, raising an outbound Platform Event, or calling out to your provider. -
Persist the new
conversationIdStore the latest
conversationIdon the conversation record so the next inbound message continues the same thread.
Outbound: From Agent to User
For agent-initiated messages — nudges, follow-ups, broadcasts, action-driven replies — build an Apex Class tool that posts to your messaging system. The agent uses it like any other tool.
What the tool needs
- A clear Description — this is how the agent decides when to use it. State explicitly that it sends a message through your channel and what kinds of message are appropriate.
- An Input Schema covering the destination identifier (phone, channel ID, conversation Id) and the message body, plus any options your provider supports (template name, locale, attachment ID).
- A Category of
Action. Outbound messages are side-effecting, so the agent will surface a confirmation card by default. - Channels that include the channel the agent runs on — a tool outside the conversation's channel never loads.
Inside the executor
The class implements the standard tool executor interface and does whatever it needs to dispatch the message:
- HTTP callout to the messaging provider’s API directly, or
- DML on the messaging app’s outbound-message object, or
- Publishing a Platform Event the messaging app subscribes to.
Return a Map<String, Object> with success, message, and the provider’s message Id when available. See Apex Class Tools for the full executor contract.
Configuring the Agent
Two settings on the Agent Definition matter for messaging integrations:
- Channel — set to
API. This tells the platform the agent is being driven by Flow rather than a UI session, and it controls which tools and prompts are loaded for the agent. - Auto Execute Actions — consider enabling. Confirmation cards don’t exist on a messaging channel; either let the agent execute non-destructive actions on its own, or constrain the toolset to read-only and outbound-message tools.
Tools — including the outbound message tool you built — need to be assigned to the agent and have API in their channel scope. See Configuring Agent Settings for full agent configuration.
Files & Attachments
When an inbound message includes an attachment, store it as a ContentVersion on the conversation record (or any record the user can read), then pass its Id as fileContentVersionId to the invocable. The agent will process the file using the same machinery as any other channel — see Document Processing.
Outbound attachments depend on the messaging provider. Most providers accept a public URL or a media Id; in the outbound tool’s executor, generate a short-lived ContentDistribution URL or upload the file to the provider before sending.
Async Replies
For most messaging conversations the synchronous response is fine — the user’s message arrives, the Flow waits, the agent replies in seconds. For heavy file processing or long agentic chains, the platform may set isAsync to true and return immediately with an asyncRequestId.
When that happens, the integration has two options:
- Send a typing-indicator message immediately, then watch the async request and post the final reply when it completes.
- Treat the async result as a separate outbound message: a record-triggered Flow on the async-request object, fired when the request reaches its terminal status, posts the reply back to the user.
Security & Governance
- Pick the running user carefully. The Flow runs in some user context — usually the running user of the inbound trigger. That user’s permissions determine what tools can do and what data the agent sees. Use a dedicated integration user with a tight permission set when the messaging system handles many users.
- Outbound is your code. The platform doesn’t enforce sharing or FLS inside your outbound tool — declare the class
with sharingand validate destination identifiers (don’t let the model send to an arbitrary phone number without checks). - No external rate limiter applies to
API. The widget rate limiter runs on external/community traffic; Flow-driven invocations rely on Salesforce’s own governor limits and any throttling you build into your messaging system. Plan for bulk inbound traffic accordingly. - Credits are consumed per invocation. Each call to the invocable counts against the org’s monthly credits. If the org runs out, the call returns an error and the conversation should fall back to a static reply.
- Audit trail. Every invocation creates a Conversation and Message record;
automatedSourceon the input lets you tag conversations with the originating Flow name for filtering and reporting.
Best Practices
Persist the conversationId. Without it, every inbound message looks like the start of a new conversation and the agent loses memory mid-thread.
Map a real Salesforce record as context. The agent works much better when it knows who it’s talking to. The conversation record from your messaging app, the matched Contact, or a related business record all work — pick the one with the richest signal.
Use a dedicated agent for the channel. Don’t reuse the same agent across the internal Salesforce UI and a messaging channel. Different channels need different tone, prompts and toolsets.
Constrain the toolset. A messaging-channel agent typically needs read tools and one outbound-message tool. Resist the temptation to give it the full action toolset — you cannot show confirmation cards in a chat thread.
Handle errors gracefully. If success is false, post a friendly fallback reply (“I’m having trouble right now — please try again in a few minutes”) rather than the raw errorMessage.
Frequently Asked Questions
The core REDA AI package is messaging-system agnostic — it ships the Flow invocable and the tool framework, not a specific provider integration. Specific connectors are delivered as separate extension packages or are built by customers using the pattern on this page.
Set the agent’s Channel to API. The Flow invocable runs under that channel, and any tools you want the agent to use on this channel must include API in their channel scope.
The Channel setting is part of the agent’s context, and you control the persona, instructions and toolset. Build a dedicated agent for the channel with a prompt that spells out the conversational style and the constraints (no markdown tables, no long replies, no action confirmations).
No — confirmation cards are a UI feature. On a messaging channel either enable Auto Execute Actions on the agent so non-destructive actions run inline, or constrain the toolset to read-only tools plus the outbound-message tool. For destructive actions, route the user back to a Salesforce UI link instead of executing in the chat.
Store the attachment as a ContentVersion linked to the conversation record, then pass its Id as fileContentVersionId on the invocable. The agent processes it through the standard Document Processing pipeline.
The platform has handed processing to a background job because the work was too heavy to complete synchronously. The Flow gets an asyncRequestId; either send a holding message immediately and watch for completion, or wire a separate Flow that posts the final reply when the async request reaches its terminal status.
Technically yes — one API-channel agent can be invoked by Flows behind several messaging systems. In practice we recommend one agent per channel; voice, WhatsApp, email and SMS each need different tone, length and toolsets, and a focused agent is easier to govern.
Next Steps
Read Apex Class Tools for the executor contract you’ll implement on the outbound side, or Invoking REDA AI from Flows for more on the inbound invocable.