Messaging

Update time: 2024/03/07 11:09:07

The SDK for Flutter can send and receive multiple types of messages, helping you implement messaging for diverse use cases. The SDK provides the MessageBuilder class and the MessageService class that create messages of different types, send and receive messages, and listen for messaging events. The structure of a message defined in the SDK is NIMMessage (does not support inheritance and extension). Different message types are defined in NIMMessageType. The sendMessage method is used to send different types of messages. Messages sent using this method for P2P chats or group chats are identified by the NIMSessionType parameter.

This document introduces how a message works in different sessions, prerequisites and how to create and send a message.

  • Messaging in chat rooms and Qchat channels must be configured separately. For specific workflows to implement messaging, see Messaging in chat room and Messaging in Qchat.
  • The sequence diagrams in this document may display abnormally due to network problems. To fix the displayed problem, refresh the current page.

How it works

After your app integrates the NIM SDK and completes the SDK initialization, the message sending and receiving process is shown in the diagram below (except for local tip messages and notification messages).

Message.png

The process in the figure above contains the following 3 steps:

  1. Integrate accounts and login.
    1. Register IM accounts with user account of your app, Register IM accounts (accid).
    2. CommsEase IM server returns the token to the app server.
    3. A client logs in to the app server.
    4. App server returns the token to the client.
    5. The client logs in to IM server using the token.
  2. User A sends a message to IM server.
  3. IM server forwards messages to other users:
    • For messages in P2P chats, IM server delivers the message to User B.
    • For messages in group chats, IM server delivers the message to all users in the group.

The above figure only uses static token login as an example to show the message sending and receiving process. IM also supports login authentication using dynamic tokens and webhooks. For more information, see Login authentication.

Prerequisites

Before sending messages, make sure:

  • SDK is initialized.
  • You have created IM accounts
  • You have created a group for messaging in group chats.
  • You have understood the [limits] of each message type (https://doc.yunxin.163.com/messaging/docs/Tg1MjcyMjg?platform=flutter#message-types).

API rate limit

The method of sending a message (sendMessage) can be called up to 300 times per minute by default.

Messaging

Send text messages.

sequenceDiagram

%%{init: 
{
  "theme": "default",
  "themeVariables": {
    "mainBkg" : "#9DC3E6",
    "actorBkg" : "#337EFF",
    "labelBoxBorderColor" : "#7FBC00",
    "labelBoxBkgColor" : "#7FBC00",
    "fontFamily": "Inter",
    "fontSize": "10px"
 }
}
}%%

    participant Sender
    participant NIM
    participant Receiver

    note over NIM: Initialization of SDK by both participants

    Sender ->> NIM: Listen for message status change <br>(onMessageStatus)
    Sender ->> NIM: Log in

    Receiver ->> NIM: Listen for message status change & message reception <br>(onMessageStatus & onMessage)
    Receiver ->> NIM: Log in

    Sender ->> NIM: Create text message <br>(createTextMessage)
    Sender ->> NIM: Send message <br>(sendMessage)
    NIM -->> Receiver: NIMMessage

Procedure

  1. The sender has registered the onAudioRecordStatus event stream to track changes of the message status.

    NimCore.instance.messageService.onMessageStatus.listen((NIMMessage message) {
        // 1. Determine whether it is your message based on the sessionId
        // 2. Change the message status in memory
        // 3. Refresh the interface
    });
    
  2. The recipient has registered the onMessage and onAudioRecordStatus event streams to track changes of the message receiving and message status.

    NimCore.instance.messageService.onMessage.listen((List<NIMMessage> list) {
        // Handle new messages. For the convenience of uploading and processing, the SDK ensures that the messages parameter come from the same chat object.
    });
    
  3. The sender creates a message by calling the createTextMessage method.

    You can specify a text message of a P2P chat or group chat by setting the sessionType parameter. Make sure a group chat exists if you set the message for the group chat.

    Parameter Type Description
    sessionId String The ID of a session. The sessionType is used to determine the session type.
    • If the session is a P2P chat, the sessionId is the user’s IM account (accid)
    • If the session is a group chat, sessionId is the group ID
    sessionType NIMSessionType The session type.
    text String The body of a text message.
  4. The sender sends the message by calling the sendMessage method.

    You can specify whether the message is stored on the server, added to the roaming messages or counted as unread messages by configuring NIMCustomMessageConfig. For specific configuration examples, see Message Configuration.


    Sample code for creating and sending a text message:

    // Test account
    String account = 'testAccount';
    // P2P chat
    NIMSessionType sessionType = NIMSessionType.p2p;
    String text = 'this is an example';
    // Create and send a text message.
    Future<NIMResult<NIMMessage>> result = MessageBuilder.createTextMessage(
        sessionId: account, sessionType: sessionType, text: text)
        .then((value) => value.isSuccess
        ? NimCore.instance.messageService
            .sendMessage(message: value.data!, resend: false)
        : Future.value(value));
    
  5. The recipient receives the text message returned by the onMessage callback.

Send and receive multimedia messages.

Multimedia messages include image, audio, video, and file messages.

NIM SDK allows users to make high-definition voice recordings and playbacks for processing audio messages. For more information, see Audio message processing.

API sequence diagram

sequenceDiagram

%%{init: 
{
  "theme": "default",
  "themeVariables": {
    "mainBkg" : "#9DC3E6",
    "actorBkg" : "#337EFF",
    "labelBoxBorderColor" : "#7FBC00",
    "labelBoxBkgColor" : "#7FBC00",
    "fontFamily": "Inter",
    "fontSize": "10px"
 }
}
}%%

    participant Sender
    participant NIM
    participant Receiver


    note over NIM: Initialization of SDK by Both Parties

    Sender ->> NIM: Listen for message status change<br>Listen for attachment upload/download progress<br>(onMessageStatus & onAttachmentProgress)
    Sender ->> NIM: Log in

    Receiver ->> NIM: Listen for message status change<br>Listen for message reception<br>Listen for attachment upload/download Progress<br>(onMessageStatus & onMessage & onAttachmentProgress)
    Receiver ->> NIM: Log in

    Sender ->> NIM: Create multimedia messages<br>(createAudio/Image/Video/FileMessage)
    Sender ->> NIM: Send created message
    Sender ->> NIM: Optional: cancel attachment upload<br>(cancelUploadAttachment)
    NIM -->> Receiver: NIMMessage

    Receiver ->> NIM: Optional: Manually download attachment<br>(downloadAttachment)

Procedure

  1. The sender registers the following event flow.

    • Register the onMessageStatus event stream to track the changes of the message status NIMMessageStatus and attachment status [NIMMessageAttachmentStatus](https://doc.yunxin.163 .com/docs/interface/NIM_SDK/Latest/Flutter/nim_core/NIMMessageAttachmentStatus.html).
    • Resiter the onAttachmentProgress event stream to track the progress of uploading or downloading message attachment. Note: The event flow is not supported for web apps.
    onMessageStatus
    NimCore.instance.messageService.onMessageStatus.listen((NIMMessage message) {
        // 1. Determine whether it is your message based on the sessionId
        // 2. Change the message status in memory
        // 3. Refresh the interface
    });
    
    NIMMessageAttachmentStatus
    NimCore.instance.messageService.onAttachmentProgress.listen((NIMAttachmentProgress process) {
      // TODO  updates the UI based on the attachment download/upload progress
    });
    
  2. Recipient registers the following event streams.

    • onMessage used to track message receiving.
    • onAttachmentProgress used to track the transfer progress of uploading or downloading message attachments.
    onMessage
    NimCore.instance.messageService.onMessage.listen((List<NIMMessage> list) {
        // Handle new messages. For the convenience of uploading and processing, the SDK ensures that the messages parameter come from the same chat object.
    });
    
    onAttachmentProgress
    NimCore.instance.messageService.onAttachmentProgress.listen((NIMAttachmentProgress process) {
      // TODO  updates the UI based on the attachment download/upload progress
    });
    
  3. The sender create a multimedia message.

    Type
    Method
    Resources storage
    Image message createImageMessage You can specify the expiration time of multimedia resources (image, audio, video, or file) for multimedia messages stored on the Netease Object Storage (Netease Object Storage, NOS) service. For more information, see [Multimedia Resource Storage](https://doc.yunxin.163.com/TM5MzM5Njk/docs/jIzNjg1MDU?platform =flutter).
    Audio message createAudioMesssage
    Video message createVideoMessage
    File message createFileMessage

    The previous methods contain the following parameters:

    Parameter Type Description
    sessionId String The ID of a session. The sessionType is used to determine the session type.
    • If the session is a P2P chat, the sessionId is the user’s IM account (accid)
    • If the session is a group chat, sessionId is the group ID
    sessionType NIMSessionType The session type.
    filePath String The file path of a multimedia resource. An empty string can be used for web apps.
  4. The sender sends the message by calling the sendMessage method.

    • You can specify whether the message is stored on the server, added to the roaming messages or counted as unread messages by configuring NIMCustomMessageConfig. For specific configuration examples, see Message Configuration.
    • If you send an image message, video message or file message you can call cancelUploadAttachment method to cancel the upload of an attachment (image, video or file). If the resource is already uploaded, the operation fails. If uploading the resources is canceled, the delivery of the message with the attachment will fail. The message state becomes NIMMessageStatus.fail, and the attachment NIMMessageAttachmentStatus.cancel.
    • If the same multimedia message needs to be sent multiple times, control the sequence and the rate to avoid delivery failures.

    ** Sample code for creating and sending a multimedia message:

    Image message
    // Test account
        String account = 'testAccount';
    // P2P chat
        NIMSessionType sessionType = NIMSessionType.p2p;
    // Keep the image in the corresponding directory
        File file = new File('filePath');
    // Display the image name
        String displayName = 'this is a file';
    // Base64 is required for web apps. Other platforms can ignore it.
        String base64 = 'this is base64';
    // Send the image message.
        Future<NIMResult<NIMMessage>> result =
        MessageBuilder.createImageMessage(
            sessionId: account,
            sessionType: sessionType,
            filePath: file.path,
            fileSize: file.lengthSync(),
            displayName: displayName,
            base64: base64,
            nosScene: NIMNosScene.defaultIm)
            .then((value) => value.isSuccess
            ? NimCore.instance.messageService
            .sendMessage(message: value.data!, resend: false)
            : Future.value(value));
    
    Audio message
    // Test account
        String account = 'testAccount';
    // P2P chat
        NIMSessionType sessionType = NIMSessionType.p2p;
    // Keep the audio file in the corresponding directory
        File file = new File('filePath');
    // Display the audio name
        String displayName = 'this is a file';
        // Base64 is required for web apps. Other platforms can ignore it. 
        String base64 = 'this is base64';
    // Send the audio message
        Future<NIMResult<NIMMessage>> result =
        MessageBuilder.createAudioMessage(
            sessionId: account,
            sessionType: sessionType,
            filePath: file.path,
            fileSize: file.lengthSync(),
            base64: base64,
            duration: 2000,
            displayName: displayName,
            nosScene: NIMNosScene.defaultIm)
            .then((value) => value.isSuccess
            ? NimCore.instance.messageService
            .sendMessage(message: value.data!, resend: false)
            : Future.value(value));
    
    Video message
    // Test account
    String account = 'testAccount';
    // P2P chat
        NIMSessionType sessionType = NIMSessionType.p2p;
    // Keep the video file in the corresponding directory
        File file = new File('filePath');
    // Display the video name
        String displayName = 'this is a file';
        // Base64 is required for web apps. Other platforms can ignore it. 
        String base64 = 'this is base64';
    // Send the message
        Future<NIMResult<NIMMessage>> result =
        MessageBuilder.createVideoMessage(
            sessionId: account,
            sessionType: sessionType,
            filePath: file.path,
            fileSize: file.lengthSync(),
            base64: base64,
            duration: 2000,
            width: 1080,
            height: 720,
            displayName: displayName,
            nosScene: NIMNosScene.defaultIm)
            .then((value) => value.isSuccess
            ? NimCore.instance.messageService
            .sendMessage(message: value.data!, resend: false)
            : Future.value(value));
    
    File message
    // Test account
        String account = 'testAccount';
    // P2P chat
        NIMSessionType sessionType = NIMSessionType.p2p;
    // Keep the file in the corresponding directory
        File file = new File('filePath');
    // Display the file name
        String displayName = 'this is a file';
        // Base64 is required for web apps. Other platforms can ignore it. 
        String base64 = 'this is base64';
    // Send the message
        Future<NIMResult<NIMMessage>> result = MessageBuilder.createFileMessage(
            sessionId: account,
            sessionType: sessionType,
            filePath: file.path,
            fileSize: file.lengthSync(),
            base64: base64,
            displayName: displayName,
            nosScene: NIMNosScene.defaultIm)
            .then((value) => value.isSuccess
            ? NimCore.instance.messageService
            .sendMessage(message: value.data!, resend: false)
            : Future.value(value));
    
  5. The recipient receives the multimedia message returned by the callback of the onMessage event stream.

    Multimedia resources are automatically downloaded by default. For the default download strategies of different types of messages, see the table below:

    Type Download strategy
    Imageor video message The SDK automatically downloads thumbnail and cover image when receiving a message.
    Audio message The SDK automatically downloads the source audio when receiving a message.
    File message The SDK DOES NOT download the source file by default.
    • To download the source file of a file message, call the downloadAttachment method to download the file manually. If the resources of multimedia messages fail to be downloaded automatically, this method can also be called to manually download the resources.

      Paraters of the downloadAttachment method
      Parameter
      Type
      Description
      message NIMMessage The message that hold the attachment.
      thumb bool Whether only thumbnails are downloaded. If the value is set to true, only the thumbnail will be downloaded. The parameter is valid only for image and video message. The parameter is not supported on Windows and macOS.
    • If you want to choose the proper time to download the resources, set the initialization configuration parameter NIMSDKOptions.enablePreloadMessageAttachment to false, disable the default resource download strategy, and call downloadAttachment method.


    An example of manually downloading multimedia resources is as follows:

    NimCore.instance.messageService.downloadAttachment(message, true);
    
  6. The recipient can get the message attachment using NIMMessageAttachment after the attachment is downloaded. The base class of multimedia attachment NIMFileAttachment is inherited from NIMMessageAttachment. Its subclasses include:

    Some parameters of multimedia attachments
    Parameter Type Description
    path String Optional, The path of a local file. If the file does not exit, null is returned.
    The file path of an audio message can be obtained after the attachment is downloaded.
    The file path of an image or video message is obtained after the file is manually downloaded. When receiving an image or video message, the SDK only automatically downloads the thumbnail of the file by default.
    path String Optional, The path of a local thumbnail. If the thumbnail does not exit, null is returned.
    If the thumbnail download is complete, the thumbnail file path is obtained. The parameter is not supported on Windows and macOS)
    thumbUrl String Optional. The URL of a thumbnail. The parameter is not supported on Windows and macOS.
    size int Optional, the size of a file in bytes.
    md5 String Optional. The MD5 value of a file.
    url String Optional, the download URL of a file on the server. If the file is not uploaded, null is returned.
    extension String Optional, the file extension.
    expire int Optional, the expiration time of a file. is not supported for Windows and macOS.
    nosScene NIMNosScene NOS token used for uploading files. The default value is [NIMNosScenes.defaultIm]
    displayName String Optional, the display name of a file. The display name can be different from the file name and used for display on UI.
    base64 String Optional. The parameter is used to specify the information about a file to be delivered. The parameter is required for sending files for web apps.

    NIMFileAttachment holds the attachment of a message.

Send and receive a location message

The process of sending and receiveing location messages is similar to that of text messages. Only the method of constructing a location message is different. This section only shows relevant examples. For the specific implementation process, see [Send and receive text messages] (https://doc.yunxin.163.com/docs/TM5MzM5Njk/jk0NDM1NjA?platformId=60002#Send and receive text messages).

  1. Create a location message by calling the createLocationMessage method.

    Parameter Type Description
    sessionId String The chat ID. If it is a P2P chat, use a user account (accid). For group chats, use a group ID.
    sessionType NIMSessionType The session type, NIMSessionType.p2p represents the P2P chat and NIMSessionType.team is the group chat.
    latitude double latitude
    longitude double longitude
    address String The description of a location.

    You can specify whether the message is stored on the server, added to the roaming messages or counted as unread messages by configuring NIMCustomMessageConfig. For specific configuration examples, see Message Configuration.

  2. Send the location message by calling the sendMessage method.

    Sample code for creating and sending a location message:

    // Test account
    String account = 'testAccount';
    // P2P chat
    NIMSessionType sessionType = NIMSessionType.p2p;
    // Display the file name
    String address = 'this is a address';
    // Send the message
    Future<NIMResult<NIMMessage>> result =
        MessageBuilder.createLocationMessage(
                sessionId: account,
                sessionType: sessionType,
                latitude: 30.3,
                longitude: 120.2,
                address: address)
            .then((value) => value.isSuccess
                ? NimCore.instance.messageService
                    .sendMessage(message: value.data!, resend: false)
                : Future.value(value));
    

Send an alert message

Alert messages are used for reminders in the session. The message type is NIMMessageType.tip. Alert messages are different from custom messages. Alert messages cannot hold attachments by calling thesetAttachment method. If you must add an attachment, use a custom message.. Tip messages can serve as in-session notification reminders, such the welcome message that appears when joining a session, or the prompt after hitting a sensitive word during the session. You can use custom message for these scenarios but the implementation is complicated.

This section takes the scenario of "You have recalled a message and the reminder appears in the group (the message is only visible to the sender and not sent to the server)" as an example to introduce the process of sending and receiving tip messages.

API sequence diagram

sequenceDiagram

%%{init: 
{
  "theme": "default",
  "themeVariables": {
    "mainBkg" : "#9DC3E6",
    "actorBkg" : "#337EFF",
    "labelBoxBorderColor" : "#7FBC00",
    "labelBoxBkgColor" : "#7FBC00",
    "fontFamily": "Inter",
    "fontSize": "10px"
 }
}
}%%


    participant Participant_A
    participant NIM
    participant Other participants


    note over NIM: SDK Initialization

    Participant_A ->> NIM: Listen for nessage status change <br> receive system notifications <br>(onMessageStatus & onReceiveSystemMsg)
    Participant_A ->> NIM: Log in

    Other participants ->> NIM: Log in

    note over Participant_A: Join group

    Participant_A ->> NIM: Create tip message <br>(createTipMessage)
    note right of Participant_A: Set the tip message to be excluded from unread count
    Participant_A ->> NIM: Store tip message to local database <br>(saveMessageToLocalEx)

Procedure

  1. Before logging in to the IM server, User A registers the onMessageStatus and onReceiveSystemMsg event streams to monitor the changes of the message status NIMMessageStatus and receiving system notifications. In this scenario, listen to the the notification for unsending messages.

    onMessageStatus
    NimCore.instance.messageService.onMessageStatus.listen((NIMMessage message) {
        // 1. Determine whether it is your message based on the sessionId
        // 2. Change the message status in memory
        // 3. Refresh the interface
    });
    
    onReceiveSystemMsg
    NimCore.instance.systemMessageService.onReceiveSystemMsg.  NimCore.instance.systemMessageService.onReceiveSystemMsg.listen((SystemMessage event) {
    
            });
    
    
  2. User A creates an advanced group by calling the createTeam method. For the sample code, see Create a group.

  3. Other users join the advanced group created by User A. For the method to join an advanced group, see Join a group.

  4. User A creates an alert message by calling the createTipMessage method with the enableUnreadCount parameter set to false. In this case, alert messages are not counted as unread.

    The methods contain the following parameters:

    Parameter Type Description
    sessionId String The ID of a session. The sessionType is used to determine the session type.
    • If the session is a P2P chat, the sessionId is the user’s IM account (accid)
    • If the session is a group chat, sessionId is the group ID
    sessionType NIMSessionType The session type.
  5. User A stores alert messages in the local database by calling the saveMessageToLocalEx method without sending alert messages to the server.

    The sample code for Step 4 to 5:

 //Create an alert message.
      var tipMessageBuild = await MessageBuilder.createTipMessage(sessionId: sessionId, sessionType: sessionType,content: "content");
      var message = tipMessageBuild.data!;
      message.config = NIMCustomMessageConfig(enableUnreadCount:false);
      // Save the alert message.
      NimCore.instance.messageService.saveMessageToLocalEx(message: message, time: time).then((value) {
        if(value.isSuccess){
          // TODO success
        }
      });

Receive notification messages

For events in some specific scenarios, CommsEase server presets some notification messages and sends them to the SDK when the event occurs. A notification is a specific message. You must parse the data of a notification message to obtain the content of a notification. For example, notifications for group events. If new members join a group, the members in the group will receive this type of notifications. For the difference between notification messages and system notifications, see [Notification Messages and System Notifications] (https://doc.yunxin.163.com/messaging/docs/Tg1MjcyMjg?platform=flutter#Notification Messages and System Notifications)

  • The notification message is an in-session message and its corresponding construct is NIMMessage. The message type is NIMMessageType.notification. Notification messages are used for notifications for events in groups and chat rooms.

To parse the notifications, see [Group notification messages](https://doc.yunxin.163.com/messaging/docs/jE1NjkyNzA?platform=flutter#group notifications).

Send and receive custom messages

In addition to built-in types of messages, the NIM SDK also supports custom messages. The SDK does not define and parse the specific content of a custom message. You must handle parsing of custom messages.. The SDK will store custom messages in the message database, and display custom message in the message history the same as built-in messages.

Custom messages are displayed in the form of attachments. In the NIMMessage class, custom messages are parsed as the NIMCustomMessageAttachment object.

FAQ

How can I get the message body

Register the onMessageStatus event stream that tracks the changes of message status. The method can track the NIMMessage object returned when the message status changes.

You can get the message body using the following attributes of the NIMMessage object.

  • messageDirection: message direction (sending or receiving a message)
  • sessionId: the chat target, a user account (accid) for P2P chats, and group ID (teamId) for groups chats.
  • content: The content of a message.
  • messageAttachment: The attachment of a message.
  • status: the message status, sending or receiving a message.
  • timestamp: The time when a message was sent in milliseconds.

How can I set the extension field of a message

You can set the extension field of messages in P2P chats or group chats for server side and client side. The server-side extension field can only be set before the message is sent, and it will be synchronized to other devices.

  • For extension fields, wrap them in JSON format and pass in a non-formatted JSON string with a maximum length of 1024 bytes.

Method to set the extension field:

Update the extension field of a message on the client side
  1. For messages in P2P chats and group chats, set the extension field of a message when creating the IMMessage object using the localExtension parameter.

  2. Update the local extension field of a message by calling the updateMessage method.

    After setting the local extension field of a message, call the updateIMMessage method to update the field. Otherwise, the extension field will not take effect.

Update the extension field of a message on the server

For messages in P2P chats and group chats, set the extension field of a message on the server when creating the NIMMessage object using the remoteExtension method.

Was this page helpful?
Yes
No
  • How it works
  • Prerequisites
  • API rate limit
  • Messaging
  • Send text messages.
  • Send and receive multimedia messages.
  • Send and receive a location message
  • Send an alert message
  • Receive notification messages
  • Send and receive custom messages
  • FAQ
  • How can I get the message body
  • How can I set the extension field of a message