SAMA chat server API: Conversations

FAST — CONFIDENTIAL — SCALABLE

Oleksandr Chabaniuk
SAMA communications

--

When we developed our API, we followed three rules: fast, confidential, and scalable. Each of these rules has a powerful force when we choose which messenger you will use. And by combining them, we get the perfect service that will be forever relevant for use and improvement.

Chats are an imaginary box that groups messages between users, which is why you need to build a reliable and efficient connection between these things to avoid collapse.

You’ve signed up for the messenger, so what’s next? Write a message to someone? But how?

This is the main reason why you will next think about creating a conversation 💬. We provide two types of channels through our chat API:

  1. 👤 Personal Chat Channels.
  2. 👥 Group Chat Channels.
Group & Personal cahts

Now that you know the types of chats, let’s get acquainted with the developed methods that you will use in the future.

* You also will be able to run and test out both features locally (scroll to Try SAMA block) or use them in the development of your messenger.

At the moment, our API has 5 main methods, and several child methods that are used to facilitate keeping other users’ data up-to-date in real time.

  • conversation_create | Create a new conversation
  • 📝 conversation_update | Add/Remove users from the conversation or update parameters
  • 📑 conversation_list | Get a list of all user conversations
  • conversation_delete | Delete a conversation
  • 👥 get_participants_by_cids | Get a list of conversation participants from the list of specified chats

Create a new conversation

~ request name: conversation_create

The first thing we need is a method to create a conversation. As mentioned earlier, the API provides two types of conversations: group (g) and personal (u). Based on this, the requests will differ slightly in the list of fields inherent in each type.

If you need to create a conversation for personal use, meaning between you and another user (private chat), your request ⬆️ will look like this:

{
request: {
conversation_create: {
type: "u",
participants: [ "64e4972ec0d3198d69c6de48" ]
},
id: "create_request"
}
}
  • In the participants field, you should specify the IDs of the users who will be in the chat, you do not need to specify your own.
  • The opponent_id field will be filled in automatically if the other participant’s ID was passed correctly.

The response ⬇️ to your request from the server will look like this:

{
response: {
conversation: {
_id: "64e5ccc00377ba662f72eff5",
type: "u",
opponent_id: "64e4972ec0d3198d69c6de48",
owner_id: "6470a39168eb2d21bf7ea0ba",
created_at: "2023-08-23T09:09:20.993Z",
updated_at: "2023-08-23T09:09:20.993Z"
},
id: "create_request"
}
}

* The opponent_id field is specific to the personal chat type only.

Now that you know how to create chats for personal use, let’s look at how group chats should be created.

The first thing you need to add is the name of our chat, and the second thing is to pass an array of user IDs, and here is the minimum set of parameters for a chat creation request ⬆️.

{
request: {
conversation_create: {
name: "GroupChat",
description: "Description...",
type: "g",
participants: [
"64e4973ac0d3198d69c6de4b",
"64e4972ec0d3198d69c6de48",
"64d36e9da030fd25fef3ff1f"
]
},
id: "create_request"
}
}
  • You can also pass a short description for the chat.

The response ⬇️ to your request from the server will look like this:

{
response: {
conversation: {
_id: "64e5d1790377ba662f72eff8",
name: "GroupChat",
description: "Description...",
type: "g",
owner_id: "6470a39168eb2d21bf7ea0ba",
created_at: "2023-08-23T09:29:29.247Z",
updated_at: "2023-08-23T09:29:29.247Z"
},
id: "create_request"
}
}

Great! You’ve created chats for yourself, but what about other users? Can they see them? How will they even know about it?

These are the logical questions that you will have next, so it is worth noting that when creating a chat, we create two different types of objects in the database.

  1. The first will be a single Conversation object, I think that no explanation is needed.
  2. The second will be the objects of chat participants. The object will contain data about the user’s id and the id of the chat in which he is a member.

An example of an object 📄of one of the participants:

{
_id: "64ca637c2869f09d838308df",
user_id: "6470a39168eb2d21bf7ea0ba",
conversation_id: "64e5d1790377ba662f72eff8",
created_at: "2023-08-23T09:29:29.247Z",
updated_at: "2023-08-23T09:29:29.247Z"
}

❗️ If the user ID of the array is not registered in the system, or the ID is incorrect, they will be ignored.

But it’s still not enough to let users know in real time about the chats they’re joining. That’s why we’ve added an event system that sends notifications to all users who participate in a conversation.

An example of an event ➡️ that will be sent to participants after the conversation is created:

{
event: {
conversation_created: {
_id: "64e5d1790377ba662f72eff8",
name: "GroupChat",
description: "Description...",
type: "g",
owner_id: "6470a39168eb2d21bf7ea0ba",
created_at: "2023-08-23T09:29:29.247Z",
updated_at: "2023-08-23T09:29:29.247Z"
}
}
}

Update participants and conversation data

~ request name: conversation_update

What if I made a mistake in the chat name? Or added an extra user? What if I need to add a new participant?

These are some of the most used tools you need when managing a conversation, which is why we’ve combined them into one request.

Updating 🔃 text fields are not new, just pass the new value. But to add new participants or delete existing ones, use the participants field and additional options:

  • add | Pass an array of IDs of the participants you want to add.
  • remove | Pass an array of IDs of the participants you want to delete.

A generalized view of your request ⬆️ will look like this:

{
request: {
conversation_update: {
id: "64e5d1790377ba662f72eff8",
name: "NewGroupName",
description: "NewDescription",
participants: {
add: [ "63077ad836b78c3d82af0812", "63077ad836b78c3d82af0832" ],
remove: [ "64e4973ac0d3198d69c6de4b" ],
}
},
id: "update_request"
}
}

If the owner is deleted from the chat, then this field will be assigned to the ID of another participant who will remain in the chat.

In response ⬇️ to your request, you will receive a conversation object 📄 with updated fields:

{ 
response: {
conversation: {
_id: "64e5d1790377ba662f72eff8",
name: "NewGroupName",
description: "NewDescription",
type: "g",
owner_id: "64e4973ac0d3198d69c6de4b",
created_at: "2023-08-23T09:32:29.247Z",
updated_at: "2023-08-23T09:32:29.247Z"
},
id: "updated_request"
}
}

❕ If you add new participants to a group conversation, they’ll receive a similar notification.

Get a list of all user conversations

~ request name: conversation_list

Okay, I’ve created chats and I’ve also been added to several chats, can I get a list of these chats at any time?

All you need to get a list of all your chats is to send one single request without parameters, but you can also modify it using the following options:

  • 🕐 updated_at | Use gt to set the date from the last chat update
  • 🔢 limit | Add a limit to the maximum number of records

A generalized view of your request ⬆️ might look like this:

{
request: {
conversation_list: {
updated_at: {
gt: "2023-08-23T09:32:29.247Z",
},
limit: 25,
},
id: "list_request"
}
}

* You can also use the timestamp format for representing a time parameter.

As a response ⬇️, you will receive a list of chats according to the specified parameters:

{
response: {
conversations: [
{
_id: "64e5d77f0377ba662f72f003",
name: "GroupChat",
type: "g",
owner_id: "6470a39168eb2d21bf7ea0ba",
created_at: "2023-08-23T09:55:11.915Z",
updated_at: "2023-08-23T09:55:11.915Z",
unread_messages_count: 0
},
{
_id: "64d36ec1a030fd25fef3ff23",
type: "u",
opponent_id: "64d36e9da030fd25fef3ff1f",
owner_id: "6470a39168eb2d21bf7ea0ba",
created_at: "2023-08-09T10:47:29.263Z",
updated_at: "2023-08-16T11:50:03.916Z",
last_message: {
_id: "64dcb7eb404b7683cb634b6a",
body: "Any news on the recent decision?",
from: "64d36e9da030fd25fef3ff1f",
t: 1692186604,
status: "read"
},
unread_messages_count: 10
},
...
],
id: "list_request"
}
}

Delete a conversation

~ request name: conversation_delete

Great, but what if I was added to the chat by mistake? Can I personally leave the chat?

Of course, you can also use the delete chat method. Just send a request ⬆️ with the chat ID you want to leave:

{
request: {
conversation_delete: {
id: "630f1d007ab4ed1a72a78a6a2"
},
id: "delete_request"
},
}

Let’s talk about some features of the method:

  1. If you are the owner of the chat, the chat will continue to exist, but this status will be transferred to another participant.
  2. If you are the last participant in the chat, this applies to both personal (u) and group (g) chats, this chat will be deleted completely, without the possibility of restoring it.
  3. If this is a group chat, you will leave the chat, with the possibility of being added again by other participants.
  4. Similarly to personal chats, you will delete the chat, but the other participant will have the option to re-create the chat with you (for example, by sending you a message) or you will be able to re-create it.

If the operation is successful, you will receive the following response ⬇️:

{ 
response: {
success: true,
id: "delete_request"
}
}

Re-store a personal chat

~ this is a feature of the chat creation request

Excellent! What if I deleted the chat by mistake? Or do I want to view the chat I deleted earlier again?

This option is available if you send the request to create a chat again. But it’s important to remember:

  • If you left the group chat, ask the owner to add you back.
  • If you have seen a personal chat, you will be able to save the history of messages only if the other participant has not deleted the current chat.
  • If the chat was deleted by all users, just create it again as a new chat.

👇🏼 Try it yourself! Go to the Try SAMA block.

Get a list of conversation participants

~ request name: get_participants_by_cids

Amazing! How can I recognize the participants in the chat?

It’s very simple, just send a request ⬆️ where in the cids field you specify an array of IDs of the chats you need:

{
request: {
get_participants_by_cids: {
cids: [
"64e5d77f0377ba662f72f003",
"64e5d1790377ba662f72eff8",
"64e5ccc00377ba662f72eff5",
],
includes: ["id"]
},
id: "get_participants_by_cids_request"
}
}

* You can also pass the value“id” to the includes field if you only need user IDs. This field is not required.

❗️ If you are not a member of the chat, the chat ID will be ignored.

As a result, you will receive a response ⬇️ with all the users that were found:

{
response: {
users: [
{
_id: "64e4973ac0d3198d69c6de4b",
login: "Oliver56"
},
{
_id: "64e4972ec0d3198d69c6de48",
login: "Alb3rt1"
},
{
_id: "64d36e9da030fd25fef3ff1f",
login: "Th0masss"
},
...
],
id: "get_participants_by_cids_request"
}
}

Conclusion

With a set of tools 🧰 like the SAMA Conversation API, you can create scalable chats that are easy to maintain, edit, and improve. And most importantly, they will be easy to understand and fast to use, which will encourage people to use your application!

👀 Check out more posts on our page for fantastic improvements to your app!

Try SAMA 👇🏼

To run SAMA server locally — follow https://github.com/SAMA-Communications/sama-server. Frontend app is available at https://github.com/SAMA-Communications/sama-client.

Discover, enjoy, and all feedback is welcome. We will be thankful a lot for every GitHub star, issue, or comment!

--

--