Air-Gapped Support Integration: Intercom to Salesforce via MuleSoft
Security policies didn't allow Intercom to be integrated directly with the Salesforce CRM. Support chat was already running but cases were not, because those were managed in Salesforce Service Cloud, which wasn't connected to Intercom.
So, we decided to add MuleSoft between them as an authenticated proxy. It polls Intercom every 30 minutes, reshapes the data with DataWeave, and writes Salesforce cases keyed on the Intercom Conversation ID. One long chat becomes one case instead of ten.
Executive Summary
Context
An enterprise architecture review board treats a direct API connection from an external chat platform to the Salesforce production instance as an unacceptable exposure. That constraint decides the design more than the data mapping does. A middleware proxy satisfies it, and the batch interval becomes a rate-limit decision rather than a latency compromise.
What We Built
An integration brief specifying MuleSoft as an authenticated middleware proxy. A Mule App Scheduler polls Intercom's Search for Conversations endpoint every 30 minutes. DataWeave flattens nested conversation JSON into Salesforce Case objects, and Anypoint Connectors handle both ends. Conversation ID is the key that stops duplicates.
Tech Stack
- MuleSoft
- Anypoint Connectors
- DataWeave
- Mule App Scheduler
- Intercom
- Salesforce Service Cloud
- Connected App
Teams who can point a chat platform straight at their CRM. If no architecture review stands between the two systems, a native connector is cheaper than a middleware tier.
The Challenge
Enterprise security forbade a direct API connection between Intercom and the Salesforce production instance. The review board's position was blunt: the CRM does not get exposed to an external custom application. That ruled out the obvious build and it ruled out a point-to-point connector.
Support was running two distinct conversation shapes through one inbox. A chatbot handled some conversations end to end. Others escalated to a live agent partway through. Both had to become cases, owned by different parties, without a human deciding which was which.
Nothing in Intercom carried a stable case identity. A conversation continues after the first sync, so any naive push would create a fresh case on every poll and bury the real one in duplicates.
Our Approach
MuleSoft became the authenticated middleware tier, and that choice was made against two alternatives. Exposing Salesforce directly was refused on security grounds. Hevo was considered and dropped: it would have added a tool with no in-house experience behind it, plus its own security and budget review.
A Mule App Scheduler polls Intercom's Search for Conversations endpoint every 30 minutes. The interval is deliberate. It keeps the integration under Salesforce API rate limits and aggregates transcript updates into a single sync event instead of a stream of small writes.
DataWeave flattens nested Intercom conversation JSON into Salesforce Case objects. Cases are created or updated keyed on the Intercom Conversation ID, which is what stops a continuing conversation from becoming a pile of duplicate records.
Two case scenarios are specified rather than inferred. A chatbot-only conversation is created with the bot as case owner. A conversation that escalates is assigned to the live agent who took it.
This engagement is part of our systems integration work for technology & software organisations.
Impact
Support cases without CRM exposure
Chat reaches Salesforce Service Cloud as structured cases, and the production instance stays closed to the outside platform. Security and reporting stop pulling against each other.
One conversation, one case
Keying on the Intercom Conversation ID means a conversation that runs for hours updates a single case. Support reporting counts conversations, not sync events.
Bot and agent work is separable
Case ownership is stamped at creation from the conversation's own shape, so chatbot-handled volume and live-agent volume can be reported apart without manual triage.
Rate limits designed for, not discovered
The 30-minute batch was chosen to sit inside Salesforce API limits. Throttling became a design parameter rather than a production incident.
When an architecture review board refuses to expose the CRM, the integration tier is the requirement. MuleSoft holds both sets of credentials so neither platform holds the other's.
A chat conversation has no natural case identity and does not end when the first sync runs. Matching on the platform's own conversation identifier is what makes a polling integration idempotent.
The 30-minute cycle is sized to the Salesforce API budget. Aggregating transcript updates into one write per cycle keeps a high-volume support channel inside Salesforce limits.
Bot-only and bot-then-agent are different records with different owners. Deciding that in the data contract, not in a workflow afterwards, is what keeps case ownership trustworthy.
Enterprise security wouldn't let Intercom connect to the Salesforce production instance directly. A conversation also continues after its first sync, so a plain push would create a fresh case on every poll. Now MuleSoft sits between the two as an authenticated proxy and polls every 30 minutes. It creates or updates each case keyed on the Intercom "Conversation ID", so a conversation that runs for hours updates a single case and support reporting counts conversations, not sync events.
FAQ
Because security would not permit the direct connection. The review board's position was that the Salesforce production instance does not get exposed to an external custom application. That removed the direct build before cost entered the conversation.
MuleSoft holds the credentials for both platforms. Intercom never authenticates against Salesforce, and Salesforce never accepts an inbound call from the chat platform.
It matches on the Intercom Conversation ID. A conversation keeps going after the first 30-minute poll, so the sync has to recognise a conversation it has already seen and update that case rather than create another. The Conversation ID is stable for the life of the conversation, which makes it the right key. Without it, every poll adds a case and the real one is impossible to find.
Continue reading