Group messages
Apple Messages has two flavours of conversation: 1:1 chats and group chats. Group chats add complexity because the sender of a given message in a group is rarely the same as the CRM contact the conversation belongs to. This guide covers how BlueSender surfaces group context to your CRM and how to send replies into groups.
Inbound: Mac → CRM
When the Mac receives a group message, BlueSender forwards it via
POST /conversations/messages/inbound. The participant list, display
name, and actual sender handle are carried inside the
bluesendr-metadata:v1 footer embedded
in the message body.
Sender vs contact resolution in groups
In a 1:1 chat, the message sender is the contact — straightforward. In a group chat, the sender could be anyone in the group, and that person may not be a registered contact in your CRM. If BlueSender keyed the inbound delivery on the sender handle, your CRM would reject it with "contact not found".
To avoid this, BlueSender resolves the inbound contactId to a
known CRM contact in the group, while preserving the actual
sender's handle in metadata.sender. The resolution order is:
- Known CRM contact — BlueSender prefers a recipient that has previously received messages from the CRM.
- First external contact — if no recipient is known to the CRM, pick the first recipient that isn't the Mac user.
- Sender handle — last-resort fallback.
The CRM should:
- Use the top-level
contactIdfor contact lookup (BlueSender has already resolved it to a CRM contact). - Use
metadata.senderfor display ("Bob sent this message"). - Associate the group conversation with the contact at
contactId.
Inbound example
A group chat with Alice (+111), Bob (+222), and the Mac user
(+333). Alice has previously received a CRM message; Bob has not.
Bob sends "Hello group!" in the chat:
{
"type": "SMS",
"contactId": "<crm contact id for Alice>",
"locationId": "<crm location id>",
"message": "Hello group!\n\n-- bluesendr-metadata:v1 --\n{\"animation\":null,\"chat_id\":649,\"display_name\":\"Family Group\",\"group_id\":null,\"is_group\":true,\"message_guid\":\"3F9E1D72-A0B4-4C11-9D8E-1A2B3C4D5E6F\",\"recipients\":[\"+111\",\"+222\",\"+333\"],\"room_name\":null,\"sender\":\"+222\",\"service_name\":\"iMessage\"}\n-- end bluesendr-metadata --"
}
The CRM stores this against Alice's contact record but renders "Bob
(+222) sent this message" using metadata.sender.
Outbound: CRM → Mac
Sending into a group
To send a CRM-originated message into a group chat, POST to
/crm/webhook with the
bluesendr-metadata:v1 footer embedded
in the message body. The Mac extracts the metadata footer,
resolves chat_id to the local chat handle, and sends via the most
reliable path available (chat handle preferred).
If only phone / number is supplied without metadata, BlueSender
treats it as a 1:1 send to that recipient. To target a group, the
metadata footer is required.
Outbound example
{
"locationId": "<crm location id>",
"contactId": "<crm contact id for Alice>",
"messageId": "<crm correlation id>",
"phone": "+111",
"message": "Got it, thanks!\n\n-- bluesendr-metadata:v1 --\n{\"chat_id\":649,\"display_name\":\"Family Group\",\"is_group\":true,\"recipients\":[\"+111\",\"+222\",\"+333\"]}\n-- end bluesendr-metadata --"
}
Group + animation
When sending a send-with-effect animation to a
group, the metadata must include display_name. BlueSender uses
display_name to identify the correct group thread before applying
the effect. Without display_name, the animation may only be visible
locally on the Mac or may be applied to the wrong thread.
{
"locationId": "<crm location id>",
"contactId": "<crm contact id>",
"messageId": "<crm correlation id>",
"phone": "+32483119453",
"message": "Lasers test!\n\n-- bluesendr-metadata:v1 --\n{\"animation\":\"lasers\",\"chat_id\":655,\"display_name\":\"SANDBOX GROUP\",\"is_group\":true,\"recipients\":[\"+32456791066\",\"+32483119453\"]}\n-- end bluesendr-metadata --"
}
iMessage vs SMS caveats
- Green-bubble groups (SMS) — iMessage participants in an SMS group thread may not resolve cleanly. Outbound sends to mixed- service groups can fall back to lower-quality paths.
- Mixed-capability participants — if any recipient in a group is
not iMessage-capable on the sending Mac, participant-based group
creation can fail. The chat-handle-based path (using the metadata
footer's
chat_id) is the most reliable.
CRM responsibilities checklist
- Preserve the metadata footer on inbound messages.
- Strip the footer from any UI rendering.
- Round-trip the footer back to BlueSender on outbound sends.
- Look up contacts by the top-level
contactId, not bymetadata.sender. - Display the actual sender using
metadata.sender. - Include
display_namein the metadata when sending an animation to a group.
Related
- Animations — group animations require
display_namein the metadata footer. - Reactions — Tapbacks on messages within a group thread.
- Voice messages — voice messages can arrive in group threads.
bluesendr-metadata:v1footer —chat_id,display_name, andrecipientsschema.- HTTP Webhooks — both webhook directions.