这是本文档旧的修订版!
消息
消息是客户端集成中最重要的功能之一,WebIM 消息的使用方法主要为 :
- 构造消息
- 发送消息
- 消息撤回
- 接收消息
- 处理消息
- 拉取历史消息
- 新消息提醒
- 消息回执
通过对消息的集成,您可以最快速的集成体验 IM 收发消息的流畅体验。
构造消息
var msg = new WebIM.message('txt', id);
msg.set(option); //消息内容option,下面会有详细介绍
msg.setGroup('groupchat'); //用于设置当前聊天模式为多人聊天,如聊天室/群组。单聊不调用此方法
注意: 发送ext 扩展消息,可以没有这个字段,但是如果有,值不能是“ext:null”这种形式,否则出错
发送消息
环信支持向单聊、群组及聊天室中发送:
- 文本消息
- 表情消息
- 贴图消息
- URL图片消息
- 命令消息
- 附件消息
- 自定义消息
多样化的消息类型,覆盖多种场景下的消息需求。
发送文本消息(单聊、扩展)
单聊发送文本消息示例如下:
// 单聊发送文本消息
var sendPrivateText = function () {
var id = conn.getUniqueId(); // 生成本地消息id
var msg = new WebIM.message('txt', id); // 创建文本消息
msg.set({
msg: 'message content', // 消息内容
to: 'username', // 接收消息对象(用户id)
roomType: false,
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);
};
发送文本消息(群组)
群组发送文本消息示例如下:
// 群组发送文本消息
var sendGroupText = function () {
var id = conn.getUniqueId(); // 生成本地消息id
var msg = new WebIM.message('txt', id); // 创建文本消息
var option = {
msg: 'message content', // 消息内容
to: 'group id', // 接收消息对象(群组id)
roomType: false, // 群聊类型,true时为聊天室,false时为群组
ext: {}, // 扩展消息
success: function () {
console.log('send room text success');
}, // 对成功的相关定义,sdk会将消息id登记到日志进行备份处理
fail: function () {
console.log('failed');
} // 对失败的相关定义,sdk会将消息id登记到日志进行备份处理
};
msg.set(option);
msg.setGroup('groupchat'); // 群聊类型
conn.send(msg.body);
};
发送文本消息(聊天室)
聊天室发送文本消息示例如下:
// 聊天室发送文本消息
var sendRoomText = function () {
var id = conn.getUniqueId(); // 生成本地消息id
var msg = new WebIM.message('txt', id); // 创建文本消息
var option = {
msg: 'message content', // 消息内容
to: 'chatroom id', // 接收消息对象(聊天室id)
roomType: true, // 群聊类型,true时为聊天室,false时为群组
ext: {}, // 扩展消息
success: function () {
console.log('send room text success');
}, // 对成功的相关定义,sdk会将消息id登记到日志进行备份处理
fail: function () {
console.log('failed');
} // 对失败的相关定义,sdk会将消息id登记到日志进行备份处理
};
msg.set(option);
msg.setGroup('groupchat'); // 群聊类型
conn.send(msg.body);
};
注意:单聊和群聊的表现示例基本一样,区别在于
- 接受消息的对象不同,单聊 to 的对象为用户 ID ,群组/聊天室 to 的对象为群组/聊天室 ID
- 聊天室/群组 比单聊代码中调一个方法
msg.setGroup('groupchat')
- 通过
roomType
区分聊天室、群组,true为聊天室,false为群组
API
发送表情消息
- 发送表情同发送文本消息,需要在对方客户端将表情文本进行解析成图片。
- 示例代码为单聊,贴图发送至群组和聊天室时需参考发送文本消息修改
roomType
和msg.setGroup('groupchat')
。
单聊发送表情消息的代码示例如下:
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)
roomType: false,
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 表示文本消息。
API
发送贴图消息
- Web IM SDK本身不支持截图,使用下述代码可以实现用户粘贴图片至输入框后发送。
- 示例代码为单聊,贴图发送至群组和聊天室时需参考发送文本消息修改
roomType
和msg.setGroup('groupchat')
。
单聊发送贴图消息的代码示例如下:
// 单聊贴图发送
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', // 接收消息对象
roomType: false,
onFileUploadError: function (error) {
console.log('Error');
},
onFileUploadComplete: function (data) {
console.log('Complete');
},
success: function (id) {
console.log('Success');
}
});
conn.send(msg.body);
}
}
}
});
API
发送URL图片消息
- 示例代码为单聊,贴图发送至群组和聊天室时需参考发送文本消息修改
roomType
和msg.setGroup('groupchat')
。
单聊通过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);
}
API
发送命令消息
发送命令消息的代码示例如下:
var id = conn.getUniqueId(); //生成本地消息id
var msg = new WebIM.message('cmd', id); //创建命令消息
msg.set({
msg: 'msg',
to: 'username', //接收消息对象
action : 'action', //用户自定义,cmd消息必填
ext :{'extmsg':'extends messages'}, //用户自扩展的消息内容(群聊用法相同)
success: function ( id,serverMsgId ) {}//消息发送成功回调
});
if ( /*如果是发送到群组*/ ) {
msg.setGroup('groupchat');
} else if ( /*如果是发送到聊天室*/ ) {
msg.body.roomType = true;
msg.setGroup('groupchat');
}
conn.send(msg.body);
API
发送附件消息
附件消息是消息中重要的消息类型,附件消息主要包括以下几种:
- 图片消息
- 文件消息
- 音频消息
- 视频消息
· 发送附件消息,SDK 自动分两步完成:
- 上传附件到服务器,并得到服务返回的附件信息等;
- 发送附件消息,消息体包含附件的基本信息、服务器路径、secret 等。
· 示例代码为单聊,贴图发送至群组和聊天室时需参考发送文本消息修改roomType
和msg.setGroup('groupchat')
。
单聊发送图片消息示例如下:
// 单聊发送图片消息
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,
to: 'username', // 接收消息对象
roomType: false,
onFileUploadError: function () { // 消息上传失败
console.log('onFileUploadError');
},
onFileUploadComplete: function () { // 消息上传成功
console.log('onFileUploadComplete');
},
success: function () { // 消息发送成功
console.log('Success');
},
flashUpload: WebIM.flashUpload
};
msg.set(option);
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', // 接收消息对象
roomType: false,
onFileUploadError: function () { // 消息上传失败
console.log('onFileUploadError');
},
onFileUploadComplete: function () { // 消息上传成功
console.log('onFileUploadComplete');
},
success: function () { // 消息发送成功
console.log('Success');
},
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,
to: 'username', // 接收消息对象
roomType: false,
onFileUploadError: function () { // 消息上传失败
console.log('onFileUploadError');
},
onFileUploadComplete: function () { // 消息上传成功
console.log('onFileUploadComplete');
},
success: function () { // 消息发送成功
console.log('Success');
},
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', // 接收消息对象
roomType: false,
onFileUploadError: function () { // 消息上传失败
console.log('onFileUploadError');
},
onFileUploadComplete: function () { // 消息上传成功
console.log('onFileUploadComplete');
},
success: function () { // 消息发送成功
console.log('Success');
},
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);
};
API
消息撤回
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群发消息会走这个回调并且消息不会传递给群其它成员
});
API
处理消息
这里主要介绍几种特殊的消息处理示例
- 表情消息
- 图片消息
- 音频消息
表情消息
收到表情消息的处理示例:
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 ) {
var options = { url: message.url };
options.onFileDownloadComplete = function ( response ) {
//音频下载成功,需要将response转换成blob,使用objectURL作为audio标签的src即可播放。
var objectURL = WebIM.utils.parseDownloadResponse.call(Demo.conn, response);
};
options.onFileDownloadError = function () {
//音频下载失败
};
//通知服务器将音频转为mp3
options.headers = {
'Accept': 'audio/mp3'
};
WebIM.utils.download.call(conn, options);
}
})
注意:
- conn.listen() 中注册不同消息接收 handler 之后,可自行解析消息体,定位聊天好友,并追加到与其聊天窗口。具体参考 http://webim.easemob.com 效果。
- 对于图片、语音消息需要先进行下载,然后进行显示或者播放处理。
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
});
Demo.conn.send(msg.body);
群聊:
- 发送群可以收已读回执的消息
sendGroupReadMsg = () => {
let id = conn.getUniqueId(); // 生成本地消息id
let msg = new WebIM.message('txt', id); // 创建文本消息
msg.set({
msg: 'message content', // 消息内容
to: 'username', // 接收消息对象(用户id)
roomType: true,
success: function (id, serverMsgId) {
console.log('send private text Success');
},
fail: function(e){
console.log("Send private text error");
}
});
msg.setGroup("groupchat");
msgObj.body.msgConfig = { allowGroupAck: true }
conn.send(msg.body);
}
- 收到需要回执的消息后发送回执
sendReadMsg = () => {
let msg = new WebIM.message("read", WebIM.conn.getUniqueId());
msg.body.group = "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
success(data){
resolve(data);
},
error(err){
reject(err);
},
});