消息

消息是客户端集成中最重要的功能之一,WebIM 消息的使用方法主要为 :

  • 构造消息
  • 发送消息
  • 消息撤回
  • 接收消息
  • 处理消息
  • 消息漫游
  • 新消息提醒
  • 消息回执

通过对消息的集成,您可以最快速的集成体验 IM 收发消息的流畅体验。

let msg = new WebIM.message('txt', id);
msg.set(option);                //消息内容option,下面会有详细介绍
msg.setChatType('groupChat');   //用于设置当前聊天模式为单聊、群聊(groupChat)、聊天室(chatRoom),不设置默认为单聊

注意: 发送ext 扩展消息,可以没有这个字段,但是如果有,值不能是“ext:null”这种形式,否则出错

环信支持向单聊群组聊天室中发送:

  • 文本消息
  • 表情消息
  • 贴图消息
  • URL图片消息
  • 命令消息
  • 附件消息
  • 自定义消息

多样化的消息类型,覆盖多种场景下的消息需求。

发送文本消息(单聊、扩展)

单聊发送文本消息示例如下:

// 单聊发送文本消息
function sendPrivateText() {
    let id = conn.getUniqueId();                 // 生成本地消息id
    let msg = new WebIM.message('txt', id);      // 创建文本消息
    msg.set({
        msg: 'message content',                  // 消息内容
        to: 'username',                          // 接收消息对象(用户id)
        chatType: 'singleChat',                  // 设置为单聊
        ext: {
            key: value,
            key2: {
                key3: value2
            }
        },                                  //扩展消息
        success: function (id, serverMsgId) {
            console.log('send private text Success');  
        },                                       // 对成功的相关定义,sdk会将消息id登记到日志进行备份处理
        fail: function(e){
            console.log("Send private text error");  
        }                                        // 对失败的相关定义,sdk会将消息id登记到日志进行备份处理
    });
    conn.send(msg.body);
};

发送文本消息(群组)

群组发送文本消息示例如下:

// 群组发送文本消息
function sendGroupText() {
    let id = conn.getUniqueId();            // 生成本地消息id
    let msg = new WebIM.message('txt', id); // 创建文本消息
    let option = {
        msg: 'message content',             // 消息内容
        to: 'group id',                     // 接收消息对象(群组id)
        chatType: 'groupChat',              // 群聊类型设置为群聊
        ext: {},                            // 扩展消息
        success: function () {
            console.log('send room text success');
        },                                  // 对成功的相关定义,sdk会将消息id登记到日志进行备份处理
        fail: function () {
            console.log('failed');
        }                                   // 对失败的相关定义,sdk会将消息id登记到日志进行备份处理
    };
    msg.set(option);
    conn.send(msg.body);
};

发送文本消息(聊天室)

聊天室发送文本消息示例如下:

// 聊天室发送文本消息
function sendRoomText() {
    let id = conn.getUniqueId();         // 生成本地消息id
    let msg = new WebIM.message('txt', id); // 创建文本消息
    let option = {
        msg: 'message content',          // 消息内容
        to: 'chatroom id',               // 接收消息对象(聊天室id)
        chatType: 'chatRoom',            // 群聊类型设置为聊天室
        ext: {},                         // 扩展消息
        success: function () {
            console.log('send room text success');
        },                               // 对成功的相关定义,sdk会将消息id登记到日志进行备份处理
        fail: function () {
            console.log('failed');
        }                                // 对失败的相关定义,sdk会将消息id登记到日志进行备份处理
    };
    msg.set(option);
    conn.send(msg.body);
};

注意:单聊和群聊的表现示例基本一样,区别在于接受消息的对象不同,单聊 to 的对象为用户 ID ,群组/聊天室 to 的对象为群组/聊天室 ID


发送表情消息

发送表情同发送文本消息,需要在对方客户端将表情文本进行解析成图片。

单聊发送表情消息的代码示例如下:

conn.listen({
    onEmojiMessage: function (message) {
        console.log('Emoji');
        var data = message.data;
        for(var i = 0 , l = data.length ; i < l ; i++){
            console.log(data[i]);
        }
    },   //收到表情消息
});
// 单聊发送文本消息
var sendPrivateText = function () {
    var id = conn.getUniqueId();                 // 生成本地消息id
    var msg = new WebIM.message('txt', id);      // 创建文本消息
    msg.set({
        msg: 'message content',                  // 消息内容
        to: 'username',                          // 接收消息对象(用户id)
        chatType: 'singleChat',
        success: function (id, serverMsgId) {
            console.log('send private text Success');
        },
        fail: function(e){
            console.log("Send private text error");
        }
    });
    conn.send(msg.body);
};

注意:当为 WebIM 添加了 Emoji 属性后,若发送的消息含 WebIM.Emoji 里特定的字符串,connection 就会自动将这些字符串和其它文字按顺序组合成一个数组,每一个数组元素的结构为 {type:'emoji(或者txt)',data:'msg(或者src)'}

当 type='emoji' 时,data 表示表情图像的路径

当 type='txt' 时,data 表示文本消息


发送贴图消息

Web IM SDK本身不支持截图,使用下述代码可以实现用户粘贴图片至输入框后发送。

单聊发送贴图消息的代码示例如下:

// 单聊贴图发送
document.addEventListener('paste', function (e) {
    if (e.clipboardData && e.clipboardData.types) {
        if (e.clipboardData.items.length > 0) {
            if (/^image\/\w+$/.test(e.clipboardData.items[0].type)) {
                var blob = e.clipboardData.items[0].getAsFile();
                var url = window.URL.createObjectURL(blob);
                var id = conn.getUniqueId();             // 生成本地消息id
                var msg = new WebIM.message('img', id);  // 创建图片消息
                msg.set({
                    apiUrl: WebIM.config.apiURL,
                    file: {data: blob, url: url},
                    to: 'username',                      // 接收消息对象
                    chatType: 'singleChat',
                    onFileUploadError: function (error) {
                        console.log('Error');
                    },
                    onFileUploadComplete: function (data) {
                        console.log('Complete');
                    },
                    success: function (id) {
                        console.log('Success');
                    },
                    fail: function(e){
                        console.log("Fail"); //如禁言、拉黑后发送消息会失败
                    }
                });
                conn.send(msg.body);
            }
        }
    }
});

发送URL图片消息

App端需要开发者自己实现下载,Web端需要在 WebIMConfig.js中 设置 useOwnUploadFun: true

单聊通过URL发送图片消息的代码示例如下:

// 单聊通过URL发送图片消息
 var sendPrivateUrlImg = function () {
    var id = conn.getUniqueId();                   // 生成本地消息id
    var msg = new WebIM.message('img', id);        // 创建图片消息
    var option = {
        body: {
          type: 'file',
          url: url,
          size: {
            width: msg.width,
            height: msg.height,
           },
          length: msg.length,
          filename: msg.file.filename,
          filetype: msg.filetype
        },
        to: 'username',  // 接收消息对象
    };
    msg.set(option);
    conn.send(msg.body);
 }

发送命令消息

发送命令消息的代码示例如下:

var id = conn.getUniqueId();            //生成本地消息id
var msg = new WebIM.message('cmd', id); //创建命令消息

msg.set({
  to: 'username',                        //接收消息对象
  action : 'action',                     //用户自定义,cmd消息必填
  ext :{'extmsg':'extends messages'},    //用户自扩展的消息内容(群聊用法相同)
  success: function ( id,serverMsgId ) {}, //消息发送成功回调 
  fail: function(e){
      console.log("Fail"); //如禁言、拉黑后发送消息会失败
  }
});   

conn.send(msg.body);

发送附件消息

附件消息是消息中重要的消息类型,附件消息主要包括以下几种:

  • 图片消息
  • 文件消息
  • 音频消息
  • 视频消息

· 发送附件消息,SDK 自动分两步完成:

  1. 上传附件到服务器,并得到服务返回的附件信息等;
  2. 发送附件消息,消息体包含附件的基本信息、服务器路径、secret 等。

注意:web端和小程序发送附件消息是有区别的,小程序发送附件消息需要自己将附件上传到环信服务器,下面以发送图片消息展示小程序怎样发送附件消息

单聊发送图片消息示例如下:

// web单聊发送图片消息
var sendPrivateImg = function () {
    var id = conn.getUniqueId();                   // 生成本地消息id
    var msg = new WebIM.message('img', id);        // 创建图片消息
    var input = document.getElementById('image');  // 选择图片的input
    var file = WebIM.utils.getFileUrl(input);      // 将图片转化为二进制文件
    var allowType = {
        'jpg': true,
        'gif': true,
        'png': true,
        'bmp': true
    };
    if (file.filetype.toLowerCase() in allowType) {
        var option = {
            apiUrl: WebIM.config.apiURL,
            file: file,
            length: '3000',                       // 视频文件时,单位(ms)
            ext: {
                file_length: file.data.size       // 文件大小
            },
            to: 'username',                       // 接收消息对象
            chatType: 'singleChat',               // 设置为单聊
            onFileUploadError: function () {      // 消息上传失败
                console.log('onFileUploadError');
            },
            onFileUploadComplete: function () {   // 消息上传成功
                console.log('onFileUploadComplete');
            },
            success: function () {                // 消息发送成功
                console.log('Success');
            },
            fail: function(e){
                console.log("Fail");              //如禁言、拉黑后发送消息会失败
            },
            flashUpload: WebIM.flashUpload
        };
        msg.set(option);
        conn.send(msg.body);
    }
};

// 小程序单聊发送图片消息
sendImage(){
    const me = this;
    wx.chooseImage({
        count: 1,
        sizeType: ["original", "compressed"],
        sourceType: ["album"],
        success(res){
            me.upLoadImage(res);
        }
    });
}
upLoadImage(res){
    const me = this;
    let tempFilePaths = res.tempFilePaths;
    let token = WebIM.conn.context.accessToken
    wx.getImageInfo({
	src: res.tempFilePaths[0],
	success(res){
        let allowType = {jpg: true, gif: true, png: true, bmp: true};
        let str = WebIM.config.appkey.split("#");
        let width = res.width;
        let height = res.height;
        let index = res.path.lastIndexOf(".");
        let filetype = (~index && res.path.slice(index + 1)) || "";
        let domain = wx.WebIM.conn.apiUrl + '/'
        if(filetype.toLowerCase() in allowType){
            wx.uploadFile({
                url: domain + str[0] + "/" + str[1] + "/chatfiles",
                filePath: tempFilePaths[0],
                name: "file",
                header: {
                    "Content-Type": "multipart/form-data",
                    Authorization: "Bearer " + token
                },
                success(res){
                    if(res.statusCode === 400){
                        // 图片上传阿里云检验不合法
                        let errData = JSON.parse(res.data);
                        if (errData.error === 'content improper') {
                            wx.showToast({
                                title: '图片不合法'
                            });
                            return
                        }
                    }
                    let data = res.data;
                    let dataObj = JSON.parse(data);
                    let id = WebIM.conn.getUniqueId(); // 生成本地消息 id
                    let msg = new WebIM.message(msgType.IMAGE, id);
                    let file = {
                        type: msgType.IMAGE,
                        size: {
                            width: width,
                            height: height
                        },
                        url: dataObj.uri + "/" + dataObj.entities[0].uuid,
                        filetype: filetype,
                        filename: tempFilePaths[0]
                    };
                    msg.set({
                        apiUrl: WebIM.config.apiURL,
                        body: file,
                        from: me.data.username.myName,
                        to: me.getSendToParam(),
                        chatType: me.data.chatType,
                        success: function (argument) {},
                        fail: function(e){
                            console.log("Fail"); //如禁言、拉黑后发送消息会失败
                        }
                    });
                    WebIM.conn.send(msg.body);
                }
            });
        }
    }
});
}

单聊发送文件消息示例如下:

// 单聊发送文件消息
var sendPrivateFile = function () {
    var id = conn.getUniqueId();                   // 生成本地消息id
    var msg = new WebIM.message('file', id);        // 创建文件消息
    var input = document.getElementById('file');  // 选择文件的input
    var file = WebIM.utils.getFileUrl(input);      // 将文件转化为二进制文件
    var allowType = {
        'jpg': true,
        'gif': true,
        'png': true,
        'bmp': true,
        'zip': true,
        'txt': true,
        'doc':true,
        'pdf': true
    };
    if (file.filetype.toLowerCase() in allowType) {
        var option = {
            apiUrl: WebIM.config.apiURL,
            file: file,
            to: 'username',                       // 接收消息对象
            chatType: 'singleChat',               // 设置单聊
            onFileUploadError: function () {      // 消息上传失败
                console.log('onFileUploadError');
            },
            onFileUploadComplete: function () {   // 消息上传成功
                console.log('onFileUploadComplete');
            },
            success: function () {                // 消息发送成功
                console.log('Success');
            },
            fail: function(e){
                console.log("Fail");              //如禁言、拉黑后发送消息会失败
            },
            flashUpload: WebIM.flashUpload,
            ext: {file_length: file.data.size}
        };
        msg.set(option);
        conn.send(msg.body);
    }
};

单聊发送音频消息示例如下:

// 单聊发送音频消息
var sendPrivateAudio = function () {
    var id = conn.getUniqueId();                   // 生成本地消息id
    var msg = new WebIM.message('audio', id);      // 创建音频消息
    var input = document.getElementById('audio');  // 选择音频的input
    var file = WebIM.utils.getFileUrl(input);      // 将音频转化为二进制文件
    var allowType = {
        'mp3': true,
        'amr': true,
        'wmv': true
    };
    if (file.filetype.toLowerCase() in allowType) {
        var option = {
            apiUrl: WebIM.config.apiURL,
            file: file,
            length: '3',                          // 音频文件时长,单位(s)
            to: 'username',                       // 接收消息对象
            chatType: 'singleChat',               // 设置单聊
            onFileUploadError: function () {      // 消息上传失败
                console.log('onFileUploadError');
            },
            onFileUploadComplete: function () {   // 消息上传成功
                console.log('onFileUploadComplete');
            },
            success: function () {                // 消息发送成功
                console.log('Success');
            },
            fail: function(e){
                console.log("Fail");              //如禁言、拉黑后发送消息会失败
            },
            flashUpload: WebIM.flashUpload,
            ext: {file_length: file.data.size}
        };
        msg.set(option);
        conn.send(msg.body);
    }
};

单聊发送视频消息示例如下:

// 单聊发送视频消息
var sendPrivateVideo = function () {
    var id = conn.getUniqueId();                   // 生成本地消息id
    var msg = new WebIM.message('video', id);      // 创建视频消息
    var input = document.getElementById('video');  // 选择视频的input
    var file = WebIM.utils.getFileUrl(input);      // 将视频转化为二进制文件
    var allowType = {
        'mp4': true,
        'wmv': true,
        'avi': true,
        'rmvb':true,
        'mkv':true
    };
    if (file.filetype.toLowerCase() in allowType) {
        var option = {
            apiUrl: WebIM.config.apiURL,
            file: file,
            to: 'username',                       // 接收消息对象
            chatType: singleChat,                 // 设置为单聊
            onFileUploadError: function () {      // 消息上传失败
                console.log('onFileUploadError');
            },
            onFileUploadComplete: function () {   // 消息上传成功
                console.log('onFileUploadComplete');
            },
            success: function () {                // 消息发送成功
                console.log('Success');
            },
            fail: function(e){
                console.log("Fail");              // 如禁言、拉黑后发送消息会失败
            },
            flashUpload: WebIM.flashUpload,
            ext: {file_length: file.data.size}
        };
        msg.set(option);
        conn.send(msg.body);
    }
};

发送自定义消息

单聊发送自定义消息示例如下:

var sendCustomMsg = function () {
    var id = conn.getUniqueId();                 // 生成本地消息id
    var msg = new WebIM.message('custom', id);   // 创建自定义消息
    var customEvent = "customEvent";             // 创建自定义事件
    var customExts = {};                         // 消息内容,key/value 需要 string 类型
    msg.set({
        to: 'username',                          // 接收消息对象(用户id)
        customEvent,
        customExts,
        ext:{},                                  // 消息扩展
        roomType: false,
        success: function (id, serverMsgId) {},
        fail: function(e){}
    });
    conn.send(msg.body);
};

SDK增值服务。

/**
 * 发送撤回消息
  * @param {Object} option - 
 * @param {Object} option.mid -   回撤消息id
 * @param {Object} option.to -   消息的接收方
 * @param {Object} option.type -  chat(单聊) groupchat(群组) chatroom(聊天室)
 */
WebIM.conn.recallMessage(option)

查看回调函数,接收各类消息的回调函数代码如下:

conn.listen({
    onOpened: function ( message ) {          //连接成功回调
    },  
    onClosed: function ( message ) {},         //连接关闭回调
    onTextMessage: function ( message ) {},    //收到文本消息
    onEmojiMessage: function ( message ) {},   //收到表情消息
    onPictureMessage: function ( message ) {}, //收到图片消息
    onCmdMessage: function ( message ) {},     //收到命令消息
    onAudioMessage: function ( message ) {},   //收到音频消息
    onLocationMessage: function ( message ) {},//收到位置消息
    onFileMessage: function ( message ) {},    //收到文件消息
    onCustomMessage: function ( message ) {},  //收到自定义消息
    onVideoMessage: function (message) {
        var node = document.getElementById('privateVideo');
        var option = {
            url: message.url,
            headers: {
              'Accept': 'audio/mp4'
            },
            onFileDownloadComplete: function (response) {
                var objectURL = WebIM.utils.parseDownloadResponse.call(conn, response);
                node.src = objectURL;
            },
            onFileDownloadError: function () {
                console.log('File down load error.')
            }
        };
        WebIM.utils.download.call(conn, option);
    },   //收到视频消息
    onPresence: function ( message ) {},       //处理“广播”或“发布-订阅”消息,如联系人订阅请求、处理群组、聊天室被踢解散等消息
    onRoster: function ( message ) {},         //处理好友申请
    onInviteMessage: function ( message ) {},  //处理群组邀请
    onOnline: function () {},                  //本机网络连接成功
    onOffline: function () {},                 //本机网络掉线
    onError: function ( message ) {},          //失败回调
    onBlacklistUpdate: function (list) {       //黑名单变动
        // 查询黑名单,将好友拉黑,将好友从黑名单移除都会回调这个函数,list则是黑名单现有的所有好友信息
        console.log(list);
    },
    onRecallMessage: function( message ){},    //收到消息撤回回执
    onReceivedMessage: function(message){},    //收到消息送达服务器回执
    onDeliveredMessage: function(message){},   //收到消息送达客户端回执
    onReadMessage: function(message){},        //收到消息已读回执
    onCreateGroup: function(message){},        //创建群组成功回执(需调用createGroupNew)
    onMutedMessage: function(message){}        //如果用户在A群组被禁言,在A群发消息会走这个回调并且消息不会传递给群其它成员
});

这里主要介绍几种特殊的消息处理示例

  • 表情消息
  • 图片消息
  • 音频消息

表情消息

收到表情消息的处理示例:

conn.listen({
    onEmojiMessage: function (message) {
        console.log('Emoji');
        var data = message.data;
        for(var i = 0 , l = data.length ; i < l ; i++){
            console.log(data[i]);
        }
    },   //收到表情消息
});

注意:当为 WebIM 添加了 Emoji 属性后,若发送的消息含 WebIM.Emoji 里特定的字符串,connection 就会自动将这些字符串和其它文字按顺序组合成一个数组,每一个数组元素的结构为 {type:'emoji(或者txt)',data:type}

当 type='emoji' 时,data 表示表情图像的路径

当 type='txt' 时,data 表示文本消息

图片消息

收到图片消息的处理示例:

conn.listen({
    onPictureMessage: function (message) {
        console.log("Location of Picture is ", message.url);
    }, //收到图片消息
});

音频消息

收到音频消息的处理示例:

conn.listen({
  onAudioMessage: function ( message ) {
    // 在这里接收音频消息
  }
})
// 小程序播放
playAudio(message){
  let audioCtx = wx.createInnerAudioContext();
  let curl = ''
  wx.downloadFile({
  url: message.url,
  header: {
    "X-Requested-With": "XMLHttpRequest",
    Accept: "audio/mp3",
    Authorization: "Bearer " + this.data.msg.msg.token
  },
  success(res){
    curl = res.tempFilePath;
    audioCtx.src = curl;
    audioCtx.play();			
  },
  fail(e){
    wx.showToast({
      title: "下载失败",
      duration: 1000
    });
  }
});

// web
addAudioMessage: (message, bodyType) => {
  return (dispatch, getState) => {
    let options = {
          url: message.url,
          headers: {
            Accept: 'audio/mp3'
          },
          onFileDownloadComplete: function (response) {
            let objectUrl = WebIM.utils.parseDownloadResponse.call(WebIM.conn, response)
            message.audioSrcUrl = message.url
              message.url = objectUrl
            },
          onFileDownloadError: function () {}
        }
      WebIM.utils.download.call(WebIM.conn, options)
   }
}

注意:

  • 对于图片、语音消息需要先进行下载,然后进行显示或者播放处理。

API

示例中使用到的 API


漫游消息,SDK增值功能

/**
 * 获取对话历史消息
 * @param {Object} options
 * @param {String} options.queue   - 对方用户id(如果用户id内含有大写字母请改成小写字母)/群组id/聊天室id
 * @param {String} options.count   - 每次拉取条数
 * @param {Boolean} options.isGroup - 是否是群聊,默认为false
 * @param {Function} options.success
 * @param {Funciton} options.fail
 */
var options = {
    queue: "test1",
    isGroup: false,
    count: 10,
    success: function(){},
    fail: function(){}
}
WebIM.conn.fetchHistoryMessages(options)

SDK 在收到新消息时会直接转发给登录用户,接收到消息后,Demo 中会在好友或者群组的后面显示红色消息数,具体样式开发者可自行处理。


单聊:

  • 已送达回执:在 webim.config.js 中配置 delivery 为 true ,在收到消息时会自动发送已送达回执,对方收到已送达回执的回调函数是 onDeliveredMessage
  • 已读回执:当认为用户已读某条(些)消息时,可以生成已读回执,再进行发送

对方收到已送达回执的回调函数是 onReadMessage

var bodyId = message.id;         // 需要发送已读回执的消息id
var msg = new WebIM.message('read',conn.getUniqueId());
msg.set({
    id: bodyId
    ,to: message.from
});
conn.send(msg.body);

群聊SDK增值功能

  • 发送群可以收已读回执的消息
sendGroupReadMsg = () => {
  let id = conn.getUniqueId();                 // 生成本地消息id
  let msg = new WebIM.message('txt', id);      // 创建文本消息
  msg.set({
     msg: 'message content',                  // 消息内容
     to: 'username',                          // 接收消息对象(用户id)
     chatType: 'groupChat',                   // 设置为群聊
     success: function (id, serverMsgId) {
         console.log('send private text Success');
     },
     fail: function(e){
         console.log("Send private text error");
     }
  });
  msgObj.body.msgConfig = { allowGroupAck: true }
  conn.send(msg.body);
}
 
  • 收到需要回执的消息后发送回执
sendReadMsg = () => {
  let msg = new WebIM.message("read", WebIM.conn.getUniqueId());
  msg.body.chatType = "groupChat";
  msg.body.msgConfig = { allowGroupAck: true };
  msg.body.ackContent = JSON.stringify({});
  WebIM.conn.send(msg.body);
}
  • 监听收到群组消息回执:分两种情况 1、正常在线时可以在 onReadMessage 函数里监听到回执,2、离线时收到群组消息回执,登录后会在onStatisticMessage函数里监听到回执
// 在线时可以在onReadMessage里监听
onReadMessage: (message) => {
  const { mid } = message;
  const msg = {
    id: mid
  };
  if(message.groupReadCount){
    // 消息阅读数
    msg.groupReadCount = message.groupReadCount[message.mid];
  }
}
      
// 离线时收到回执,登录后会在这里监听到
onStatisticMessage: (message) => {
  let statisticMsg = message.location && JSON.parse(message.location);
  let groupAck = statisticMsg.group_ack || [];
}
  • 查看读过消息的用户
WebIM.conn.getGroupMsgReadUser({
    msgId,  // 消息id
    groupId // 群组id
}).then((res)=>{
    console.log(res)
})

上一页:Web SDK API Doc

下一页: 好友管理