How to Send iMessages from Slack
Your sales and support teams live in Slack. Your customers live in iMessage. Connecting the two means your team can send and receive iMessages without leaving Slack — no context switching, no separate apps, and full team visibility into customer conversations.
Why Slack + iMessage?
Most business teams use Slack as their internal communication hub. But when they need to reach a customer via iMessage, they have to switch to a separate dashboard, app, or tool. This creates friction:
- Context switching kills productivity. Switching between Slack and a messaging dashboard interrupts workflow.
- Lost visibility. When one rep sends an iMessage from a separate tool, other team members do not see it. This leads to duplicate outreach or missed follow-ups.
- Delayed responses. If incoming customer iMessages only appear in a separate dashboard, response times suffer because team members are not monitoring it constantly.
By connecting iMessage to Slack, you get:
- Send iMessages to customers directly from Slack with a slash command or bot
- Receive customer iMessage replies as Slack messages in a dedicated channel
- Full team visibility — everyone can see the conversation
- Zero context switching — stay in Slack for everything
Architecture Overview
The integration has two data flows:
Sending (Slack → iMessage):
- Team member types a slash command in Slack:
/imessage +15551234567 Hey Sarah, your proposal is ready! - Slack sends the command to your server (a simple Express app or serverless function)
- Your server parses the number and message, then calls the Sendblue API
- Sendblue delivers the iMessage to the customer as a blue bubble
- Your server posts a confirmation back to Slack
Receiving (iMessage → Slack):
- Customer sends an iMessage reply to your Sendblue number
- Sendblue fires a webhook to your server with the message content
- Your server formats the message and posts it to a Slack channel via Slack's Incoming Webhooks or Web API
- The team sees the customer's reply in Slack in real-time
Both flows run through a lightweight server that acts as a bridge. This can be a simple Express app on any hosting platform, or a serverless function on AWS Lambda, Vercel, or Cloudflare Workers.
Setup Guide
Step 1: Create a Slack App
Go to api.slack.com/apps and create a new app. Choose "From scratch" and select your workspace.
Step 2: Add a Slash Command
In your app settings, go to "Slash Commands" and create a new command:
- Command:
/imessage - Request URL:
https://your-server.com/slack/imessage - Description: "Send an iMessage to a customer"
- Usage hint:
+1234567890 Your message here
Step 3: Set Up Incoming Webhook (for receiving)
In your Slack app settings, go to "Incoming Webhooks" and activate them. Create a new webhook URL pointed at the Slack channel where you want incoming iMessages to appear (e.g., #customer-messages).
Step 4: Install the app to your workspace
Go to "Install App" in your Slack app settings and install it to your workspace. Note the Bot Token and Webhook URL.
Code Example: Slash Command Handler
Here is the Express server that handles both sending and receiving:
import express from 'express';
import Sendblue from 'sendblue';
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const sendblue = new Sendblue(
process.env.SENDBLUE_API_KEY,
process.env.SENDBLUE_API_SECRET
);
const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
// Handle /imessage slash command from Slack
app.post('/slack/imessage', async (req, res) => {
const { text, user_name } = req.body;
// Parse: "+15551234567 Hello, this is the message"
const match = text.match(/^(\+\d{10,15})\s+(.+)$/s);
if (!match) {
return res.json({
response_type: 'ephemeral',
text: 'Usage: /imessage +15551234567 Your message here',
});
}
const [, number, content] = match;
try {
await sendblue.sendMessage({ number, content });
res.json({
response_type: 'in_channel',
text: `*${user_name}* sent iMessage to ${number}:\n> ${content}`,
});
} catch (error) {
res.json({
response_type: 'ephemeral',
text: `Failed to send: ${error.message}`,
});
}
});
// Handle incoming iMessages via Sendblue webhook
app.post('/webhook/receive', async (req, res) => {
const { from_number, content, media_url } = req.body;
let slackMessage = `*New iMessage from ${from_number}:*\n${content || '(no text)'}`;
if (media_url) {
slackMessage += `\n📎 Media: ${media_url}`;
}
// Post to Slack channel
await fetch(SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: slackMessage }),
});
res.status(200).json({ ok: true });
});
app.listen(3000, () => {
console.log('Slack-iMessage bridge running on port 3000');
});Set your Sendblue receive webhook URL to https://your-server.com/webhook/receive in the Sendblue dashboard.
Receiving Replies in Slack
When a customer replies to your iMessage, Sendblue fires a webhook to your server. The handler above posts it to your Slack channel via the incoming webhook URL. Here is what the team sees:
# In your #customer-messages Slack channel:
*New iMessage from +15551234567:*
Yes, I reviewed the proposal. Can we schedule a call for Thursday?
# Team member replies via slash command:
/imessage +15551234567 Absolutely! How about Thursday at 2pm EST?
*sarah_sales* sent iMessage to +15551234567:
> Absolutely! How about Thursday at 2pm EST?The entire conversation is visible to the team in one Slack channel. Any team member can jump in and respond. The customer just sees a seamless iMessage conversation from your business number — they have no idea Slack is involved.
Advanced Features
The basic setup above gets you sending and receiving. Here are enhancements for a production deployment:
Thread per conversation. Instead of posting all messages to one flat channel, create a Slack thread for each unique phone number. Use Slack's Web API (chat.postMessage with thread_ts) to keep conversations organized. Store the thread timestamp mapping in a database.
Delivery confirmation reactions. After sending an iMessage, check the delivery status via Sendblue's status webhook. When delivery is confirmed, add a checkmark reaction to the Slack message. This gives the team visual confirmation that the message was delivered.
Team assignment. Add a system where team members can "claim" a conversation by reacting to a message. Once claimed, route replies from that customer to the claiming team member via DM or a specific thread.
Rich formatting. Use Slack's Block Kit to format incoming messages with the customer's name (if known), conversation history link, and quick-action buttons (reply, schedule call, add to CRM).
Media handling. When customers send images or files via iMessage, download them from Sendblue's media URL and upload them to Slack so they appear inline in the channel.
Alternative: No-Code with Zapier or Make
If you prefer not to write code, you can connect Slack and Sendblue through Zapier or Make.com:
Zapier approach:
- Trigger: New message in a specific Slack channel (use a naming convention like "#send-imessage")
- Parse the message to extract the phone number and content
- Action: Send via Sendblue API (webhook action)
For receiving:
- Set up a Zapier webhook as your Sendblue receive webhook URL
- Action: Post the incoming message to your Slack channel
The no-code approach is simpler to set up but offers less flexibility. You cannot easily implement threading, reactions, or custom formatting. For teams with basic needs (send messages, see replies in a channel), it works well. For a full-featured integration, the code-based approach above is recommended.
Getting Started
Here is your setup checklist:
- Create a Sendblue account (free, no credit card)
- Create a Slack app at api.slack.com/apps
- Deploy the bridge server — the code above works on Railway, Render, Heroku, or any Node.js host
- Configure webhooks — set the Sendblue receive webhook to your server's /webhook/receive endpoint
- Test — use the /imessage command in Slack and verify the message arrives as a blue bubble
The entire setup takes about 30 minutes. Once running, your team can send and receive iMessages without ever leaving Slack.
For more integration options, explore Sendblue's native integrations with GoHighLevel, HubSpot, Salesforce, and other platforms. Or see our API documentation for building custom integrations.
Ready to send your first iMessage?
Get API access in minutes. Free sandbox, no credit card required.