1.0.6(2016.1.12)
修复pc客户端发送链接后,刷新页面获取漫游消息后链接不显示的问题 增加群消息返回的type(见下方Base.startListenAllMsg)
1.0.5(2016.1.7)
修复Base.getNick()的bug
1.0.1(2015.12.24)
重构了登录逻辑,增加更加详细的错误日志,错误code见下方 重构了上传图片逻辑,修复手机端传大图carsh问题 增加了KICK_OFF事件,监听到此事件,表示当前登录账号被踢下线,只有在调用startListenMsg与startListenAllMsg时才会触发 表情插件增加htmlEncode方法,代替原来的encode方法,防止xss !修改群聊实时消息的返回格式与字段,统一成与单聊一致(如果使用了低版本的wsdk中的群聊接口,升级前请注意)
0.3.7(2015.11.30)
修复ie7及部分ie8下登录超时的问题
0.3.4(2015.11.26)
优化登录接口,增加登录失败log
0.3.2(2015.11.20)
Chat模块下增加“获取用户在线状态”接口
0.3.1(2015.11.19)
修复ie低版本下出现空白块的问题
0.3.0(2015.11.17)
发送消息时,带上nickname,解决ios端最近联系人,发送者位置显示空白的问题
0.2.7(2015.11.6)
修复某些机器上firefox内无法登陆问题
0.2.5(2015.11.5)
修复通过获取历史消息接口获得的语音消息的消息类型不正确的bug(从1变成2)
0.2.1(2015.11.03)
修复无法在ios端微信中登录的问题
0.1.8 (2015.10.13)
修复了英文账号中包含大小写字符后,发送消息无法收到问题 修复了部分机器ie8以下,无法发送消息的问题
0.1.6 (2015.10.9)
新增表情插件,支持表情渲染,表情encode/decode等函数 修复上传图片接口bug
0.1.0 (2015.9.1)
修改模块名称及部分函数的调用名称 getHistory与实时消息返回统一的数据格式 新增单聊发送自定义消息接口 新增插件模块 插件模块下,新增上传图片接口
0.0.9 (2015.8.10)
新增了部分群相关的接口 修改了整体的调用方式 细分了消息监听的事件名称
0.0.8
新增“sendMsgToCustomService”接口 “sendMsg”, “setReadState”,“getHistory”新增了hasPrefix字段 修改“startReceiveOne”接口的入参,由之前的只传touid改为传对象,包含touid,新增hasPreifx字段
0.0.5
增加版本管理,不会在发布新版本后,对线上版本造成影响
在你页面你的js前中加入<script src="https://g.alicdn.com/aliww/h5.openim.sdk/1.0.6/scripts/wsdk.js"></script>
<!doctype html> <html> <head> </head> <body> </body> <!-- IE8及以下支持JSON --> <!--[if lt IE 9]> <script src="https://g.alicdn.com/aliww/ww/json/json.js" charset="utf-8"></script> <![endif]--> <!-- WSDK--> <script src="https://g.alicdn.com/aliww/h5.openim.sdk/1.0.6/scripts/wsdk.js"></script> <!--你的js--> <script src="your.js"></script> </html>
1000: 'SUCCESS', // 成功 1001: 'NOT_LOGIN', // 未登录 1002: 'TIMEOUT', // 超时 1003: 'OTHER_ERROR', // 其他错误,返回的数据格式不正确,拿不到期望的数据 1004: 'PARSE_ERROR', // 解析json错误 1005: 'NET_ERROR', // 网络错误 1006: 'KICK_OFF', // 被踢下线 1007: 'LOGIN_INFO_ERROR', // 登录信息错误 1008: 'ALREADY_LOGIN', // 已经登录(本地判断) 1009: 'NO_MESSAGE' // 没有新消息(用在监听消息的事件返回上) 1010: 'PARAM_ERROR' // 参数错误 1011: '' // 登录太频繁 1012: '' // 已经登录(服务端判断) 1013: '' // 用户名不存在 1014: '' // 密码错误
object.Event.on(event, callback, [context])
var sdk = new WSDK(); var obj = { text: 'wsdk' }; sdk.Event.on('START_RECEIVE_ONE', function(data){ console.log(data); console.log(this.text); // wsdk }, obj);
object.Event.off([event], [callback])
var sdk = new WSDK(); // 移除START_RECEIVE_ONE事件的callback1回调 sdk.Event.off('START_RECEIVE_ONE', callback1); // 移除START_RECEIVE_ONE事件的所有回调 sdk.Event.off('START_RECEIVE_ONE'); // 移除所有的事件回调 sdk.Event.off();
object.Event.fire(event, [data])
var sdk = new WSDK(); sdk.Event.on('START_RECEIVE_ONE', function(data){ console.log(data); }); sdk.Event.fire('START_RECEIVE_ONE', {code: 1000, resultText: 'SUCCESS'}); // {code: 100, resultText: 'SUCCESS'}
object.Base.login(config)
config.appkey: appkey config.uid: 用户id config.credential: 登录凭证,请向你的服务端要 [config.toAppkey]: 当需要跨appkey聊天时使用 [config.timeout]: 超时时间,默认5000ms [config.success]: 登录成功回调 [config.error]: 登录失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Base.login({ uid:'uid', appkey: 'appkey', credential: 'credential', timeout: 4000, success: function(data){ // {code: 1000, resultText: 'SUCCESS'} console.log('login success', data); }, error: function(error){ // {code: 1002, resultText: 'TIMEOUT'} console.log('login fail', error); } });
object.Base.getUnreadMsgCount(config)
[config.count]: 一次获取条数,默认30 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Base.getUnreadMsgCount({ count: 10, success: function(data){ console.log('get unread msg count success' ,data); }, error: function(error){ console.log('get unread msg count fail' ,error); } });
内部需要区分是单聊的还是群聊的
当contact的值的前8位是chntribe时,表示是群聊,否则是单聊
object.Base.getRecentContact(config)
[config.count]: 一次获取的消息条数,默认30,最多100 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Base.getRecentContact({ count: 10, success: function(data){ console.log('get recent contact success' ,data); }, error: function(error){ console.log('get recent contact success' ,error); } }
object.Base.startListenAllMsg()
监听所有消息,包括成功和失败的消息: START_RECEIVE_ALL_MSG
所有成功的消息: MSG_RECEIVED
只监听成功的单聊消息:CHAT.MSG_RECEIVED
只监听成功的群聊消息:TRIBE.MSG_RECEIVED
群type | 描述 |
---|---|
1 | 普通消息 |
3 | 用户加入群 |
5 | 用户退出群 |
7 | 群主转让 |
8 | 取消管理员 |
9 | 用户被请出群 |
12 | 停用群 |
14 | 更新群信息 |
15 | 通知群名片修改 |
16 | 图片消息 |
35 | 被邀请者拒绝管理员加入群(用户手动拒绝) |
98 | 管理员拒绝用户加入群 |
101 | 被邀请者拒绝管理员加入群(用户在客户端有设置,系统自动拒绝) |
212 | 申请加入群消息 |
注:无法监听到自己发送的消息
var sdk = new WSDK(); sdk.Event.on('MSG_RECEIVED', function(data){ console.log(data); }); sdk.Base.startListenAllMsg();
object.Base.stopListenAllMsg()
var sdk = new WSDK(); sdk.Event.on('MSG_RECEIVED', function(data){ console.log(data); }); sdk.Base.stopListenAllMsg(); sdk.Base.stopListenAllMsg();
object.Base.getNick(longnick)
var sdk = new WSDK(); // 当前登录的appkey的前缀为iwangxin sdk.Base.getNick('iwangxinvisitor1'); // visitor1 // 内部会判断是否带有登录的前缀,如果没有会直接返回 sdk.Base.getNick('visitor1'); // visitor1
object.Chat.sendMsg(config)
config.touid: 对方nick config.msg: 消息内容 [config.msgType]: 消息类型 0:文本消息 1: 图片消息 2: 语音消息 [config.hasPrefix]: 传入的touid中是否已带有前缀 [config.success]: 发送消息成功回调 [config.error]: 发送消息失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Chat.sendMsg({ touid: 'touid', msg: '你好啊', success: function(data){ console.log('send success', data); }, error: function(error){ console.log('send fail', error); } });
object.Chat.sendCustomMsg(config)
config.touid: 对方nick config.msg: 消息内容 [config.summary]: 消息摘要 (如果不传,默认为msg的值) [config.hasPrefix]: 传入的touid中是否已带有前缀 [config.success]: 发送消息成功回调 [config.error]: 发送消息失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Chat.sendCustomMsg({ touid: 'touid', msg: 'xxx已经添加你为好友', summary: '添加好友', success: function(data){ console.log('send success', data); }, error: function(error){ console.log('send fail', error); } });
object.Chat.sendMsgToCustomService(config)
config.touid: 对方nick(当nick中已经带了:,不会再走分流) config.msg: 消息内容 [config.msgType]: 消息类型 0: 文本消息 1: 图片消息 [config.groupid]: 在千牛开启了分流后,得到的groupid [config.hasPrefix]:传入的touid是否已带有前缀 [config.nocache]: 不缓存联系人,每次都会重新走分流接口获取客服(不推荐) [config.success]: 发送消息成功回调 [config.error]: 发送消息失败回调
注:[ ]内的参数表示不是必填
注:默认给同一个主账号发消息,只会走一次分流接口,下次跟此主账号发消息时,还是用之前分流得到的子账号聊天,可以节省流量电量等,当然也可以通过传入nocache
强制再次获取分流账号,此时会重新获取子账号,但是不保证本次获取到的子账号一定跟之前的不一样
var sdk = new WSDK(); sdk.Chat.sendMsgToCustomService({ touid: 'touid', msg: '你好啊', success: function(data){ console.log('send success', data); }, error: function(error){ console.log('send fail', error); } });
object.Chat.setReadState(config)
config.touid: 对方nick [config.hasPrefix]: 传入的touid中是否已带有前缀 [config.timestamp]: 当前时间的秒数 [config.success]: 设置成功回调 [config.error]: 设置失败回调
注:[ ]内的参数表示不是必填
在最近联系人列表页面,点击某个联系人进行聊天时,如果此联系人有未读消息,需要手动的调用此方法,将此联系人的消息设置为已读
var sdk = new WSDK(); sdk.Chat.setReadState({ touid: 'touid', timestamp: Math.floor((+new Date())/1000), success: function(data){ console.log('set read state success', data); }, error: function(error){ console.log('set read state fail', error); } });
object.Chat.getHistory(config)
config.touid: 对方nick [config.hasPrefix]:传入的touid中是否已带前缀 [config.nextkey]: 分页获取漫游历史消息时,服务端返回的下一页分页标示,如果要获取下一页,需要将这个标示带上,默认为'' [config.count]: 一次获取的消息条数,默认20 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
注:返回的消息条数有可能会大于你设置的count条数,因为pc端发送的**图文/文本与链接**消息由于消息协议的原因会包含在一条消息内,但是h5端会把图文消息拆开成了多条
var sdk = new WSDK(), nextkey = ''; sdk.Chat.getHistory({ touid: 'touid', nextkey, nextkey, count: 10, success: function(data){ console.log('get history msg success', data); nextkey = data.data && data.data.next_key; }, error: function(error){ console.log('get history msg fail', error); } });
object.Chat.startListenMsg(config)
config.touid: 对方nick [config.hasPrefix]: 传入的touid是否已带有前缀
CHAT_START_RECEIVE_MSG
MSG_RECEIVED
或者 CHAT.MSG_RECEIVED
var sdk = new WSDK(); sdk.Event.on('CHAT.MSG_RECEIVED', function(data){ console.log(data); }); sdk.Chat.startListenMsg({touid: 'touid'});
object.Chat.stopListenMsg()
var sdk = new WSDK(); sdk.Event.on('CHAT.MSG_RECEIVED', function(data){ console.log(data); }); sdk.Chat.startListenMsg(); sdk.Chat.stopListenMsg();
object.Chat.getUserStatus(config)
config.uids: 需要获取的用户nick数组 [config.hasPrefix]:传入的uid中是否已带前缀 [config.charset]:传入的uid的编码,默认utf-8; 可选:gbk [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
注意:返回的状态值,0表示离线,1表示在线
注意:uids为数组,数组的长度不能超过30,即不能一次传超过30个的uid
注意:如果uids中的uid不带前缀,默认会拼接登录时传入的appkey对应的前缀,如果需要查询其他前缀的用户,请在传uids时,自己拼接完后在传,并且设置hasPrefix字段为true
注意:获取成功后,返回的状态也是数组,数组的顺序与你传入的uids的顺序一致
var sdk = new WSDK(), statusMap = { 0: '离线', 1: '在线' }; sdk.Chat.getUserStatus({ uids: ['iwangxinvisitor1','iwangxinvisitor2','iwangxinvisitor3'], hasPrefix: true, success: function(data){ console.log('visitor1的状态为': statusMap[data.result.status[0]]); console.log('visitor2的状态为': statusMap[data.result.status[1]]); console.log('visitor3的状态为': statusMap[data.result.status[2]]); }, error: function(){ console.log('getUserStatus fail'); } });
object.Tribe.sendMsg(config)
config.tid: 群号 config.msg: 消息内容 [config.msgTime]: 发送消息的时间(秒) [config.msgType]: 消息类型 0: 文本消息 1: 图片消息 [config.success]: 发送消息成功回调 [config.error]: 发送消息失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Tribe.sendMsg({ tid: 'tid', msg: '你好啊', success: function(data){ console.log(data); }, error: function(error){ console.log(error); } });
object.Tribe.getHistory(config)
config.tid: 群号 [config.nextkey]: 分页获取漫游历史消息时,服务端返回的下一页分页标示,如果要获取下一页,需要将这个标示带上,默认为'' [config.count]: 一次获取的消息条数,默认20 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
注:返回的消息条数有可能会大于你设置的count条数,因为pc端发送的**图文/文本与链接**消息由于消息协议的原因会包含在一条消息内,但是h5端会把图文消息拆开成了多条
var sdk = new WSDK(), nextkey = ''; sdk.Tribe.getHistory({ tid: 'tid', count: 10, nextkey: nextkey, success: function(data){ console.log('get history msg success', data); nextkey = data.data && data.data.next_key; }, error: function(error){ console.log('get history msg fail', error); } });
object.Tribe.getTribeInfo(config)
config.tid: 群号 [config.excludeFlag]: 群的类型(默认:0) 0: 所有类型的群的群信息 1: 普通群的群信息 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Tribe.getTribeInfo({ tid: 'tid', success: function(data){ console.log(data); }, error: function(error){ console.log(error); } });
object.Tribe.getTribeList(config)
config.tribeTypes: 群类型 0:普通群 1:多聊 2:企业群 可以传多个如[0,1,2] 单个或多个都必须为数组形式 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Tribe.getTribeList({ tribeTypes: [0,1,2], success: function(data){ console.log(data); }, error: function(error){ console.log(error); } });
object.Tribe.getTribeMembers(config)
config.tid: 群号 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Tribe.getTribeMembers({ tid: 'tid', success: function(data){ console.log(data); }, error: function(error){ console.log(error); } });
object.Tribe.responseInviteIntoTribe(config)
config.tid: 群号 config.validatecode: 收到消息中的validatecode值 与收到的邀请消息中的validatecode值相同表示同意加入,否则表示拒绝加入 config.recommender: 收到消息中的recommender值 config.manager: 收到消息中的manager值 [config.success]: 获取成功回调 [config.error]: 获取失败回调
注:[ ]内的参数表示不是必填
var sdk = new WSDK(); sdk.Tribe.responseInviteIntoTribe({ tid: 'tid', recommender: '', validatecode: '', manager: '', success: function(data){ console.log(data); }, error: function(error){ console.log(error); } });
object.Plugin.Image.upload(input[file])
[config.target]: 上传的input[file] dom元素,请传入原生dom [config.base64Img]:图片base64后的字符串 [config.ext]: 图片的格式 如:png,当传base64Img时,此字段必填 [config.timeout]: 超时时间,默认30000ms [config.success]: 登录成功回调 [config.error]: 登录失败回调
注:[ ]内的参数表示不是必填
可以传入target来上传图片,或者传入base64Img(图片base64后的字符串)与ext(图片格式)来上传图片
HTML:
<input type="file" id="J_fileInput" />
var input = document.getElementById('J_fileInput'); var sdk = new WSDK(); sdk.Plugin.Image.upload({ target: input, timeout: 20000, success: function(data){ console.log(data); }, error: function(error){ } });
var base64Img = '图片的base64字符串'; var ext = '图片的格式'; // png || jpg... sdk.Plugin.Image.upload({ base64Img: base64Img, ext: ext, timeout: 20000, success: function(data){ console.log(data); }, error: function(error){ } });
object.Plugin.Emot.emotTitles
object.Plugin.Emot.emotW320
object.Plugin.Emot.emotW640
object.Plugin.Emot.encode(str) object.Plugin.Emot.htmlEncode(str) 推荐使用此方法,可以防止xss
<img class="wsdk-emot" src="https://g.alicdn.com/aliww/h5-openim/0.0.1/faces/s077.png" alt="惊声尖叫">
[Function]object.Plugin.Emot.decode(str)
object.Plugin.Emot.splitByEmot(str)
object.Plugin.Emot.isEmot(str)
object.Plugin.Emot.render(config)
config.container: 表情框渲染的容器,原生dom [config.emots]: 表情的title文案列表,默认object.Plugin.Emot.emotTitles [config.emotsImg]: 表情的图片集合地址, 默认object.Plugin.Emot.emotW320 [config.emotSize]: 单个表情的大小,默认45(px) [config.row]: 一次展示的表情行数,默认7 [config.col]: 一次展示的表情列数,默认3 [config.trigger]: 切换表情的触发按钮,默认:true [config.onEmotClick]: 当表情被点击时的回调 [config.customStyle]: 当默认的样式不满足需求时,将customStyle设置为true,可以去除默认样式,自己在css文件中定义样式
注:[ ]内的参数表示不是必填
HTML
<div class="my-msg-content" id="myMsgCon"></div> <div class="my-soft-input"> <a href="javascript:;" id="myEmotTrigger">表情</a> <div id="myEmotBox" style="display:none"></div> </div> <div class="my-msg-input"> <textarea id="myMsgInput"></textarea> </div>
CSS
*{margin:0;padding:0;} .my-msg-content{ width: 400px; height: 200px; } .my-soft-input{ position: relative; width: 400px; height: 20px; } #myEmotBox{ position: absolute; width: 315px; height: 155px; border: 1px solid #ccc; background: #fff; bottom: 30px; } .my-msg-input textarea{ width: 400px; height: 100px; border: 1px solid #ccc; } /* 表情切换触发按钮样式 */ .wsdk-emot-trigger { text-align: center; } .wsdk-emot-trigger .wsdk-emot-trigger-item { display: inline-block; width: 8px; height: 8px; overflow: hidden; border-radius: 100%; margin-right: 8px; *zoom: 1; *display: inline; background: #ccc; } .wsdk-emot-trigger .wsdk-active { background: #f00; }
JS
var trigger = document.getElementById('myEmotTrigger'), box = document.getElementById('myEmotBox'), textarea = document.getElementById('myMsgInput'), msgCon = document.getElementById('myMsgCon'), isEmotInited = false, isEmotBoxShow = false, sdk = new WSDK(), Emot = sdk.Plugin.Emot; trigger.onclick = function(){ if(!isEmotInited){ Emot.render({ container: box, onEmotClick: emotClickHandler }); isEmotInited = true; } if(isEmotBoxShow){ box.style.display = 'none'; }else{ box.style.display = 'block'; } isEmotBoxShow = !isEmotBoxShow; }; textarea.onkeydown = function(ev){ if(ev.keyCode == 13 && this.value){ ev.preventDefault(); var encodeMsg = Emot.htmlEncode(this.value); var decodeMsg = Emot.decode(encodeMsg); console.log('用来发送的消息:', encodeMsg); console.log('用来显示的消息:', decodeMsg); renderMsg(decodeMsg); this.value = ''; } }; var emotClickHandler = function(emotTitle){ textarea.value += emotTitle; }; var renderMsg = function(msg){ var div = document.createElement('div'); div.innerHTML = msg; msgCon.appendChild(div); }