When Sunshine Conversations determines that two separate appUsers are actually the same person, the two users may be merged together in order to provide a more unified view of the user, and to allow the business to keep track of users more easily as they move between different channels. The purpose of this section is to describe when and how merges occur, and how your software should react to them.
If the business is able to confirm that two users in fact refer to the same person, a merge can be triggered manually by providing the IDs of the surviving and discarded user to the merge user API. See how merges work for more information about surviving and discarded users.
When manually merging users that have access to SDKs, it’s possible for users to lose access to their SDK conversations in some cases:
If an anonymous user is merged with an identified user, the anonymous user’s session token will be revoked, and they must be issued a JWT to continue using the SDK as the surviving user.
If two identified users are merged, the userId of the discarded user can not be used to log in to the survived user (it would instead generate a new user with the discarded userId).
If two anonymous users are merged, the session token of the surviving user will be retained, and the discarded user will lose access to their conversation.
If the discarded user is online and has an active websocket connection at the time of the merge, they will receive the new session token and be able to continue as usual. If not, the conversation history will not be retrievable from the discarded user’s device and a new anonymous user will be created if they return on that device.
When dealing with users on SDKs, it is recommended to use SDK login wherever possible instead of the merge user API to avoid the pitfalls mentioned above.
Merging because of a channel transfer
When a user confirms their identity on a messaging channel by completing a channel transfer flow, it is possible that the confirmed identity already matches another user in your Sunshine Conversations app. If two anonymous appUsers are confirmed to be in possession of the same messaging channel account or phone number, then those two users will be merged into one.
Sunshine Conversations determines that both User X and User Y share the same phone number, and decides that they should be merged into one.
The users are merged together, and the conversation history is now shared between both iOS and SMS. Alice can choose to reply from either channel, and her replies will be routed to the same conversation.
Example user-initiated flow
A user named Alice is using the Web Messenger on your business’ website to chat with a support agent.
Alice does not want to remain at her computer for the duration of the support session, and chooses to continue her conversation on Facebook Messenger.
Alice is now linked to the Messenger channel, and can send replies from either her browser session, or Facebook Messenger, and her replies will be routed to the same conversation (Conversation X).
Later on, Alice returns to the business’ website from a different computer, and starts a new conversation (Conversation Y) with a support agent.
Once again, Alice chooses to continue her conversation on Facebook Messenger.
The Facebook Messenger account that she used in step 5 is the same account as was used in step 2, and therefore Sunshine Conversations determines that Conversation X and Conversation Y are referring to the same person, and therefore decides that they should be merged into one.
The users are merged together and Alice now sees her full conversation history which is shared between both browsers, as well as Alice’s Facebook Messenger account. Alice can choose to reply from either channel, and her replies will be routed to the same conversation.
Merging because of a login event
When an anonymous user on the Web or Mobile SDKs is identified using the login method, and the identified user already exists in Sunshine Conversations (if they were previously active on a different device, for example) a merge will occur between the anonymous user and the identified user. This allows a user to start a conversation with your business anonymously before they log in (for example, while browsing your business’ website). After logging in, the user will still see the conversation they had before logging in and be able to seamlessly continue as a logged in user.
Example flow on Web Messenger
A user named Alice visits your business’ website, and logs in using her existing account in your system.
As a result of the authentication, the website calls the login method to identify the user with a userId and JWT.
Alice starts a conversation with your business using the Web Messenger, as her identified user (User X).
Later on, Alice visits your website from a different browser, but does not choose to log in.
Alice uses the Web Messenger to start a new anonymous conversation with your business, creating a new anonymous user (User Y).
While conversing with a support agent, Alice decides to log in to your website to view her account settings.
Your website calls the login method, and supplies the same userId as in step 2.
User X and User Y are now confirmed to be the same identified user, and Sunshine Conversations merges the two users into one.
The users and conversations are merged together, and Alice is able to seamlessly continue her conversation using the Web Messenger, and is also able to view her previous conversation history by scrolling up in the messaging window.
How merges work
Before a merge can occur between users, Sunshine Conversations must first elect a “surviving” user, which is the user that will remain once the merge is complete. The second user becomes the “discarded” user, and will eventually be deleted at the end of the merge. In the case of a merge initiated via channel transfer, the user that initiated the transfer becomes the surviving user. In the case of a merge initiated via a login event, the surviving user is the user that was created in Sunshine Conversations first. For merges manually triggered by an API call, the caller decides the surviving and discarded users.
Once a surviving user is elected, Sunshine Conversations starts the merge flow for the users and their associated conversations.
In the case of a conflict, the discarded user’s custom properties takes precedence.
If the resulting size of the merged properties is greater than the maximum allowed value of 4KB, then properties are discarded one by one until the object is within the size limit.
The _id of the surviving user is retained, and the userId of the surviving user is resolved according to the following logic:
If an anonymous user is being merged with an identified user, the userId of the identified user is assigned to the surviving user.
If two identified users are being merged, the surviving user retains its original userId.
If two anonymous users are being merged, the surviving user will also be anonymous and will not have a userId.
The clients arrays of both users are merged, filtering for duplicates. The resulting user will contain all the clients of both users.
The conversation histories of both users are merged, sorting the resulting conversation by message timestamp.
An appUser:merge webhook is fired to indicate the surviving user, discarded user, and any custom properties that were discarded as part of step 2.
Handling merge events as a business
When a merge occurs, Sunshine Conversations will send an appUser:merge event to any subscribed webhooks, to inform the business that a merge occurred. When you receive such an event, you should update any records in your own system that reference the discarded user (or its conversations) to instead reference the surviving user. If any record merging is required on your end, you should also perform that in response to this event.
In the event where user properties were discarded as a result of a merge (in the case where the properties would have exceeded the size limit of 4KB), you may also want to handle this event in your system. The discarded properties and their values can be found in the discardedProperties field of the webhook payload.