Skip to main content

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:

  1. Known CRM contact — BlueSender prefers a recipient that has previously received messages from the CRM.
  2. First external contact — if no recipient is known to the CRM, pick the first recipient that isn't the Mac user.
  3. Sender handle — last-resort fallback.

The CRM should:

  • Use the top-level contactId for contact lookup (BlueSender has already resolved it to a CRM contact).
  • Use metadata.sender for 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:

POST /conversations/messages/inbound
{
"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​

POST /crm/webhook — group reply
{
"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.

POST /crm/webhook — group + animation
{
"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 by metadata.sender.
  • Display the actual sender using metadata.sender.
  • Include display_name in the metadata when sending an animation to a group.