網(wǎng)易云Web SDK 開發(fā)手冊(cè)

點(diǎn)擊查看原文

Web SDK 開發(fā)手冊(cè)

SDK 概述

網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)開發(fā)框架, 屏蔽掉 IM 系統(tǒng)的復(fù)雜的細(xì)節(jié), 對(duì)外提供較為簡(jiǎn)潔的 API 接口, 方便第三方應(yīng)用快速集成 IM 功能。
網(wǎng)易云信還開發(fā)了可供開發(fā)者們參考拦焚,如何使用該SDK的Web Demo:

開發(fā)準(zhǔn)備

下載并引入 SDK 文件

  • 云信官網(wǎng)下載 Web SDK 并解壓
  • 目錄結(jié)構(gòu)介紹
  • 如果要在瀏覽器里面使用 SDK, 相應(yīng)的 JS 文件都在 js 目錄下.
  • 如果要在微信小程序里面使用 SDK, 相應(yīng)的 JS 文件在 weixin-app 目錄下.
  • 選擇并引入
  • 如果要使用 IM 功能, 請(qǐng)引入 NIM_Web_NIM_v.js
  • 如果通過 script 標(biāo)簽引入, 請(qǐng)通過 NIM 來獲取引用
  • 如果要使用聊天室功能, 請(qǐng)引入 NIM_Web_Chatroom_v.js
  • 如果通過 script 標(biāo)簽引入, 請(qǐng)通過 Chatroom 來獲取引用
  • 如果同時(shí)使用 IM 和聊天室功能, 請(qǐng)引入 NIM_Web_SDK_v.js
  • <p style='color: #d9534f;'>如果通過 script 標(biāo)簽引入, 請(qǐng)通過 SDK.NIMSDK.Chatroom 來獲取 NIMChatroom 的引用, 下文中的 API 都是通過 NIMChatroom 來調(diào)用的</p>
  • 如果要使用 IM 的插件版實(shí)時(shí)音視頻功能, 請(qǐng)引入 NIM_Web_Netcall_v.js, 通過 Netcall 來獲取引用, 調(diào)用 NIM.use(Netcall) 來加載實(shí)時(shí)音視頻插件
  • 如果要使用 IM 的WebRTC實(shí)時(shí)音視頻功能, 請(qǐng)引入 NIM_Web_WebRTC_v.js, 通過 WebRTC 來獲取引用, 調(diào)用 NIM.use(WebRTC) 來加載實(shí)時(shí)音視頻插件

打包

如果開發(fā)者選用 webpack/babel 來打包, 那么請(qǐng)使用 exclude 將 SDK 文件排除, 避免 babel 二次打包引起的錯(cuò)誤

瀏覽器兼容性

云信 Web SDK (不包含實(shí)時(shí)音視頻)兼容到 IE8

  • IE8/IE9 需要將項(xiàng)目部署在 HTTPS 環(huán)境下才能連接到云信服務(wù)器, 其它高級(jí)瀏覽器可以在 HTTP 或者 HTTPS 環(huán)境下連接到云信服務(wù)器

數(shù)據(jù)庫兼容性

在支持?jǐn)?shù)據(jù)庫的瀏覽器上 SDK 會(huì)將數(shù)據(jù)緩存到數(shù)據(jù)庫中, 后續(xù)同步都是增量更新, 加快初始化速度

是否支持?jǐn)?shù)據(jù)庫

// 通過此 `boolean` 值來查看 SDK 在某個(gè)瀏覽器上是否支持?jǐn)?shù)據(jù)庫
NIM.support.db

不使用數(shù)據(jù)庫

如果開發(fā)者不想使用數(shù)據(jù)庫, 那么可以設(shè)置初始化參數(shù)dbfalse來禁用數(shù)據(jù)庫

var nim = NIM.getInstance({
db: false
});

微信小程序

使用前請(qǐng)找技術(shù)支持開通功能

require

請(qǐng)查閱開發(fā)準(zhǔn)備來下載并引入 SDK 文件

// 只使用 NIM
var NIM = require('NIM_Web_NIM_v')
// 只使用 Chatroom
var Chatroom = require('NIM_Web_Chatroom_v')

接口調(diào)用

微信小程序的大部分接口跟瀏覽器環(huán)境完全一致, 如有不同會(huì)額外說明, 請(qǐng)查閱其它章節(jié)

真機(jī)準(zhǔn)備

微信公眾品臺(tái) > 設(shè)置 > 開發(fā)設(shè)置 > 服務(wù)器配置, 配置域名白名單. 注意一個(gè)月內(nèi)可申請(qǐng)3次修改, 請(qǐng)慎重修改.

設(shè)置 IM 需要的域名

  • request合法域名
  • lbs.netease.im
  • wlnimsc0.netease.im
  • socket合法域名
  • wlnimsc0.netease.im
  • uploadFile合法域名
  • nos.netease.com
  • downloadFile合法域名
  • nos.netease.com

設(shè)置聊天室需要的域名

  • request合法域名
  • wlnim43.netease.im
  • socket合法域名
  • wlnim43.netease.im
  • uploadFile合法域名
  • nos.netease.com
  • downloadFile合法域名
  • nos.netease.com

依賴說明

  • SDK 使用一系列開源庫來更好的完成工作, 所有庫均掛在 NIM 下面
  • SDK 使用 es5-shim 來讓低版本瀏覽器兼容 ES5 的部分方法
  • SDK 使用 platform.js 來檢測(cè)瀏覽器平臺(tái), 通過 NIM.platform 來獲取此庫的引用
  • SDK 使用 socket.io-client 0.9 來建立 Socket 連接, 通過 NIM.iowindow.io 來獲取此庫的引用

初始化 SDK

請(qǐng)查閱開發(fā)準(zhǔn)備來下載并引入 SDK 文件

示例代碼

var data = {};
// 注意這里, 引入的 SDK 文件不一樣的話, 你可能需要使用 SDK.NIM.getInstance 來調(diào)用接口
var nim = NIM.getInstance({
// debug: true,
appKey: 'appKey',
account: 'account',
token: 'token',
onconnect: onConnect,
onwillreconnect: onWillReconnect,
ondisconnect: onDisconnect,
onerror: onError
});
function onConnect() {
console.log('連接成功');
}
function onWillReconnect(obj) {
// 此時(shí)說明 SDK 已經(jīng)斷開連接, 請(qǐng)開發(fā)者在界面上提示用戶連接已斷開, 而且正在重新建立連接
console.log('即將重連');
console.log(obj.retryCount);
console.log(obj.duration);
}
function onDisconnect(error) {
// 此時(shí)說明 SDK 處于斷開狀態(tài), 開發(fā)者此時(shí)應(yīng)該根據(jù)錯(cuò)誤碼提示相應(yīng)的錯(cuò)誤信息, 并且跳轉(zhuǎn)到登錄頁面
console.log('丟失連接');
console.log(error);
if (error) {
switch (error.code) {
// 賬號(hào)或者密碼錯(cuò)誤, 請(qǐng)?zhí)D(zhuǎn)到登錄頁面并提示錯(cuò)誤
case 302:
break;
// 重復(fù)登錄, 已經(jīng)在其它端登錄了, 請(qǐng)?zhí)D(zhuǎn)到登錄頁面并提示錯(cuò)誤
case 417:
break;
// 被踢, 請(qǐng)?zhí)崾惧e(cuò)誤后跳轉(zhuǎn)到登錄頁面
case 'kicked':
break;
default:
break;
}
}
}
function onError(error) {
console.log(error);
}

參數(shù)解釋

  • debug: 是否開啟日志, 開發(fā)者可以開啟日志, 這樣 SDK 會(huì)將關(guān)鍵操作的信息打印到控制臺(tái)上, 便于調(diào)試
  • appKey: 在云信管理后臺(tái)查看應(yīng)用的 appKey
  • account: 帳號(hào), 應(yīng)用內(nèi)唯一
  • token: 帳號(hào)的 token, 用于建立連接
  • transports: 用于建立長(zhǎng)連接的協(xié)議數(shù)組脱盲,可不填,默認(rèn)為['websocket', 'xhr-polling']
  • 默認(rèn)狀態(tài) sdk優(yōu)先使用websocket連接,如果瀏覽器不支持websocket端蛆,則使用xhr-polling
  • 開發(fā)者可手動(dòng)設(shè)置連接及順序瞭稼,可支持選項(xiàng)包括websocket忽洛、xhr-polling、flashsocket
  • 示例如: transports: ['websocket'环肘、'xhr-polling'欲虚、'flashsocket']
  • onconnect: 連接建立后的回調(diào), 會(huì)傳入一個(gè)對(duì)象, 包含登錄的信息, 有以下字段
  • lastLoginDeviceId: 上次登錄的設(shè)備的設(shè)備號(hào)
  • connectionId: 本次登錄的連接號(hào)
  • ip: 客戶端IP
  • port: 客戶端端口
  • country: 本次登錄的國家
  • onwillreconnect: 即將重連的回調(diào)
  • 此時(shí)說明 SDK 已經(jīng)斷開連接, 請(qǐng)開發(fā)者在界面上提示用戶連接已斷開, 而且正在重新建立連接
  • 此回調(diào)會(huì)收到一個(gè)對(duì)象, 包含額外的信息, 有以下字段
  • duration: 距離下次重連的時(shí)間
  • retryCount: 重連嘗試的次數(shù)
  • ondisconnect: 斷開連接后的回調(diào)
  • 此時(shí)說明 SDK 處于斷開狀態(tài), 開發(fā)者此時(shí)應(yīng)該根據(jù)錯(cuò)誤碼提示相應(yīng)的錯(cuò)誤信息, 并且跳轉(zhuǎn)到登錄頁面
  • 此回調(diào)會(huì)收到一個(gè)對(duì)象, 包含錯(cuò)誤的信息, 有以下字段
  • code: 出錯(cuò)時(shí)的錯(cuò)誤碼, 可能為空
  • 302: 賬號(hào)或者密碼錯(cuò)誤, 請(qǐng)?zhí)D(zhuǎn)到登錄頁面并提示錯(cuò)誤
  • 417: 重復(fù)登錄, 已經(jīng)在其它端登錄了, 請(qǐng)?zhí)D(zhuǎn)到登錄頁面并提示錯(cuò)誤
  • 'kicked': 被踢
  • onerror: 發(fā)生錯(cuò)誤的回調(diào), 會(huì)傳入錯(cuò)誤對(duì)象

同步完成

SDK 在同步完成之后會(huì)通知開發(fā)者, 開發(fā)者可以在此回調(diào)之后再初始化自己的界面, 以及進(jìn)行其他操作, 同步的數(shù)據(jù)包括下面章節(jié)中的

  • 黑名單, 對(duì)應(yīng)回調(diào) onblacklist, 請(qǐng)參考用戶關(guān)系托管里面的初始化參數(shù)
  • 靜音列表, 對(duì)應(yīng)回調(diào) onmutelist, 請(qǐng)參考用戶關(guān)系托管里面的初始化參數(shù)
  • 好友, 對(duì)應(yīng)回調(diào) onfriends, 請(qǐng)參考好友關(guān)系托管里面的初始化參數(shù)
  • 我的名片, 對(duì)應(yīng)回調(diào) onmyinfo, 請(qǐng)參考用戶名片托管里面的初始化參數(shù)
  • 好友的名片, 對(duì)應(yīng)回調(diào) onusers, 請(qǐng)參考用戶名片托管里面的初始化參數(shù)
  • 群, 對(duì)應(yīng)回調(diào) onteams, 請(qǐng)參考群組里面的初始化參數(shù)
  • 會(huì)話, 對(duì)應(yīng)回調(diào) onsessions, 請(qǐng)參考會(huì)話里面的初始化參數(shù)
  • 漫游消息, 對(duì)應(yīng)回調(diào) onroamingmsgs, 請(qǐng)參考消息里面的初始化參數(shù)
  • 離線消息, 對(duì)應(yīng)回調(diào) onofflinemsgs, 請(qǐng)參考消息里面的初始化參數(shù)
  • 離線系統(tǒng)通知, 對(duì)應(yīng)回調(diào) onofflinesysmsgs, 請(qǐng)參考系統(tǒng)通知里面的初始化參數(shù)
  • 離線自定義系統(tǒng)通知, 對(duì)應(yīng)回調(diào) onofflinecustomsysmsgs, 請(qǐng)參考系統(tǒng)通知里面的初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onsyncdone: onSyncDone,
});
function onSyncDone() {
console.log('同步完成');
}

同步開關(guān)

SDK 默認(rèn)會(huì)同步所有的數(shù)據(jù), 開發(fā)者可以通過開關(guān)來選擇不同步某些數(shù)據(jù), 這些開關(guān)都是初始化參數(shù)

  • syncRelations, 是否同步黑名單和靜音列表, 默認(rèn)true. 如果傳false就收不到黑名單和靜音列表, 即不會(huì)收到onblacklist回調(diào)和onmutelist回調(diào), 開發(fā)者后續(xù)可以調(diào)用獲取黑名單和靜音列表來獲取黑名單和靜音列表。
  • syncFriends, 是否同步好友列表, 默認(rèn)true. 如果傳false就收不到onfriends回調(diào), 開發(fā)者后續(xù)可以調(diào)用獲取好友列表來獲取好友列表悔雹。
  • syncFriendUsers, 是否同步好友對(duì)應(yīng)的用戶名片列表, 默認(rèn)true, 如果傳false就收不到onusers回調(diào).
  • syncRobots, 是否同步機(jī)器人列表复哆,默認(rèn)false, 如果傳false就收不到onrobots回調(diào)。
  • syncTeams, 是否同步群列表, 默認(rèn)true. 如果傳false就收不到群列表, 即不會(huì)收到onteams回調(diào), 開發(fā)者后續(xù)可以調(diào)用獲取群列表來獲取群列表.
  • syncExtraTeamInfo, 是否同步額外的群信息, 默認(rèn)true會(huì)同步額外的群信息, 目前包括
  • 當(dāng)前登錄用戶是否開啟某個(gè)群的消息提醒 (SDK 只是存儲(chǔ)了此信息, 具體用此信息來做什么事情完全由開發(fā)者控制)
  • 調(diào)用接口修改自己的群屬性來關(guān)閉/開啟某個(gè)群的消息提醒
  • 調(diào)用接口是否需要群消息通知來查詢是否需要群消息通知
  • syncTeamMembers, 是否同步群成員, 默認(rèn)true. 只有在syncTeams=true的時(shí)候才起作用, 如果傳false就不會(huì)同步群成員, 即不會(huì)收到onteammembersonsyncteammembersdone回調(diào), 開發(fā)者后續(xù)可以調(diào)用獲取群成員來獲取群成員.
  • syncRoamingMsgs, 是否同步漫游消息, 默認(rèn)true. 如果傳false就收不到漫游消息, 即不會(huì)收到onroamingmsgs回調(diào).
  • syncMsgReceipts, 是否同步已讀回執(zhí)時(shí)間戳, 默認(rèn)true. 如果傳false就收不到已讀回執(zhí)時(shí)間戳.

示例代碼

var nim = NIM.getInstance({
syncRelations: false
});

完整的初始化代碼

var data = {};
var nim = NIM.getInstance({
// 初始化SDK
// debug: true
appKey: 'appKey',
account: 'account',
token: 'token',
onconnect: onConnect,
onerror: onError,
onwillreconnect: onWillReconnect,
ondisconnect: onDisconnect,
// 多端登錄
onloginportschange: onLoginPortsChange,
// 用戶關(guān)系
onblacklist: onBlacklist,
onsyncmarkinblacklist: onMarkInBlacklist,
onmutelist: onMutelist,
onsyncmarkinmutelist: onMarkInMutelist,
// 好友關(guān)系
onfriends: onFriends,
onsyncfriendaction: onSyncFriendAction,
// 用戶名片
onmyinfo: onMyInfo,
onupdatemyinfo: onUpdateMyInfo,
onusers: onUsers,
onupdateuser: onUpdateUser,
onrobots: onRobots,
// 群組
onteams: onTeams,
onsynccreateteam: onCreateTeam,
onteammembers: onTeamMembers,
onsyncteammembersdone: onSyncTeamMembersDone,
onupdateteammember: onUpdateTeamMember,
// 會(huì)話
onsessions: onSessions,
onupdatesession: onUpdateSession,
// 消息
onroamingmsgs: onRoamingMsgs,
onofflinemsgs: onOfflineMsgs,
onmsg: onMsg,
// 系統(tǒng)通知
onofflinesysmsgs: onOfflineSysMsgs,
onsysmsg: onSysMsg,
onupdatesysmsg: onUpdateSysMsg,
onsysmsgunread: onSysMsgUnread,
onupdatesysmsgunread: onUpdateSysMsgUnread,
onofflinecustomsysmsgs: onOfflineCustomSysMsgs,
oncustomsysmsg: onCustomSysMsg,
// 同步完成
onsyncdone: onSyncDone
});

function onConnect() {
console.log('連接成功');
}
function onWillReconnect(obj) {
// 此時(shí)說明 `SDK` 已經(jīng)斷開連接, 請(qǐng)開發(fā)者在界面上提示用戶連接已斷開, 而且正在重新建立連接
console.log('即將重連');
console.log(obj.retryCount);
console.log(obj.duration);
}
function onDisconnect(error) {
// 此時(shí)說明 `SDK` 處于斷開狀態(tài), 開發(fā)者此時(shí)應(yīng)該根據(jù)錯(cuò)誤碼提示相應(yīng)的錯(cuò)誤信息, 并且跳轉(zhuǎn)到登錄頁面
console.log('丟失連接');
console.log(error);
if (error) {
switch (error.code) {
// 賬號(hào)或者密碼錯(cuò)誤, 請(qǐng)?zhí)D(zhuǎn)到登錄頁面并提示錯(cuò)誤
case 302:
break;
// 被踢, 請(qǐng)?zhí)崾惧e(cuò)誤后跳轉(zhuǎn)到登錄頁面
case 'kicked':
break;
default:
break;
}
}
}
function onError(error) {
console.log(error);
}

function onLoginPortsChange(loginPorts) {
console.log('當(dāng)前登錄帳號(hào)在其它端的狀態(tài)發(fā)生改變了', loginPorts);
}

function onBlacklist(blacklist) {
console.log('收到黑名單', blacklist);
data.blacklist = nim.mergeRelations(data.blacklist, blacklist);
data.blacklist = nim.cutRelations(data.blacklist, blacklist.invalid);
refreshBlacklistUI();
}
function onMarkInBlacklist(obj) {
console.log(obj);
console.log(obj.account + '被你在其它端' + (obj.isAdd ? '加入' : '移除') + '黑名單');
if (obj.isAdd) {
addToBlacklist(obj);
} else {
removeFromBlacklist(obj);
}
}
function addToBlacklist(obj) {
data.blacklist = nim.mergeRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function removeFromBlacklist(obj) {
data.blacklist = nim.cutRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function refreshBlacklistUI() {
// 刷新界面
}
function onMutelist(mutelist) {
console.log('收到靜音列表', mutelist);
data.mutelist = nim.mergeRelations(data.mutelist, mutelist);
data.mutelist = nim.cutRelations(data.mutelist, mutelist.invalid);
refreshMutelistUI();
}
function onMarkInMutelist(obj) {
console.log(obj);
console.log(obj.account + '被你' + (obj.isAdd ? '加入' : '移除') + '靜音列表');
if (obj.isAdd) {
addToMutelist(obj);
} else {
removeFromMutelist(obj);
}
}
function addToMutelist(obj) {
data.mutelist = nim.mergeRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function removeFromMutelist(obj) {
data.mutelist = nim.cutRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function refreshMutelistUI() {
// 刷新界面
}

function onFriends(friends) {
console.log('收到好友列表', friends);
data.friends = nim.mergeFriends(data.friends, friends);
data.friends = nim.cutFriends(data.friends, friends.invalid);
refreshFriendsUI();
}
function onSyncFriendAction(obj) {
console.log(obj);
switch (obj.type) {
case 'addFriend':
console.log('你在其它端直接加了一個(gè)好友' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'applyFriend':
console.log('你在其它端申請(qǐng)加了一個(gè)好友' + obj.account + ', 附言' + obj.ps);
break;
case 'passFriendApply':
console.log('你在其它端通過了一個(gè)好友申請(qǐng)' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'rejectFriendApply':
console.log('你在其它端拒絕了一個(gè)好友申請(qǐng)' + obj.account + ', 附言' + obj.ps);
break;
case 'deleteFriend':
console.log('你在其它端刪了一個(gè)好友' + obj.account);
onDeleteFriend(obj.account);
break;
case 'updateFriend':
console.log('你在其它端更新了一個(gè)好友', obj.friend);
onUpdateFriend(obj.friend);
break;
}
}
function onAddFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function onDeleteFriend(account) {
data.friends = nim.cutFriendsByAccounts(data.friends, account);
refreshFriendsUI();
}
function onUpdateFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function refreshFriendsUI() {
// 刷新界面
}

function onMyInfo(user) {
console.log('收到我的名片', user);
data.myInfo = user;
updateMyInfoUI();
}
function onUpdateMyInfo(user) {
console.log('我的名片更新了', user);
data.myInfo = NIM.util.merge(data.myInfo, user);
updateMyInfoUI();
}
function updateMyInfoUI() {
// 刷新界面
}
function onUsers(users) {
console.log('收到用戶名片列表', users);
data.users = nim.mergeUsers(data.users, users);
}
function onUpdateUser(user) {
console.log('用戶名片更新了', user);
data.users = nim.mergeUsers(data.users, user);
}
function onRobots (robots) {
console.log('收到機(jī)器人列表', robots);
data.robots = robots;
}
function onTeams(teams) {
console.log('群列表', teams);
data.teams = nim.mergeTeams(data.teams, teams);
onInvalidTeams(teams.invalid);
}
function onInvalidTeams(teams) {
data.teams = nim.cutTeams(data.teams, teams);
data.invalidTeams = nim.mergeTeams(data.invalidTeams, teams);
refreshTeamsUI();
}
function onCreateTeam(team) {
console.log('你創(chuàng)建了一個(gè)群', team);
data.teams = nim.mergeTeams(data.teams, team);
refreshTeamsUI();
onTeamMembers({
teamId: team.teamId,
members: owner
});
}
function refreshTeamsUI() {
// 刷新界面
}
function onTeamMembers(teamId, members) {
console.log('群id', teamId, '群成員', members);
var teamId = obj.teamId;
var members = obj.members;
data.teamMembers = data.teamMembers || {};
data.teamMembers[teamId] = nim.mergeTeamMembers(data.teamMembers[teamId], members);
data.teamMembers[teamId] = nim.cutTeamMembers(data.teamMembers[teamId], members.invalid);
refreshTeamMembersUI();
}
function onSyncTeamMembersDone() {
console.log('同步群列表完成');
}
function onUpdateTeamMember(teamMember) {
console.log('群成員信息更新了', teamMember);
onTeamMembers({
teamId: teamMember.teamId,
members: teamMember
});
}
function refreshTeamMembersUI() {
// 刷新界面
}

function onSessions(sessions) {
console.log('收到會(huì)話列表', sessions);
data.sessions = nim.mergeSessions(data.sessions, sessions);
updateSessionsUI();
}
function onUpdateSession(session) {
console.log('會(huì)話更新了', session);
data.sessions = nim.mergeSessions(data.sessions, session);
updateSessionsUI();
}
function updateSessionsUI() {
// 刷新界面
}

function onRoamingMsgs(obj) {
console.log('漫游消息', obj);
pushMsg(obj.msgs);
}
function onOfflineMsgs(obj) {
console.log('離線消息', obj);
pushMsg(obj.msgs);
}
function onMsg(msg) {
console.log('收到消息', msg.scene, msg.type, msg);
pushMsg(msg);
}
function pushMsg(msgs) {
if (!Array.isArray(msgs)) { msgs = [msgs]; }
var sessionId = msgs[0].sessionId;
data.msgs = data.msgs || {};
data.msgs[sessionId] = nim.mergeMsgs(data.msgs[sessionId], msgs);
}

function onOfflineSysMsgs(sysMsgs) {
console.log('收到離線系統(tǒng)通知', sysMsgs);
pushSysMsgs(sysMsgs);
}
function onSysMsg(sysMsg) {
console.log('收到系統(tǒng)通知', sysMsg)
pushSysMsgs(sysMsg);
}
function onUpdateSysMsg(sysMsg) {
pushSysMsgs(sysMsg);
}
function pushSysMsgs(sysMsgs) {
data.sysMsgs = nim.mergeSysMsgs(data.sysMsgs, sysMsgs);
refreshSysMsgsUI();
}
function onSysMsgUnread(obj) {
console.log('收到系統(tǒng)通知未讀數(shù)', obj);
data.sysMsgUnread = obj;
refreshSysMsgsUI();
}
function onUpdateSysMsgUnread(obj) {
console.log('系統(tǒng)通知未讀數(shù)更新了', obj);
data.sysMsgUnread = obj;
refreshSysMsgsUI();
}
function refreshSysMsgsUI() {
// 刷新界面
}
function onOfflineCustomSysMsgs(sysMsgs) {
console.log('收到離線自定義系統(tǒng)通知', sysMsgs);
}
function onCustomSysMsg(sysMsg) {
console.log('收到自定義系統(tǒng)通知', sysMsg);
}

function onSyncDone() {
console.log('同步完成');
}

登錄與登出

登出 IM

  • 初始化 SDK之后, SDK 會(huì)自動(dòng)登錄
  • 在收到onconnect回調(diào)后可以調(diào)用nim.disconnect();來登出 SDK
  • 登出 SDK 后可以調(diào)用nim.connect();來重新登入 SDK

切換 IM

如果需要切換 IM, 操作步驟如下

更新 IM 配置

SDK 設(shè)計(jì)為單例模式, 如果需要更新當(dāng)前 IM 的配置, 那么可以調(diào)用此接口, 參數(shù)列表和格式跟NIM.getInstance保持一致, 以更新 token 為例

// 斷開 IM
nim.disconnect();
// 更新 token
nim.setOptions({
token: 'newToken'
});
// 重新連接
nim.connect();

多端登錄

云信支持多端同時(shí)登錄, 即用戶可以同時(shí)在移動(dòng)端和網(wǎng)頁端登錄同一賬號(hào)

初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onloginportschange: onLoginPortsChange
});
function onLoginPortsChange(loginPorts) {
console.log('當(dāng)前登錄帳號(hào)在其它端的狀態(tài)發(fā)生改變了', loginPorts);
}

參數(shù)解釋

  • onloginportschange: 多端登錄狀態(tài)變化的回調(diào), 會(huì)收到登錄端列表, 以下情況會(huì)收到此回調(diào)
  • 登錄時(shí)其它端在線
  • 登錄后其它端上線或者下線

登錄端

登錄端代表登錄在某個(gè)設(shè)備上的相關(guān)信息, 有如下字段

  • type: 登錄的設(shè)備類型
  • os: 登錄設(shè)備的操作系統(tǒng)
  • mac: 登錄設(shè)備的 mac 地址
  • deviceId: 登錄設(shè)備ID, uuid
  • account: 登錄的帳號(hào)
  • connectionId: 登錄設(shè)備分配的連接號(hào)
  • ip: 登錄的服務(wù)器 IP
  • time: 登錄時(shí)間
  • online: 是否在線

設(shè)備類型

目前云信支持的登錄端有以下幾種類型

  • 'Android' (安卓)
  • 'iOS' (蘋果)
  • 'PC' (桌面)
  • 'Web' (瀏覽器)
  • 'Mac' (桌面)

踢其它端

示例代碼

nim.kick({
deviceIds: ['deviceId1'],
done: onKick
});
function onKick(error, obj) {
console.log('踢其它端' + (!error?'成功':'失敗'));
console.log(error);
console.log(obj);
}

參數(shù)解釋

  • 其它登錄端的設(shè)備號(hào)可以在onloginportschange回調(diào)里獲取, 參考登錄端對(duì)象

用戶關(guān)系托管

SDK 提供了用戶關(guān)系托管, 包括黑名單和靜音列表

黑名單

  • 如果一個(gè)用戶被加入了黑名單, 那么就不再會(huì)收到此用戶發(fā)送的消息
  • 如果一個(gè)用戶被從黑名單移除, 那么會(huì)重新收到此用戶發(fā)送的消息

靜音列表

  • SDK只負(fù)責(zé)維護(hù)靜音列表, 具體根據(jù)靜音列表要進(jìn)行的操作由開發(fā)者決定

初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onblacklist: onBlacklist,
onsyncmarkinblacklist: onMarkInBlacklist,
onmutelist: onMutelist,
onsyncmarkinmutelist: onMarkInMutelist
});
function onBlacklist(blacklist) {
console.log('收到黑名單', blacklist);
data.blacklist = nim.mergeRelations(data.blacklist, blacklist);
data.blacklist = nim.cutRelations(data.blacklist, blacklist.invalid);
refreshBlacklistUI();
}
function onMarkInBlacklist(obj) {
console.log(obj);
console.log(obj.account + '被你' + (obj.isAdd ? '加入' : '移除') + '黑名單');
if (obj.isAdd) {
addToBlacklist(obj);
} else {
removeFromBlacklist(obj);
}
}
function addToBlacklist(obj) {
data.blacklist = nim.mergeRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function removeFromBlacklist(obj) {
data.blacklist = nim.cutRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function refreshBlacklistUI() {
// 刷新界面
}
function onMutelist(mutelist) {
console.log('收到靜音列表', mutelist);
data.mutelist = nim.mergeRelations(data.mutelist, mutelist);
data.mutelist = nim.cutRelations(data.mutelist, mutelist.invalid);
refreshMutelistUI();
}
function onMarkInMutelist(obj) {
console.log(obj);
console.log(obj.account + '被你' + (obj.isAdd ? '加入' : '移除') + '靜音列表');
if (obj.isAdd) {
addToMutelist(obj);
} else {
removeFromMutelist(obj);
}
}
function addToMutelist(obj) {
data.mutelist = nim.mergeRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function removeFromMutelist(obj) {
data.mutelist = nim.cutRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function refreshMutelistUI() {
// 刷新界面
}

參數(shù)解釋

  • onblacklist: 同步黑名單的回調(diào), 會(huì)傳入黑名單列表blacklist
  • blacklist的屬性invalid包含被刪除的黑名單列表
  • 此回調(diào)是增量回調(diào), 可以調(diào)用nim.mergeRelationsnim.cutRelations來合并數(shù)據(jù)
  • onsyncmarkinblacklist: 當(dāng)前登錄用戶在其它端加入黑名單/從黑名單移除后的回調(diào), 會(huì)傳入一個(gè)參數(shù), 包含兩個(gè)字段
  • account: 要加入黑名單/從黑名單移除的賬號(hào)
  • isAdd: true表示加入黑名單, false表示從黑名單移除
  • reocrd, 拼裝好的對(duì)象
  • onmutelist: 同步靜音列表的回調(diào), 會(huì)傳入靜音列表mutelist
  • mutelist的屬性invalid包含被刪除的靜音列表
  • 此回調(diào)是增量回調(diào), 可以調(diào)用nim.mergeRelationsnim.cutRelations來合并數(shù)據(jù)
  • onsyncmarkinmutelist: 當(dāng)前登錄用戶在其它端加入靜音列表/從靜音列表移除后的回調(diào), 會(huì)傳入一個(gè)參數(shù), 包含兩個(gè)字段
  • account: 要加入靜音列表/從靜音列表移除的賬號(hào)
  • isAdd: true表示加入靜音列表, false表示從靜音列表移除
  • reocrd, 拼裝好的對(duì)象

加入黑名單/從黑名單移除

  • 此接口可以完成以下兩個(gè)功能, 通過參數(shù)isAdd來決定實(shí)際的功能
  • isAddtrue時(shí), 會(huì)將account加入黑名單
  • 如果一個(gè)用戶被加入了黑名單, 那么就不再會(huì)收到此用戶發(fā)送的消息
  • isAddfalse時(shí), 會(huì)將account從黑名單移除
  • 如果一個(gè)用戶被從黑名單移除, 那么會(huì)重新收到此用戶發(fā)送的消息
  • 每個(gè)功能SDK都提供了相應(yīng)的獨(dú)立接口
nim.markInBlacklist({
account: 'account',
// `true`表示加入黑名單, `false`表示從黑名單移除
isAdd: true,
done: markInBlacklistDone
});
function markInBlacklistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('將' + obj.account + (isAdd ? '加入黑名單' : '從黑名單移除') + (!error?'成功':'失敗'));
if (!error) {
onMarkInBlacklist(obj);
}
}

加入黑名單

  • 如果一個(gè)用戶被加入了黑名單, 那么就不再會(huì)收到此用戶發(fā)送的消息
  • SDK內(nèi)部調(diào)用nim.markInBlacklist來完成實(shí)際工作
nim.addToBlacklist({
account: 'account',
done: addToBlacklistDone
});
function addToBlacklistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('加入黑名單' + (!error?'成功':'失敗'));
if (!error) {
addToBlacklist(obj);
}
}

從黑名單移除

  • 如果一個(gè)用戶被從黑名單移除, 那么會(huì)重新收到此用戶發(fā)送的消息
  • SDK內(nèi)部調(diào)用nim.markInBlacklist來完成實(shí)際工作
nim.removeFromBlacklist({
account: 'account',
done: removeFromBlacklistDone
});
function removeFromBlacklistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('從黑名單移除' + (!error?'成功':'失敗'));
if (!error) {
removeFromBlacklist(obj);
}
}

加入靜音列表/從靜音列表移除

  • 此接口可以完成以下兩個(gè)功能, 通過參數(shù)isAdd來決定實(shí)際的功能
  • isAddtrue時(shí), 會(huì)將account加入靜音列表
  • isAddfalse時(shí), 會(huì)將account從靜音列表移除
  • 每個(gè)功能SDK都提供了相應(yīng)的獨(dú)立接口
nim.markInMutelist({
account: 'account',
// `true`表示加入靜音列表, `false`表示從靜音列表移除
isAdd: 'true',
done: markInMutelistDone
});
function markInMutelistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('將' + obj.account + (isAdd ? '加入靜音列表' : '從靜音列表移除') + (!error?'成功':'失敗'));
if (!error) {
onMarkInMutelist(obj);
}
}

加入靜音列表

  • SDK只負(fù)責(zé)維護(hù)靜音列表, 具體要根據(jù)靜音列表進(jìn)行的操作由開發(fā)者決定
  • SDK內(nèi)部調(diào)用nim.markInMutelist來完成實(shí)際工作
nim.addToMutelist({
account: 'account',
done: addToMutelistDone
});
function addToMutelistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('加入靜音列表' + (!error?'成功':'失敗'));
if (!error) {
addToMutelist(obj);
}
}

從靜音列表移除

  • SDK只負(fù)責(zé)維護(hù)靜音列表, 具體要根據(jù)靜音列表進(jìn)行的操作由開發(fā)者決定
  • SDK內(nèi)部調(diào)用nim.markInMutelist來完成實(shí)際工作
nim.removeFromMutelist({
account: 'account',
done: removeFromMutelistDone
});
function removeFromMutelistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('從靜音列表移除' + (!error?'成功':'失敗'));
if (!error) {
removeFromMutelist(obj);
}
}

獲取黑名單和靜音列表

  • 如果開發(fā)者在初始化SDK的時(shí)候設(shè)置了syncRelationsfalse, 那么就收不到onblacklistonmutelist回調(diào), 可以調(diào)用此接口來獲取黑名單和靜音列表腌零。
nim.getRelations({
done: getRelationsDone
});
function getRelationsDone(error, obj) {
console.log('獲取靜音列表' + (!error?'成功':'失敗'), error, obj);
if (!error) {
onBlacklist(obj.blacklist);
onMutelist(obj.mutelist);
}
}

好友關(guān)系托管

  • SDK 提供好友關(guān)系托管

好友關(guān)系初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onfriends: onFriends,
onsyncfriendaction: onSyncFriendAction
});
function onFriends(friends) {
console.log('收到好友列表', friends);
data.friends = nim.mergeFriends(data.friends, friends);
data.friends = nim.cutFriends(data.friends, friends.invalid);
refreshFriendsUI();
}
function onSyncFriendAction(obj) {
console.log(obj);
switch (obj.type) {
case 'addFriend':
console.log('你在其它端直接加了一個(gè)好友' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'applyFriend':
console.log('你在其它端申請(qǐng)加了一個(gè)好友' + obj.account + ', 附言' + obj.ps);
break;
case 'passFriendApply':
console.log('你在其它端通過了一個(gè)好友申請(qǐng)' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'rejectFriendApply':
console.log('你在其它端拒絕了一個(gè)好友申請(qǐng)' + obj.account + ', 附言' + obj.ps);
break;
case 'deleteFriend':
console.log('你在其它端刪了一個(gè)好友' + obj.account);
onDeleteFriend(obj.account);
break;
case 'updateFriend':
console.log('你在其它端更新了一個(gè)好友', obj.friend);
onUpdateFriend(obj.friend);
break;
}
}
function onAddFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function onDeleteFriend(account) {
data.friends = nim.cutFriendsByAccounts(data.friends, account);
refreshFriendsUI();
}
function onUpdateFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function refreshFriendsUI() {
// 刷新界面
}

參數(shù)解釋

  • onfriends, 同步好友列表的回調(diào), 會(huì)傳入好友列表friends
  • friends的屬性invalid包含被刪除的好友列表
  • 此回調(diào)是增量回調(diào), 可以調(diào)用nim.mergeFriendsnim.cutFriends來合并數(shù)據(jù)
  • onsyncfriendaction, 當(dāng)前登錄用戶在其它端進(jìn)行好友相關(guān)的操作后的回調(diào)
  • 操作包括
  • 直接加為好友
  • 申請(qǐng)加為好友
  • 通過好友申請(qǐng)
  • 拒絕好友申請(qǐng)
  • 刪除好友
  • 更新好友
  • 此回調(diào)會(huì)收到一個(gè)參數(shù)obj, 它有一個(gè)字段type的值為操作的類型, 具體類型如下:
  • 'addFriend' (直接加為好友), 此時(shí)obj的字段如下:
  • account的值為被直接加為好友的賬號(hào)
  • friend為被直接加為好友的好友對(duì)象
  • ps為附言
  • 'applyFriend' (申請(qǐng)加為好友), 此時(shí)obj的字段如下:
  • account的值為被申請(qǐng)加為好友的賬號(hào)
  • ps為附言
  • 'passFriendApply' (通過好友申請(qǐng)), 此時(shí)obj的字段如下:
  • account的值為被通過好友申請(qǐng)的賬號(hào)
  • friend為被通過好友申請(qǐng)的好友對(duì)象
  • ps為附言
  • 'rejectFriendApply' (拒絕好友申請(qǐng)), 此時(shí)obj的字段如下:
  • account的值為被拒絕好友申請(qǐng)的賬號(hào)
  • ps為附言
  • 'deleteFriend' (刪除好友), 此時(shí)obj的字段如下:
  • account的值為被刪除好友的賬號(hào)
  • 'updateFriend' (更新好友), 此時(shí)obj的字段如下:
  • friend的值為被更新的好友對(duì)象
  • 可以調(diào)用nim.mergeFriendsnim.cutFriendsByAccounts來合并數(shù)據(jù)

好友對(duì)象

好友對(duì)象有以下字段:

  • account: 賬號(hào)
  • alias: 昵稱
  • custom: 擴(kuò)展字段, 開發(fā)者可以自行擴(kuò)展, 建議封裝成JSON格式字符串
  • createTime: 成為好友的時(shí)間
  • updateTime: 更新時(shí)間

直接加為好友

  • 直接加某個(gè)用戶為好友后, 對(duì)方不需要確認(rèn), 直接成為當(dāng)前登錄用戶的好友
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
  • 對(duì)方會(huì)收到一條類型為'addFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為接收方的賬號(hào)梯找。
nim.addFriend({
account: 'account',
ps: 'ps',
done: addFriendDone
});
function addFriendDone(error, obj) {
console.log(error);
console.log(obj);
console.log('直接加為好友' + (!error?'成功':'失敗'));
if (!error) {
onAddFriend(obj.friend);
}
}

申請(qǐng)加為好友

  • 申請(qǐng)加某個(gè)用戶為好友后, 對(duì)方會(huì)收到一條類型為'applyFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為接收方的賬號(hào), 用戶在收到好友申請(qǐng)后, 可以選擇通過或者拒絕好友申請(qǐng)。
  • 如果通過好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'passFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為通過方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)益涧。
  • 如果拒絕好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'rejectFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)锈锤。
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
nim.applyFriend({
account: 'account',
ps: 'ps',
done: applyFriendDone
});
function applyFriendDone(error, obj) {
console.log(error);
console.log(obj);
console.log('申請(qǐng)加為好友' + (!error?'成功':'失敗'));
}

通過好友申請(qǐng)

  • 申請(qǐng)加某個(gè)用戶為好友后, 對(duì)方會(huì)收到一條類型為'applyFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為接收方的賬號(hào), 用戶在收到好友申請(qǐng)后, 可以選擇通過或者拒絕好友申請(qǐng)。
  • 如果通過好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'passFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為通過方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)。
  • 如果拒絕好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'rejectFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)久免。
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
// 假設(shè) sysMsg 是通過回調(diào) `onsysmsg` 收到的系統(tǒng)通知
nim.passFriendApply({
idServer: sysMsg.idServer,
account: 'account',
ps: 'ps',
done: passFriendApplyDone
});
function passFriendApplyDone(error, obj) {
console.log(error);
console.log(obj);
console.log('通過好友申請(qǐng)' + (!error?'成功':'失敗'));
if (!error) {
onAddFriend(obj.friend);
}
}

拒絕好友申請(qǐng)

  • 申請(qǐng)加某個(gè)用戶為好友后, 對(duì)方會(huì)收到一條類型為'applyFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為接收方的賬號(hào), 用戶在收到好友申請(qǐng)后, 可以選擇通過或者拒絕好友申請(qǐng)浅辙。
  • 如果通過好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'passFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為通過方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)。
  • 如果拒絕好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'rejectFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)阎姥。
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
// 假設(shè) sysMsg 是通過回調(diào) `onsysmsg` 收到的系統(tǒng)通知
nim.rejectFriendApply({
idServer: sysMsg.idServer,
account: 'account',
ps: 'ps',
done: rejectFriendApplyDone
});
function rejectFriendApplyDone(error, obj) {
console.log(error);
console.log(obj);
console.log('拒絕好友申請(qǐng)' + (!error?'成功':'失敗'));
}

刪除好友

  • 刪除好友后, 被刪除的人會(huì)收到一條類型為'deleteFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為刪除方的帳號(hào), to字段的值為被刪除方的賬號(hào)记舆。
nim.deleteFriend({
account: 'account',
done: deleteFriendDone
});
function deleteFriendDone(error, obj) {
console.log(error);
console.log(obj);
console.log('刪除好友' + (!error?'成功':'失敗'));
if (!error) {
onDeleteFriend(obj.account);
}
}

更新好友

  • 開發(fā)者可以用此接口來更新好友的備注
  • 開發(fā)者也可以使用JSON格式的擴(kuò)展字段來進(jìn)行擴(kuò)展
nim.updateFriend({
account: 'account',
alias: 'alias',
custom: 'custom',
done: updateFriendDone
});
function updateFriendDone(error, obj) {
console.log(error);
console.log(obj);
console.log('更新好友' + (!error?'成功':'失敗'));
if (!error) {
onUpdateFriend(obj);
}
}

獲取好友列表

  • 如果開發(fā)者在初始化SDK的時(shí)候設(shè)置了syncFriendsfalse, 那么就收不到onfriends回調(diào), 可以調(diào)用此接口來獲取好友列表。
nim.getFriends({
done: getFriendsDone
});
function getFriendsDone(error, friends) {
console.log('獲取好友列表' + (!error?'成功':'失敗'), error, friends);
if (!error) {
onFriends(friends);
}
}

用用戶名片托管

SDK 提供用戶名片托管

用戶名片初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onmyinfo: onMyInfo,
onupdatemyinfo: onUpdateMyInfo,
onusers: onUsers,
onupdateuser: onUpdateUser
});
function onMyInfo(user) {
console.log('收到我的名片', user);
data.myInfo = user;
updateMyInfoUI();
}
function onUpdateMyInfo(user) {
console.log('我的名片更新了', user);
data.myInfo = NIM.util.merge(data.myInfo, user);
updateMyInfoUI();
}
function updateMyInfoUI() {
// 刷新界面
}
function onUsers(users) {
console.log('收到用戶名片列表', users);
data.users = nim.mergeUsers(data.users, users);
}
function onUpdateUser(user) {
console.log('用戶名片更新了', user);
data.users = nim.mergeUsers(data.users, user);
}

參數(shù)解釋

  • onmyinfo: 同步登錄用戶名片的回調(diào), 會(huì)傳入用戶名片
  • onupdatemyinfo: 當(dāng)前登錄用戶在其它端修改自己的個(gè)人名片之后的回調(diào), 會(huì)傳入用戶名片
  • onusers: 同步好友用戶名片的回調(diào), 會(huì)傳入用戶名片數(shù)組
  • 此回調(diào)是增量回調(diào), 可以調(diào)用nim.mergeUsers來合并數(shù)據(jù)
  • onupdateuser: 用戶名片更新后的回調(diào), 會(huì)傳入用戶名片呼巴,請(qǐng)參考用戶名片更新時(shí)機(jī)

用戶名片對(duì)象

用戶名片對(duì)象有以下字段:

  • account: 賬號(hào)
  • nick: 昵稱
  • avatar: 頭像
  • sign: 簽名
  • gender: 性別
  • email: 郵箱
  • birth: 生日
  • tel: 電話號(hào)碼
  • custom: 擴(kuò)展字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • createTime: 創(chuàng)建時(shí)間
  • updateTime: 更新時(shí)間

性別

  • 'unknown' (未知)
  • 'male' (男)
  • 'female' (女)

更新我的名片

nim.updateMyInfo({
nick: 'newNick',
avatar: 'http://newAvatar',
sign: 'newSign',
gender: 'male',
email: 'new@email.com',
birth: '1900-01-01',
tel: '13523578129',
custom: '{type: "newCustom", value: "new"}',
done: updateMyInfoDone
});
function updateMyInfoDone(error, user) {
console.log('更新我的名片' + (!error?'成功':'失敗'));
console.log(error);
console.log(user);
if (!error) {
onUpdateMyInfo(user);
}
}

用戶名片更新時(shí)機(jī)

  • 用戶名片除自己之外泽腮,不保證其他用戶名片實(shí)時(shí)更新,其他用戶名片更新時(shí)機(jī)為
  • 收到此用戶發(fā)來的消息
  • 每次同步會(huì)同步好友對(duì)應(yīng)的用戶名片
  • 如果想手動(dòng)刷新用戶名片衣赶,請(qǐng)參考獲取用戶名片獲取用戶名片數(shù)組

獲取用戶名片

nim.getUser({
account: 'account',
done: getUserDone
});
function getUserDone(error, user) {
console.log(error);
console.log(user);
console.log('獲取用戶名片' + (!error?'成功':'失敗'));
if (!error) {
onUsers(user);
}
}

獲取用戶名片數(shù)組

  • 請(qǐng)參考用戶名片更新時(shí)機(jī)
  • 可以傳入?yún)?shù)sync=true來強(qiáng)制從服務(wù)器獲取最新的數(shù)據(jù)
  • 每次最多 150 個(gè)
nim.getUsers({
accounts: ['account1', 'account2'],
done: getUsersDone
});
function getUsersDone(error, users) {
console.log(error);
console.log(users);
console.log('獲取用戶名片數(shù)組' + (!error?'成功':'失敗'));
if (!error) {
onUsers(users);
}
}

智能機(jī)器人

智能機(jī)器人簡(jiǎn)介

  • 智能聊天機(jī)器人解決方案依托網(wǎng)易IM即時(shí)通訊诊赊、語音識(shí)別、語義理解等服務(wù)府瞄,為開發(fā)者提供人機(jī)交互API/SDK豪筝、語音識(shí)別、意圖識(shí)別摘能、知識(shí)庫配置续崖、動(dòng)態(tài)接口等功能,可以在應(yīng)用IM內(nèi)快速集成場(chǎng)景豐富的智能聊天機(jī)器人团搞。
  • 詳見網(wǎng)易人工智能

同步機(jī)器人列表

  • 機(jī)器人列表的同步可以通過設(shè)置同步字段syncRobots: true來實(shí)現(xiàn)
  • 參見完整的初始化代碼
  • 用戶也可以手動(dòng)同步機(jī)器人列表
  • 手動(dòng)同步機(jī)器人列表严望,其本質(zhì)仍然是一個(gè)同步協(xié)議,所以會(huì)觸發(fā)用戶設(shè)置的同步函數(shù) onrobots 的回調(diào)逻恐。
nim.getRobots();
  • 機(jī)器人列表中的機(jī)器人對(duì)象包含以下字段:
  • account: 機(jī)器人賬號(hào)像吻,對(duì)應(yīng)機(jī)器人消息中的robotAccid
  • avatar: 機(jī)器人頭像
  • createTime: 機(jī)器人創(chuàng)建時(shí)間
  • intro: 機(jī)器人簡(jiǎn)介
  • nick: 機(jī)器人昵稱

智能機(jī)器人消息模板

發(fā)送智能機(jī)器人消息

群組

群組功能概述

SDK 提供了普通群以及高級(jí)群兩種形式的群功能。 高級(jí)群擁有更多的權(quán)限操作复隆,兩種群聊形式在共有操作上保持了接口一致拨匆。推薦 APP 開發(fā)時(shí)只選擇一種群類型進(jìn)行開發(fā)。普通群和高級(jí)群在原則上是不能互相轉(zhuǎn)換的挽拂,他們的群類型在創(chuàng)建時(shí)就已經(jīng)確定媳握。在 SDK 2.4.0 版本后唱歧,高級(jí)群可以擁有普通群的全部功能绳匀,推薦使用高級(jí)群進(jìn)行開發(fā)投放。

  • 普通群 開發(fā)手冊(cè)中所提及的普通群都等同于 Demo 中的討論組。普通群沒有權(quán)限操作绒北,適用于快速創(chuàng)建多人會(huì)話的場(chǎng)景黎侈。每個(gè)普通群只有一個(gè)管理員。管理員可以對(duì)群進(jìn)行增減員操作闷游,普通成員只能對(duì)群進(jìn)行增員操作峻汉。在添加新成員的時(shí)候贴汪,并不需要經(jīng)過對(duì)方同意。
  • 高級(jí)群 高級(jí)群在權(quán)限上有更多的限制休吠,權(quán)限分為群主嘶是、管理員、以及群成員蛛碌。

群組初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onteams: onTeams,
onsynccreateteam: onCreateTeam,
onteammembers: onTeamMembers,
onsyncteammembersdone: onSyncTeamMembersDone,
onupdateteammember: onUpdateTeamMember
});
function onTeams(teams) {
console.log('收到群列表', teams);
data.teams = nim.mergeTeams(data.teams, teams);
onInvalidTeams(teams.invalid);
}
function onInvalidTeams(teams) {
data.teams = nim.cutTeams(data.teams, teams);
data.invalidTeams = nim.mergeTeams(data.invalidTeams, teams);
refreshTeamsUI();
}
function onCreateTeam(team) {
console.log('你創(chuàng)建了一個(gè)群', team);
data.teams = nim.mergeTeams(data.teams, team);
refreshTeamsUI();
onTeamMembers({
teamId: team.teamId,
members: owner
});
}
function refreshTeamsUI() {
// 刷新界面
}
function onTeamMembers(obj) {
console.log('群id', teamId, '群成員', members);
var teamId = obj.teamId;
var members = obj.members;
data.teamMembers = data.teamMembers || {};
data.teamMembers[teamId] = nim.mergeTeamMembers(data.teamMembers[teamId], members);
data.teamMembers[teamId] = nim.cutTeamMembers(data.teamMembers[teamId], members.invalid);
refreshTeamMembersUI();
}
function onSyncTeamMembersDone() {
console.log('同步群列表完成');
}
function onUpdateTeamMember(teamMember) {
console.log('群成員信息更新了', teamMember);
onTeamMembers({
teamId: teamMember.teamId,
members: teamMember
});
}
function refreshTeamMembersUI() {
// 刷新界面
}

參數(shù)解釋

  • onteams, 同步列表的回調(diào), 會(huì)傳入群數(shù)組
  • teams的屬性invalid包含退出的群
  • 此回調(diào)是增量回調(diào), 可以調(diào)用nim.mergeTeamsnim.cutTeams來合并數(shù)據(jù)
  • onsynccreateteam, 當(dāng)前登錄帳號(hào)在其它端創(chuàng)建群之后, 會(huì)收到此回調(diào), 會(huì)傳入群對(duì)象
  • onteammembers, 同步群成員的回調(diào), 一個(gè)群對(duì)應(yīng)一個(gè)回調(diào), 會(huì)傳入群成員數(shù)組
  • 可以調(diào)用nim.mergeTeamMembersnim.cutTeamMembers來合并數(shù)據(jù)
  • onsyncteammembersdone, 當(dāng)所有群的群成員同步結(jié)束時(shí), 會(huì)調(diào)用此回調(diào)
  • onupdateteammember, 群成員信息更新后的回調(diào), 會(huì)傳入群成員對(duì)象, 不過此時(shí)的信息是不完整的, 只會(huì)包括被更新的字段。當(dāng)前登錄帳號(hào)在其它端修改自己的群屬性時(shí)也會(huì)收到此回調(diào)辖源。
  • onCreateTeam, 創(chuàng)建群的回調(diào), 此方法接收一個(gè)參數(shù), 包含群信息和群主信息
  • onUpdateTeam, 更新群的回調(diào), 此方法接收一個(gè)參數(shù), 更新后的群信息
  • onAddTeamMembers, 新成員入群的回調(diào), 此方法接收一個(gè)參數(shù), 包含群信息和群成員信息
  • onRemoveTeamMembers, 有人出群的回調(diào), 此方法接收一個(gè)參數(shù), 包含群信息和群成員賬號(hào)
  • onUpdateTeamManagers, 更新群管理員的回調(diào), 此方法接收一個(gè)參數(shù), 包含群信息和管理員信息
  • onDismissTeam, 解散群的回調(diào), 此方法接收一個(gè)參數(shù), 包含被解散的群id
  • onTransferTeam, 移交群的回調(diào), 此方法接收一個(gè)參數(shù), 包含群信息和新老群主信息
  • onUpdateTeamMembersMute, 更新群成員禁言狀態(tài)的回調(diào), 此方法接收一個(gè)參數(shù), 包含群信息和禁言狀態(tài)信息

群對(duì)象

群對(duì)象有如下字段

  • teamId: 群Id
  • appId: 群所屬的app的id
  • type: 群類型
  • name: 群名字
  • avatar: 群頭像
  • intro: 群簡(jiǎn)介
  • announcement: 群公告
  • joinMode: 群加入方式, 僅限高級(jí)群
  • beInviteMode: 群被邀請(qǐng)模式, 僅限高級(jí)群
  • inviteMode: 群邀請(qǐng)模式, 僅限高級(jí)群
  • updateTeamMode: 群信息修改權(quán)限, 僅限高級(jí)群
  • updateCustomMode: 群信息自定義字段修改權(quán)限, 僅限高級(jí)群
  • owner: 群主
  • level: 群人數(shù)上限
  • memberNum: 群成員數(shù)量
  • memberUpdateTime: 群成員最后更新時(shí)間
  • createTime: 群創(chuàng)建時(shí)間
  • updateTime: 群最后更新時(shí)間
  • custom: 第三方擴(kuò)展字段, 開發(fā)者可以自行擴(kuò)展, 建議封裝成JSON格式字符串
  • serverCustom: 第三方服務(wù)器擴(kuò)展字段, 開發(fā)者可以自行擴(kuò)展, 建議封裝成JSON格式字符串
  • valid: 是否有效, 解散后該群無效
  • validToCurrentUser: 該群是否對(duì)當(dāng)前用戶有效, 如果無效, 那么說明被踢了
  • mute: 是否禁言, 禁言狀態(tài)下普通成員不能發(fā)送消息, 創(chuàng)建者和管理員可以發(fā)送消息

群類型

群對(duì)象有一個(gè)字段type來標(biāo)明群類型, 具體類型如下

  • 'normal' (普通群)
  • 'advanced' (高級(jí)群)

群加入方式

群加入方式有以下幾種

  • 'noVerify' (不需要驗(yàn)證)
  • 'needVerify' (需要驗(yàn)證)
  • 'rejectAll' (禁止任何人加入)

群被邀請(qǐng)模式

群被邀請(qǐng)模式有以下幾種

  • 'needVerify' (需要邀請(qǐng)方同意)
  • 'noVerify' (不需要邀請(qǐng)方同意)

群邀請(qǐng)模式

群邀請(qǐng)模式有以下幾種

  • 'manager' (只有管理員/群主可以邀請(qǐng)他人入群)
  • 'all' (所有人可以邀請(qǐng)他人入群)

群信息修改權(quán)限

群信息修改權(quán)限有以下幾種

  • 'manager' (只有管理員/群主可以修改)
  • 'all' (所有人可以修改)

群信息自定義字段修改權(quán)限

群信息自定義字段修改權(quán)限有以下幾種

  • 'manager' (只有管理員/群主可以修改)
  • 'all' (所有人可以修改)

群成員對(duì)象

群成員對(duì)象有如下字段

  • teamId: 群ID
  • account: 帳號(hào)
  • type: 群成員類型
  • nickInTeam: 在群里面的昵稱
  • active: 普通群拉人進(jìn)來的時(shí)候, 被拉的人處于未激活狀態(tài), 未激活狀態(tài)下看不到這個(gè)群, 當(dāng)有人說話后自動(dòng)轉(zhuǎn)為激活狀態(tài), 能看到該群
  • joinTime: 入群時(shí)間
  • updateTime: 更新時(shí)間

群成員類型

  • 'normal' (普通成員)
  • 'owner' (群主)
  • 'manager' (管理員)

創(chuàng)建群

  • 普通群不可以設(shè)置群加入方式
  • 高級(jí)群的群加入方式默認(rèn)為 'needVerify'
  • 高級(jí)群的群被邀請(qǐng)模式默認(rèn)為'needVerify'
  • 高級(jí)群的群邀請(qǐng)模式默認(rèn)為'manager'
  • 高級(jí)群的群信息修改權(quán)限默認(rèn)為'manager'
  • 高級(jí)群的群信息自定義字段修改權(quán)限默認(rèn)為'manager'
  • 普通群的創(chuàng)建者可以看到所有的群成員, 而被邀請(qǐng)的群成員在有人發(fā)消息之后才能看到該群, 而且會(huì)先收到一條類型為'addTeamMembers'群通知消息, 然后會(huì)收到其它群消息蔚携。
  • 高級(jí)群被邀請(qǐng)的群成員會(huì)收到一條類型為類型為'teamInvite'系統(tǒng)通知, 群成員只有接受邀請(qǐng)之后才會(huì)出現(xiàn)在該群中。
  • 接受邀請(qǐng)后, 所有群成員會(huì)收到一條類型為'acceptTeamInvite'群通知消息克饶。
  • 拒絕邀請(qǐng)后, 群主會(huì)收到一條類型為'rejectTeamInvite'系統(tǒng)通知酝蜒。
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
// 創(chuàng)建普通群
nim.createTeam({
type: 'normal',
name: '普通群',
avatar: 'avatar',
accounts: ['a1', 'a2'],
ps: '我建了一個(gè)普通群',
done: createTeamDone
});
// 創(chuàng)建高級(jí)群
nim.createTeam({
type: 'advanced',
name: '高級(jí)群',
avatar: 'avatar',
accounts: ['a1', 'a2'],
intro: '群簡(jiǎn)介',
announcement: '群公告',
// joinMode: 'needVerify',
// beInviteMode: 'needVerify',
// inviteMode: 'manager',
// updateTeamMode: 'manager',
// updateCustomMode: 'manager',
ps: '我建了一個(gè)高級(jí)群',
custom: '群擴(kuò)展字段, 建議封裝成JSON格式字符串',
done: createTeamDone
});
function createTeamDone(error, obj) {
console.log(error);
console.log(obj);
console.log('創(chuàng)建' + obj.team.type + '群' + (!error?'成功':'失敗'));
if (!error) {
onCreateTeam(obj.team, obj.owner);
}
}

發(fā)送群消息

發(fā)送群消息時(shí)只需將上文中各個(gè)發(fā)送消息接口的scene替換為'team', 將to替換為群ID

接收群消息

參考上文的接收消息

更新群

nim.updateTeam({
teamId: 123,
name: '群名字',
avatar: 'avatar',
intro: '群簡(jiǎn)介',
announcement: '群公告',
joinMode: 'needVerify',
custom: '自定義字段',
done: updateTeamDone
});
function updateTeamDone(error, team) {
console.log(error);
console.log(team);
console.log('更新群' + (!error?'成功':'失敗'));
}

拉人入群

  • 普通群, 拉人入群后, 所有群成員會(huì)收到一條類型為'addTeamMembers'群通知消息亡脑。此類群通知消息的from字段的值為拉人的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段accounts的值為被拉的人的帳號(hào)列表, attach有一個(gè)字段members的值為被拉的群成員列表。
  • 被邀請(qǐng)的群成員在有人說話后才能看到該, 而且會(huì)先收到一條類型為'addTeamMembers'群通知消息, 然后會(huì)收到其它群消息邀跃。
  • 高級(jí)群的群主和管理員在邀請(qǐng)成員加入群(通過操作創(chuàng)建群拉人入群)之后, 被邀請(qǐng)的人會(huì)收到一條類型為'teamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為邀請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 此類系統(tǒng)通知的attach有一個(gè)字段team的值為被邀請(qǐng)進(jìn)入的, 被邀請(qǐng)的人可以選擇接受邀請(qǐng)或者拒絕邀請(qǐng)霉咨。
  • 如果接受邀請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'acceptTeamInvite'群通知消息, 此類群通知消息的from字段的值為接受入群邀請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段members的值為接收入群邀請(qǐng)的群成員列表。
  • 如果拒絕邀請(qǐng), 那么邀請(qǐng)你的人會(huì)收到一條類型為'rejectTeamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕入群邀請(qǐng)的用戶的帳號(hào), to字段的值為對(duì)應(yīng)的群ID拍屑。
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
nim.addTeamMembers({
teamId: 123,
accounts: ['a3', 'a4'],
ps: '加入我們的群吧',
done: addTeamMembersDone
});
function addTeamMembersDone(error, obj) {
console.log(error);
console.log(obj);
console.log('入群邀請(qǐng)發(fā)送' + (!error?'成功':'失敗'));
}

踢人出群

  • 踢人出群后, 所有群成員會(huì)收到一條類型為'removeTeamMembers'群通知消息途戒。此類群通知消息的from字段的值為踢人的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段accounts的值為被踢的人的帳號(hào)列表。
nim.removeTeamMembers({
teamId: 123,
accounts: ['a3', 'a4'],
done: removeTeamMembersDone
});
function removeTeamMembersDone(error, obj) {
console.log(error);
console.log(obj);
console.log('踢人出群' + (!error?'成功':'失敗'));
}

接受入群邀請(qǐng)

  • 高級(jí)群的群主和管理員在邀請(qǐng)成員加入群(通過操作創(chuàng)建群拉人入群)之后, 被邀請(qǐng)的人會(huì)收到一條類型為'teamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為邀請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 此類系統(tǒng)通知的attach有一個(gè)字段team的值為被邀請(qǐng)進(jìn)入的, 被邀請(qǐng)的人可以選擇接受邀請(qǐng)或者拒絕邀請(qǐng)僵驰。
  • 如果接受邀請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'acceptTeamInvite'群通知消息, 此類群通知消息的from字段的值為接受入群邀請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段members的值為接收入群邀請(qǐng)的群成員列表喷斋。
  • 如果拒絕邀請(qǐng), 那么邀請(qǐng)你的人會(huì)收到一條類型為'rejectTeamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕入群邀請(qǐng)的用戶的帳號(hào), to字段的值為對(duì)應(yīng)的群ID。
  • 參數(shù)from填邀請(qǐng)方的帳號(hào)
// 假設(shè) sysMsg 是通過回調(diào) `onsysmsg` 收到的系統(tǒng)通知
nim.acceptTeamInvite({
idServer: sysMsg.idServer,
teamId: 123,
from: 'zyy1',
done: acceptTeamInviteDone
});
function acceptTeamInviteDone(error, obj) {
console.log(error);
console.log(obj);
console.log('接受入群邀請(qǐng)' + (!error?'成功':'失敗'));
}

拒絕入群邀請(qǐng)

  • 高級(jí)群的群主和管理員在邀請(qǐng)成員加入群(通過操作創(chuàng)建群拉人入群)之后, 被邀請(qǐng)的人會(huì)收到一條類型為'teamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為邀請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 此類系統(tǒng)通知的attach有一個(gè)字段team的值為被邀請(qǐng)進(jìn)入的, 被邀請(qǐng)的人可以選擇接受邀請(qǐng)或者拒絕邀請(qǐng)蒜茴。
  • 如果接受邀請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'acceptTeamInvite'群通知消息, 此類群通知消息的from字段的值為接受入群邀請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段members的值為接收入群邀請(qǐng)的群成員列表星爪。
  • 如果拒絕邀請(qǐng), 那么邀請(qǐng)你的人會(huì)收到一條類型為'rejectTeamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕入群邀請(qǐng)的用戶的帳號(hào), to字段的值為對(duì)應(yīng)的群ID。
  • 參數(shù)from填邀請(qǐng)方的帳號(hào)
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
// 假設(shè) sysMsg 是通過回調(diào) `onsysmsg` 收到的系統(tǒng)通知
nim.rejectTeamInvite({
idServer: sysMsg.idServer,
teamId: 123,
from: 'zyy1',
ps: '就不',
done: rejectTeamInviteDone
});
function rejectTeamInviteDone(error, obj) {
console.log(error);
console.log(obj);
console.log('拒絕入群邀請(qǐng)' + (!error?'成功':'失敗'));
}

申請(qǐng)入群

  • 用戶可以申請(qǐng)加入高級(jí)群, 目標(biāo)群的群主和管理員會(huì)收到一條類型為'applyTeam'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 高級(jí)群的群主和管理員在收到入群申請(qǐng)后, 可以選擇通過或者拒絕入群申請(qǐng)粉私。
  • 如果通過申請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'passTeamApply'群通知消息, 此類群通知消息的from字段的值為通過入群申請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為申請(qǐng)方的帳號(hào), attach有一個(gè)字段members的值為被通過申請(qǐng)的群成員列表顽腾。
  • 如果拒絕申請(qǐng), 那么申請(qǐng)人會(huì)收到一條類型為'rejectTeamApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
nim.applyTeam({
teamId: 123,
ps: '請(qǐng)加',
done: applyTeamDone
});
function applyTeamDone(error, obj) {
console.log(error);
console.log(obj);
console.log('申請(qǐng)入群' + (!error?'成功':'失敗'));
}

通過入群申請(qǐng)

  • 用戶可以申請(qǐng)加入高級(jí)群, 目標(biāo)群的群主和管理員會(huì)收到一條類型為'applyTeam'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 高級(jí)群的群主和管理員在收到入群申請(qǐng)后, 可以選擇通過或者拒絕入群申請(qǐng)诺核。
  • 如果通過申請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'passTeamApply'群通知消息, 此類群通知消息的from字段的值為通過入群申請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為申請(qǐng)方的帳號(hào), attach有一個(gè)字段members的值為被通過申請(qǐng)的群成員列表崔泵。
  • 如果拒絕申請(qǐng), 那么申請(qǐng)人會(huì)收到一條類型為'rejectTeamApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的
  • 參數(shù)from填申請(qǐng)方的帳號(hào), 該參數(shù)的名字在v1.3.0版本中從account變?yōu)?code>from
// 假設(shè) sysMsg 是通過回調(diào) `onsysmsg` 收到的系統(tǒng)通知
nim.passTeamApply({
idServer: sysMsg.idServer,
teamId: 123,
from: 'a2',
done: passTeamApplyDone
});
function passTeamApplyDone(error, obj) {
console.log(error);
console.log(obj);
console.log('通過入群申請(qǐng)' + (!error?'成功':'失敗'));
}

拒絕入群申請(qǐng)

  • 用戶可以申請(qǐng)加入高級(jí)群, 目標(biāo)群的群主和管理員會(huì)收到一條類型為'applyTeam'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 高級(jí)群的群主和管理員在收到入群申請(qǐng)后, 可以選擇通過或者拒絕入群申請(qǐng)猪瞬。
  • 如果通過申請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'passTeamApply'群通知消息, 此類群通知消息的from字段的值為通過入群申請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為申請(qǐng)方的帳號(hào), attach有一個(gè)字段members的值為被通過申請(qǐng)的群成員列表憎瘸。
  • 如果拒絕申請(qǐng), 那么申請(qǐng)人會(huì)收到一條類型為'rejectTeamApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的
  • 參數(shù)from填申請(qǐng)方的帳號(hào), 該參數(shù)的名字在v1.3.0版本中從account變?yōu)?code>from
  • ps: 附言, 選填, 開發(fā)者也可以使用JSON格式的字符串來擴(kuò)展此內(nèi)容
// 假設(shè) sysMsg 是通過回調(diào) `onsysmsg` 收到的系統(tǒng)通知
nim.rejectTeamApply({
idServer: sysMsg.idServer,
teamId: 123,
from: 'a2',
ps: '就不',
done: rejectTeamApplyDone
});
function rejectTeamApplyDone(error, obj) {
console.log(error);
console.log(obj);
console.log('拒絕入群申請(qǐng)' + (!error?'成功':'失敗'));
}

添加群管理員

  • 添加群管理員后, 所有群成員會(huì)收到一條類型為'addTeamManagers'群通知消息陈瘦。此類群通知消息的from字段的值為添加群管理員的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段accounts的值為被加為管理員的帳號(hào)列表, attach有一個(gè)字段members的值為被加為管理員的群成員列表
nim.addTeamManagers({
teamId: 123,
accounts: ['a2', 'a3'],
done: addTeamManagersDone
});
function addTeamManagersDone(error, obj) {
console.log(error);
console.log(obj);
console.log('添加群管理員' + (!error?'成功':'失敗'));
}

移除群管理員

  • 移除群管理員后, 所有群成員會(huì)收到一條類型為'removeTeamManagers'群通知消息幌甘。此類群通知消息的from字段的值為移除群管理員的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段accounts的值為被移除的管理員的帳號(hào)列表, attach有一個(gè)字段members的值為被移除管理員的群成員列表
nim.removeTeamManagers({
teamId: 123,
accounts: ['a2', 'a3'],
done: removeTeamManagersDone
});
function removeTeamManagersDone(error, obj) {
console.log(error);
console.log(obj);
console.log('移除群管理員' + (!error?'成功':'失敗'));
}

主動(dòng)退群

  • 主動(dòng)退群后, 所有群成員會(huì)收到一條類型為'leaveTeam'群通知消息。此類群通知消息的from字段的值為退群的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象
nim.leaveTeam({
teamId: 123,
done: leaveTeamDone
});
function leaveTeamDone(error, obj) {
console.log(error);
console.log(obj);
console.log('主動(dòng)退群' + (!error?'成功':'失敗'));
}

轉(zhuǎn)讓群

  • 轉(zhuǎn)讓群后, 所有群成員會(huì)收到一條類型為'transferTeam'群通知消息锅风。此類群通知消息的from字段的值為轉(zhuǎn)讓群的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為為新群主的帳號(hào), attach有一個(gè)字段members的值為包含新舊群主的群成員列表酥诽。
  • 如果轉(zhuǎn)讓群的同時(shí)離開群, 那么相當(dāng)于調(diào)用主動(dòng)退群來離開群, 所有群成員會(huì)再收到一條類型為'leaveTeam'群通知消息
nim.transferTeam({
teamId: 123,
account: 'zyy2',
leave: false,
done: transferOwnerDone
});
function transferOwnerDone(error, obj) {
console.log(error);
console.log(obj);
console.log('轉(zhuǎn)讓群' + (!error?'成功':'失敗'));
}

解散群

  • 解散群后, 所有群成員會(huì)收到一條類型為'dismissTeam'群通知消息皱埠。此類群通知消息的from字段為解散群的人的帳號(hào), to字段的值為被對(duì)應(yīng)的群ID肮帐。
nim.dismissTeam({
teamId: 123,
done: dismissTeamDone
});
function dismissTeamDone(error, obj) {
console.log(error);
console.log(obj);
console.log('解散群' + (!error?'成功':'失敗'));
}

修改自己的群屬性

目前支持修改的屬性有這些

  • nickInTeam: 自己在群里面的群昵稱
  • 更新昵稱后, 所有其它在線的群成員會(huì)收到初始化SDK時(shí)傳入的onupdateteammember回調(diào)
  • muteTeam: 是否關(guān)閉此群的消息提醒, true表示關(guān)閉提醒, 但是SDK仍然會(huì)收到這個(gè)群的消息, SDK只是記錄這個(gè)設(shè)置, 具體根據(jù)這個(gè)設(shè)置要執(zhí)行的操作由第三方APP決定, 設(shè)置之后可以調(diào)用接口是否需要群消息通知來查詢是否需要群消息通知
  • custom: 第三方擴(kuò)展字段, 開發(fā)者可以自行擴(kuò)展, 建議封裝成JSON格式字符串
nim.updateInfoInTeam({
teamId: 123,
// 此參數(shù)為可選參數(shù)
// nickInTeam: '群昵稱',
// 靜音群, 此參數(shù)為可選參數(shù)
// muteTeam: true,
// 第三方擴(kuò)展字段
// custom: '{}'
done: updateInfoInTeamDone
});
function updateInfoInTeamDone(error, obj) {
console.log(error);
console.log(obj);
console.log('修改自己的群屬性' + (!error?'成功':'失敗'));
}

修改別人的群昵稱

  • 所有其它在線的群成員會(huì)收到會(huì)收到初始化SDK時(shí)傳入的onupdateteammember回調(diào)
nim.updateNickInTeam({
teamId: 123,
account: 'a2',
nickInTeam: '群昵稱',
done: updateNickInTeamDone
});
function updateNickInTeamDone(error, obj) {
console.log(error);
console.log(obj);
console.log('修改自己的群屬性' + (!error?'成功':'失敗'));
}

更新群成員禁言狀態(tài)

  • 更新群成員禁言狀態(tài)后, 所有群成員會(huì)收到一條類型為'updateTeamMute'群通知消息。此類群通知消息的from字段的值為操作方, to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為被禁言的帳號(hào), attach有一個(gè)字段members的值為被禁言的群成員列表边器。
nim.updateMuteStateInTeam({
teamId: '123',
account: 'a',
mute: true,
done: updateMuteStateInTeamDone
})
function updateMuteStateInTeamDone(error, obj) {
console.log('更新群成員禁言狀態(tài)' + (!error?'成功':'失敗'), error, obj);
}

獲取群禁言成員列表

nim.getMutedTeamMembers({
teamId: 'teamId',
done: getMutedTeamMembersDone
})
function getMutedTeamMembersDone (error, obj) {
console.log('獲取群禁言成員列表' + (!error?'成功':'失敗'))
console.log(obj)
}

獲取群

  • 開發(fā)者可以調(diào)用此接口獲取群資料
nim.getTeam({
teamId: 123,
done: getTeamDone
});
function getTeamDone(error, obj) {
console.log(error);
console.log(obj);
console.log('獲取群' + (!error?'成功':'失敗'));
}

獲取群列表

  • 如果開發(fā)者在初始化SDK的時(shí)候設(shè)置了syncTeamsfalse, 那么就收不到onteams回調(diào), 可以調(diào)用此方法來獲取列表
nim.getTeams({
done: getTeamsDone
});
function getTeamsDone(error, teams) {
console.log(error);
console.log(teams);
console.log('獲取群列表' + (!error?'成功':'失敗'));
if (!error) {
onTeams(teams);
}
}

獲取群成員

nim.getTeamMembers({
teamId: 123,
done: getTeamMembersDone
});
function getTeamMembersDone(error, obj) {
console.log(error);
console.log(obj);
console.log('獲取群成員' + (!error?'成功':'失敗'));
if (!error) {
onTeamMembers(obj);
}
}

是否需要群消息通知

  • 此接口用于查詢是否需要群消息通知
  • 成功時(shí)會(huì)附上一個(gè) map, key 是群 ID, value 是一個(gè)布爾值, 表示該群是否需要群消息通知
  • 調(diào)用接口修改自己的群屬性來關(guān)閉/開啟某個(gè)群的消息提醒
nim.notifyForNewTeamMsg({
teamIds: ['123'],
done: notifyForNewTeamMsgDone
})
function notifyForNewTeamMsgDone(error, map) {
console.log(error);
console.log(map);
console.log('查詢是否需要群消息通知' + (!error?'成功':'失敗'));
}

會(huì)話

生成規(guī)則

SDK 會(huì)根據(jù)漫游消息和離線消息來生成初始會(huì)話列表, 在收到消息和發(fā)送消息之后 SDK 會(huì)更新會(huì)話列表

會(huì)話初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onsessions: onSessions,
onupdatesession: onUpdateSession
});
function onSessions(sessions) {
console.log('收到會(huì)話列表', sessions);
data.sessions = nim.mergeSessions(data.sessions, sessions);
updateSessionsUI();
}
function onUpdateSession(session) {
console.log('會(huì)話更新了', session);
data.sessions = nim.mergeSessions(data.sessions, session);
updateSessionsUI();
}
function updateSessionsUI() {
// 刷新界面
}

參數(shù)解釋

會(huì)話對(duì)象

會(huì)話對(duì)象有以下字段:

  • id: 會(huì)話ID
  • scene: 場(chǎng)景
  • to: 聊天對(duì)象, 賬號(hào)或群ID
  • updateTime: 會(huì)話更新的時(shí)間
  • unread: 未讀數(shù)
  • lastMsg: 此會(huì)話的最后一條消息
  • msgReceiptTime: 消息已讀回執(zhí)時(shí)間戳, 如果有此字段, 說明此時(shí)間戳之前的所有消息對(duì)方均已讀
  • 目前僅對(duì)'p2p'會(huì)話起作用
  • 此字段不一定有, 只有對(duì)方發(fā)送過已讀回執(zhí)之后才會(huì)有
  • 調(diào)用接口發(fā)送消息已讀回執(zhí)來發(fā)送消息已讀回執(zhí)
  • 調(diào)用接口查詢消息是否被對(duì)方讀過了來查詢消息是否被對(duì)方讀過了
  • localCustom: 本地自定義擴(kuò)展字段
  • 支持?jǐn)?shù)據(jù)庫時(shí)可以調(diào)用更新本地會(huì)話來更新此字段, 此字段只會(huì)被更新到本地?cái)?shù)據(jù)庫, 不會(huì)被更新到服務(wù)器上

未讀數(shù)

SDK 會(huì)自動(dòng)管理會(huì)話的未讀數(shù), 會(huì)話對(duì)象的unread的值為會(huì)話的未讀數(shù), 如果開發(fā)者發(fā)現(xiàn)會(huì)話的未讀數(shù)大于收到的離線消息數(shù), 那么需要從本地拉取未讀取的消息

會(huì)話未讀數(shù)的初始化在不同的配置環(huán)境下训枢,會(huì)有不同的計(jì)算規(guī)則:

  • 開啟數(shù)據(jù)庫: db = true
  • 開啟同步會(huì)話未讀數(shù): syncSessionUnread = true
  • 此時(shí)會(huì)話未讀數(shù)通過服務(wù)器下推的Ack或本地存儲(chǔ)的Ack時(shí)間戳,與本地?cái)?shù)據(jù)庫中對(duì)應(yīng)會(huì)話的本地歷史記錄做比較忘巧,晚于該Ack且不是自己發(fā)的消息的數(shù)量恒界,為未讀數(shù)
  • 參見會(huì)話初始化參數(shù)
  • 未開啟會(huì)話未讀數(shù): syncSessionUnread = false
  • 此時(shí)會(huì)話未讀數(shù)通過從本地?cái)?shù)據(jù)庫上次所記錄的未讀數(shù)中取得,如果有離線消息且消息屬性標(biāo)記為isUnreadable砚嘴,則會(huì)在原來的未讀數(shù)上增加計(jì)數(shù)
  • 不開啟數(shù)據(jù)庫: db = false
  • 不開啟自動(dòng)標(biāo)記消息已讀: autoMarkRead = false
  • 此時(shí)服務(wù)器下推的所有離線消息算未讀十酣,漫游消息算已讀
  • 開啟自動(dòng)標(biāo)記消息已讀: autoMarkRead = true
  • 此時(shí)每次收到離線消息,均會(huì)告知服務(wù)器該消息已讀际长,下一次登錄耸采,服務(wù)器就不會(huì)下推離線消息,而將這些消息標(biāo)記為漫游消息工育。沒有離線消息洋幻,未讀數(shù)在表現(xiàn)上均為0
  • 參見標(biāo)記消息為已收到

設(shè)置當(dāng)前會(huì)話

  • 如果是已經(jīng)存在的會(huì)話記錄, 會(huì)將此會(huì)話未讀數(shù)置為 0, 開發(fā)者會(huì)收到onupdatesession回調(diào)
  • 之后此會(huì)話在收到消息之后不會(huì)更新未讀數(shù)
nim.setCurrSession('sessionId')

重置會(huì)話未讀數(shù)

  • 如果是已經(jīng)存在的會(huì)話記錄, 會(huì)將此會(huì)話未讀數(shù)置為 0, 那么會(huì)收到onupdatesession回調(diào)
  • 之后此會(huì)話在收到消息之后依然會(huì)更新未讀數(shù)
nim.resetSessionUnread('sessionId')

重置當(dāng)前回話

  • 重置當(dāng)前會(huì)話后, 所有會(huì)話在收到消息之后會(huì)更新未讀數(shù)
nim.resetCurrSession();

獲取本地會(huì)話列表

  • 支持?jǐn)?shù)據(jù)庫時(shí), SDK 會(huì)將會(huì)話存儲(chǔ)于數(shù)據(jù)庫中, 并且在初始化時(shí)通過回調(diào)onsessions將會(huì)話列表返回給開發(fā)者, 不過此列表最多 100 條記錄
  • 如果想獲取更多會(huì)話記錄, 可以調(diào)用此方法來獲取更多本地會(huì)話記錄
  • lastSessionId為上次查詢的最后一條會(huì)話的id, 第一次不填
  • limit為本次查詢的會(huì)話數(shù)量限制, 最多 100 條, 默認(rèn) 100 條
  • 默認(rèn)從最近的會(huì)話開始往前查找本地會(huì)話, 可以傳參數(shù)reverse=true來從第一條會(huì)話開始往后查找本地會(huì)話
nim.getLocalSessions({
lastSessionId: lastSessionId,
limit: 100,
done: getLocalSessionsDone
});
function getLocalSessionsDone(error, obj) {
console.log(error);
console.log(obj);
console.log('獲取本地會(huì)話列表' + (!error?'成功':'失敗'));
if (!error) {
onSessions(obj.sessions);
}
}

插入一條本地會(huì)話記錄

  • 開發(fā)者可以插入一條本地會(huì)話記錄, 在支持?jǐn)?shù)據(jù)庫時(shí), SDK 會(huì)將此會(huì)話存儲(chǔ)于本地?cái)?shù)據(jù)庫, 反之, 數(shù)據(jù)僅存于內(nèi)存里面
  • SDK 會(huì)設(shè)置一個(gè)比當(dāng)前所有會(huì)話更新時(shí)間大的一個(gè)時(shí)間為此會(huì)話的更新時(shí)間, 或者開發(fā)者可以傳入?yún)?shù)updateTime來指定更新時(shí)間
  • 在回調(diào)里面, 開發(fā)者需要保存生成的會(huì)話
nim.insertLocalSession({
scene: 'p2p',
to: 'account',
done: insertLocalSessionDone
});
function insertLocalSessionDone(error, obj) {
console.log('插入本地會(huì)話記錄' + (!error?'成功':'失敗'), error, obj);
if (!error) {
onSessions(obj.session);
}
}

更新本地會(huì)話

  • 更新 id 對(duì)應(yīng)的本地會(huì)話
  • 如果不支持?jǐn)?shù)據(jù)庫, 算成功
  • 如果對(duì)應(yīng)的會(huì)話不存在, 算成功, 返回 null
  • 這些字段只會(huì)被更新到本地?cái)?shù)據(jù)庫, 不會(huì)被更新到服務(wù)器上
  • 目前只允許更新 localCustom
nim.updateLocalSession({
id: 'p2p-account',
localCustom: '{"key","value"}',
done: updateLocalSessionDone
});
function updateLocalSessionDone(error, obj) {
console.log(error);
console.log(obj);
console.log('更新本地會(huì)話' + (!error?'成功':'失敗'));
}

刪除本地會(huì)話

  • 支持?jǐn)?shù)據(jù)庫時(shí), 刪了本地會(huì)話之后, 下次同步就同步不到對(duì)應(yīng)的會(huì)話
  • 如果不支持?jǐn)?shù)據(jù)庫, 算成功
  • 如果對(duì)應(yīng)的會(huì)話不存在, 算成功
  • 參數(shù) id 為會(huì)話 id 或 id 數(shù)組
nim.deleteLocalSession({
id: 'p2p-account',
done: deleteLocalSessionDone
});
function deleteLocalSessionDone(error, obj) {
console.log(error);
console.log(obj);
console.log('刪除本地會(huì)話' + (!error?'成功':'失敗'));
}

刪除服務(wù)器上的會(huì)話

  • 刪了服務(wù)器上的會(huì)話之后, 在不支持?jǐn)?shù)據(jù)庫時(shí), 下次同步就同步不到對(duì)應(yīng)的會(huì)話以及會(huì)話對(duì)應(yīng)的漫游消息; 此外, 在新設(shè)備上也同步不到對(duì)應(yīng)的會(huì)話以及會(huì)話對(duì)應(yīng)的漫游消息
  • scene請(qǐng)參考消息場(chǎng)景
  • to 為對(duì)方賬號(hào)或群ID
nim.deleteSession({
scene: 'p2p',
to: 'account',
done: deleteSessionDone
});
function deleteSessionDone(error, obj) {
console.log(error);
console.log(obj);
console.log('刪除服務(wù)器上的會(huì)話' + (!error?'成功':'失敗'));
}

批量刪除服務(wù)器上的會(huì)話

  • 刪了服務(wù)器上的會(huì)話之后, 在不支持?jǐn)?shù)據(jù)庫時(shí), 下次同步就同步不到對(duì)應(yīng)的會(huì)話以及會(huì)話對(duì)應(yīng)的漫游消息; 此外, 在新設(shè)備上也同步不到對(duì)應(yīng)的會(huì)話以及會(huì)話對(duì)應(yīng)的漫游消息
  • scene請(qǐng)參考消息場(chǎng)景
  • to 為對(duì)方賬號(hào)或群ID
nim.deleteSessions({
sessions: {[
scene: 'p2p',
to: 'account'
], [
scene: 'p2p',
to: 'account1'
]},
done: deleteSessionsDone
});
function deleteSessionsDone(error, obj) {
console.log(error);
console.log(obj);
console.log('批量刪除會(huì)話' + (!error?'成功':'失敗'));
}

消息

消息初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onroamingmsgs: onRoamingMsgs,
onofflinemsgs: onOfflineMsgs,
onmsg: onMsg
});
function onRoamingMsgs(obj) {
console.log('收到漫游消息', obj);
pushMsg(obj.msgs);
}
function onOfflineMsgs(obj) {
console.log('收到離線消息', obj);
pushMsg(obj.msgs);
}
function onMsg(msg) {
console.log('收到消息', msg.scene, msg.type, msg);
pushMsg(msg);
switch (msg.type) {
case 'custom':
onCustomMsg(msg);
break;
case 'notification':
// 處理群通知消息
onTeamNotificationMsg(msg);
break;
default:
break;
}
}
function pushMsg(msgs) {
if (!Array.isArray(msgs)) { msgs = [msgs]; }
var sessionId = msgs[0].sessionId;
data.msgs = data.msgs || {};
data.msgs[sessionId] = nim.mergeMsgs(data.msgs[sessionId], msgs);
}
function onCustomMsg(msg) {
// 處理自定義消息
}

參數(shù)解釋

  • shouldIgnoreNotification, 是否要忽略某條通知類消息, 該方法會(huì)接收一個(gè)消息對(duì)象, 如果該方法返回 true, 那么 SDK 將忽略此條通知類消息
  • onroamingmsgs, 同步漫游消息的回調(diào), 每個(gè)會(huì)話對(duì)應(yīng)一個(gè)回調(diào), 會(huì)傳入消息數(shù)組
  • onofflinemsgs, 同步離線消息的回調(diào), 每個(gè)會(huì)話對(duì)應(yīng)一個(gè)回調(diào), 會(huì)傳入消息數(shù)組
  • 支持?jǐn)?shù)據(jù)庫時(shí)并且啟用了多 tab 同時(shí)登錄, 那么如果多個(gè) tab 頁同時(shí)斷線重連之后, 只會(huì)有一個(gè) tab 頁負(fù)責(zé)存儲(chǔ)漫游消息和離線消息, 即只會(huì)有一個(gè) tab 頁會(huì)收到 onroamingmsgsonofflinemsgs 回調(diào), 其它 tab 頁在同步完成之后, 需要調(diào)用獲取本地歷史記錄來從本地緩存中拉取消息記錄
  • onmsg, 收到消息的回調(diào)
  • 當(dāng)前登錄帳號(hào)在其它端發(fā)送消息之后也會(huì)收到此回調(diào), 注意此時(shí)消息對(duì)象的from字段就是當(dāng)前登錄的帳號(hào)
  • 可以調(diào)用nim.mergeMsgs來合并數(shù)據(jù)

消息對(duì)象

消息對(duì)象有以下字段

  • scene: 消息場(chǎng)景
  • from: 消息發(fā)送方, 帳號(hào)或群id
  • fromNick: 消息發(fā)送方的昵稱
  • fromClientType: 發(fā)送方的設(shè)備類型
  • fromDeviceId: 發(fā)送端設(shè)備id
  • to: 消息接收方, 帳號(hào)或群id
  • time: 時(shí)間戳
  • type: 消息類型
  • sessionId: 消息所屬的會(huì)話的ID
  • target: 聊天對(duì)象, 賬號(hào)或者群id
  • flow: 消息的流向
  • 'in'表示此消息是收到的消息
  • 'out'表示此消息是發(fā)出的消息
  • status: 消息發(fā)送狀態(tài)
  • 'sending' 發(fā)送中
  • 'success' 發(fā)送成功
  • 'fail' 發(fā)送失敗
  • text: 文本消息的文本內(nèi)容, 請(qǐng)參考發(fā)送文本消息
  • file: 文件消息的文件對(duì)象, 具體字段請(qǐng)參考圖片對(duì)象音頻對(duì)象翅娶、視頻對(duì)象文留、文件對(duì)象, 請(qǐng)參考發(fā)送文件消息
  • geo: 地理位置消息的地理位置對(duì)象, 請(qǐng)參考發(fā)送地理位置消息
  • tip: 提醒消息的內(nèi)容, 請(qǐng)參考發(fā)送提醒消息
  • content: 自定義消息或機(jī)器人回復(fù)消息的消息內(nèi)容, 開發(fā)者可以自行擴(kuò)展, 建議封裝成JSON格式字符串, 請(qǐng)參考發(fā)送自定義消息
  • attach: 群通知消息的附加信息, 參考群通知消息來查看不同類型的群通知消息對(duì)應(yīng)的附加信息
  • idClient: SDK生成的消息id, 在發(fā)送消息之后會(huì)返回給開發(fā)者, 開發(fā)者可以在發(fā)送消息的回調(diào)里面根據(jù)這個(gè)ID來判斷相應(yīng)消息的發(fā)送狀態(tài), 到底是發(fā)送成功了還是發(fā)送失敗了, 然后根據(jù)此狀態(tài)來更新頁面的UI。如果發(fā)送失敗, 那么可以重發(fā)消息
  • idServer: 服務(wù)器用于區(qū)分消息用的ID, 主要用于獲取云端歷史記錄
  • isMuted: 該消息在接收方是否應(yīng)該被靜音
  • resend: 是否是重發(fā)的消息
  • custom: 擴(kuò)展字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • pushContent: 自定義推送文案
  • pushPayload: 自定義的推送屬性
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • needPushNick: 是否需要推送昵稱
  • apns: 特殊推送選項(xiàng), 只在群會(huì)話中使用
  • apns.accounts: 需要特殊推送的賬號(hào)列表, 此字段不存在的話表示推送給當(dāng)前會(huì)話內(nèi)的所有用戶
  • apns.content: 需要特殊推送的文案
  • apns.forcePush: 是否強(qiáng)制推送, true 表示即使推送列表中的用戶屏蔽了當(dāng)前會(huì)話(如靜音), 仍能夠推送當(dāng)前這條內(nèi)容給相應(yīng)用戶
  • localCustom: 本地自定義擴(kuò)展字段
  • 支持?jǐn)?shù)據(jù)庫時(shí)可以調(diào)用更新本地消息來更新此字段, 此字段只會(huì)被更新到本地?cái)?shù)據(jù)庫, 不會(huì)被更新到服務(wù)器上
  • isHistoryable: 是否存儲(chǔ)云端歷史
  • isRoamingable: 是否支持漫游
  • isSyncable: 是否支持發(fā)送者多端同步
  • cc: 是否支持抄送
  • isPushable: 是否需要推送
  • isOfflinable: 是否要存離線
  • isUnreadable: 是否計(jì)入消息未讀數(shù)
  • isLocal: 是否是本地消息, 請(qǐng)查閱發(fā)送本地消息

消息場(chǎng)景

消息對(duì)象有一個(gè)字段scene來標(biāo)明消息所屬的場(chǎng)景, 具體場(chǎng)景如下

  • 'p2p' (點(diǎn)對(duì)點(diǎn)消息)
  • 'team' (群消息)

消息類型

消息對(duì)象有一個(gè)字段type來標(biāo)明消息的類型, 具體類型如下

  • 'text' (文本消息)
  • 'image' (圖片消息)
  • 'audio' (音頻消息)
  • 'video' (視頻消息)
  • 'file' (文件消息)
  • 'geo' (地理位置消息)
  • 'custom' (自定義消息)
  • 'tip' (提醒消息)
  • 提醒消息用于會(huì)話內(nèi)的狀態(tài)提醒竭沫,如進(jìn)入會(huì)話時(shí)出現(xiàn)的歡迎消息燥翅,或者會(huì)話命中敏感詞后的提示消息等等.
  • 'robot' (AI機(jī)器人消息)
  • 'notification' (群通知消息)
  • 某些群操作后所有群成員會(huì)收到一條相應(yīng)的群通知消息, 詳細(xì)介紹請(qǐng)參考群通知消息
  • 此類消息不會(huì)計(jì)入未讀數(shù)
  • 請(qǐng)參考消息對(duì)象消息類型

群通知消息

  • 群通知消息是消息的一種
  • 某些群操作后所有群成員會(huì)收到一條相應(yīng)的群通知消息
  • 群通知消息對(duì)應(yīng)的消息對(duì)象有一個(gè)字段attach包含了額外的信息, attach有一個(gè)字段type來標(biāo)識(shí)群通知消息的類型
  • 'updateTeam' (更新群)
  • 更新群后, 所有群成員會(huì)收到一條類型為'updateTeam'群通知消息蜕提。此類群通知消息的from字段的值為更新群的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為被更新的群信息
  • 'addTeamMembers' (拉人入群)
  • 普通群, 拉人入群后, 所有群成員會(huì)收到一條類型為'addTeamMembers'群通知消息森书。此類群通知消息的from字段的值為拉人的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段accounts的值為被拉的人的帳號(hào)列表, attach有一個(gè)字段members的值為被拉的群成員列表。
  • 'removeTeamMembers' (踢人出群)
  • 踢人出群后, 所有群成員會(huì)收到一條類型為'removeTeamMembers'群通知消息谎势。此類群通知消息的from字段的值為踢人的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段accounts的值為被踢的人的帳號(hào)列表凛膏。
  • 'acceptTeamInvite' (接受入群邀請(qǐng))
  • 高級(jí)群的群主和管理員在邀請(qǐng)成員加入群(通過操作創(chuàng)建群拉人入群)之后, 被邀請(qǐng)的人會(huì)收到一條類型為'teamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為邀請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 此類系統(tǒng)通知的attach有一個(gè)字段team的值為被邀請(qǐng)進(jìn)入的, 被邀請(qǐng)的人可以選擇接受邀請(qǐng)或者拒絕邀請(qǐng)。
  • 如果接受邀請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'acceptTeamInvite'群通知消息, 此類群通知消息的from字段的值為接受入群邀請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段members的值為接收入群邀請(qǐng)的群成員列表脏榆。
  • 如果拒絕邀請(qǐng), 那么邀請(qǐng)你的人會(huì)收到一條類型為'rejectTeamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕入群邀請(qǐng)的用戶的帳號(hào), to字段的值為對(duì)應(yīng)的群ID猖毫。
  • 'passTeamApply' (通過入群申請(qǐng))
  • 用戶可以申請(qǐng)加入高級(jí)群, 目標(biāo)群的群主和管理員會(huì)收到一條類型為'applyTeam'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 高級(jí)群的群主和管理員在收到入群申請(qǐng)后, 可以選擇通過或者拒絕入群申請(qǐng)。
  • 如果通過申請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'passTeamApply'群通知消息, 此類群通知消息的from字段的值為通過入群申請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為申請(qǐng)方的帳號(hào), attach有一個(gè)字段members的值為被通過申請(qǐng)的群成員列表须喂。
  • 如果拒絕申請(qǐng), 那么申請(qǐng)人會(huì)收到一條類型為'rejectTeamApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的吁断。
  • 'addTeamManagers' (添加群管理員)
  • 添加群管理員后, 所有群成員會(huì)收到一條類型為'addTeamManagers'群通知消息趁蕊。此類群通知消息的from字段的值為添加群管理員的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段accounts的值為被加為管理員的帳號(hào)列表, attach有一個(gè)字段members的值為被加為管理員的群成員列表
  • 'removeTeamManagers' (移除群管理員)
  • 移除群管理員后, 所有群成員會(huì)收到一條類型為'removeTeamManagers'群通知消息。此類群通知消息的from字段的值為移除群管理員的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段accounts的值為被移除的管理員的帳號(hào)列表, attach有一個(gè)字段members的值為被移除管理員的群成員列表
  • 'leaveTeam' (主動(dòng)退群)
  • 主動(dòng)退群后, 所有群成員會(huì)收到一條類型為'leaveTeam'群通知消息。此類群通知消息的from字段的值為退群的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象
  • 'dismissTeam' (解散群)
  • 解散群后, 所有群成員會(huì)收到一條類型為'dismissTeam'群通知消息焚刺。此類群通知消息的from字段為解散群的人的帳號(hào), to字段的值為被對(duì)應(yīng)的群ID。
  • 'transferTeam' (轉(zhuǎn)讓群)
  • 轉(zhuǎn)讓群后, 所有群成員會(huì)收到一條類型為'transferTeam'群通知消息状知。此類群通知消息的from字段的值為轉(zhuǎn)讓群的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為為新群主的帳號(hào), attach有一個(gè)字段members的值為包含新舊群主的群成員列表。
  • 'updateTeamMute' (更新群成員禁言狀態(tài))
  • 更新群成員禁言狀態(tài)后, 所有群成員會(huì)收到一條類型為'updateTeamMute'群通知消息。此類群通知消息的from字段的值為操作方, to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為被禁言的帳號(hào), attach有一個(gè)字段members的值為被禁言的群成員列表。
  • 如果attachaccount或者accounts字段, 那么attach的字段users包含這些賬號(hào)對(duì)應(yīng)的用戶名片
  • 更新群昵稱不會(huì)收到群通知消息, 所有其它在線的群成員會(huì)收到初始化SDK時(shí)傳入的onupdateteammember回調(diào), 請(qǐng)參考修改自己的群屬性修改別人的群昵稱

處理群通知消息

示例代碼

function onTeamNotificationMsg(msg) {
// 處理群通知消息
var type = msg.attach.type,
from = msg.from,
teamId = msg.to,
timetag = msg.time,
team = msg.attach.team,
account = msg.attach.account,
accounts = msg.attach.accounts,
members = msg.attach.members;
switch (type) {
case 'updateTeam':
team.updateTime = timetag;
onTeams(team);
break;
case 'addTeamMembers':
onAddTeamMembers(team, accounts, members);
break;
case 'removeTeamMembers':
onRemoveTeamMembers(team, teamId, accounts);
break;
case 'acceptTeamInvite':
onAddTeamMembers(team, [from], members);
break;
case 'passTeamApply':
onAddTeamMembers(team, [account], members);
break;
case 'addTeamManagers':
updateTeamManagers(teamId, members);
break;
case 'removeTeamManagers':
updateTeamManagers(teamId, members);
break;
case 'leaveTeam':
onRemoveTeamMembers(team, teamId, [from]);
break;
case 'dismissTeam':
dismissTeam(teamId);
break;
case 'transferTeam':
transferTeam(team, members);
break;
}
}
function onAddTeamMembers(team, accounts, members) {
var teamId = team.teamId;
/*
如果是別人被拉進(jìn)來了宙地,那么拼接群成員列表
如果是自己被拉進(jìn)來了,那么同步一次群成員列表
*/
if (accounts.indexOf(data.account) === -1) {
onTeamMembers({
teamId: teamId,
members: members
});
} else {
nim.getTeamMembers({
teamId: teamId,
sync: true,
done: function(error, obj) {
if (!error) {
onTeamMembers(obj);
}
}
});
}
onTeams(team);
}
function onRemoveTeamMembers(team, teamId, accounts) {
/*
如果是別人被踢了俄烁,那么移除群成員
如果是自己被踢了,那么離開該群
*/
if (accounts.indexOf(data.account) === -1) {
if (team) {
onTeams(team);
}
data.teamMembers[teamId] = nim.cutTeamMembersByAccounts(data.teamMembers[teamId], teamId, accounts);
refreshTeamMembersUI();
} else {
leaveTeam(teamId);
}
}
function updateTeamManagers(teamId, members) {
onTeamMembers({
teamId: teamId,
members: members
});
};
function leaveTeam(teamId) {
onInvalidTeams({
teamId: teamId
});
removeAllTeamMembers(teamId);
}
function dismissTeam(teamId) {
onInvalidTeams({
teamId: teamId
});
removeAllTeamMembers(teamId);
}
function removeAllTeamMembers(teamId) {
delete data.teamMembers[teamId];
refreshTeamMembersUI();
}
function transferTeam(team, members) {
var teamId = team.teamId;
onTeamMembers({
teamId: teamId,
members: members
});
onTeams(team);
}

參數(shù)解釋

發(fā)送消息

發(fā)送文本消息

  • 文本消息是消息的一種
var msg = nim.sendText({
scene: 'p2p',
to: 'account',
text: 'hello',
done: sendMsgDone
});
console.log('正在發(fā)送p2p text消息, id=' + msg.idClient);
pushMsg(msg);
function sendMsgDone(error, msg) {
console.log(error);
console.log(msg);
console.log('發(fā)送' + msg.scene + ' ' + msg.type + '消息' + (!error?'成功':'失敗') + ', id=' + msg.idClient);
pushMsg(msg);
}

預(yù)覽文件

  • 開發(fā)者可以預(yù)覽文件, 支持以下幾種場(chǎng)景
  • 通過參數(shù)fileInput傳入文件選擇 dom 節(jié)點(diǎn)或者節(jié)點(diǎn) ID
  • 通過參數(shù)blob傳入 Blob 對(duì)象
  • 通過參數(shù)dataURL傳入包含 MIME type 和 base64 數(shù)據(jù)的 data URL, 此用法需要瀏覽器支持 window.Blob
  • 通過參數(shù)wxFilePath傳入臨時(shí)文件路徑, 僅供微信小程序使用, 通過 wx.chooseImage 或者 wx.startRecord 拿到的臨時(shí)文件路徑
  • SDK會(huì)將文件上傳到文件服務(wù)器, 然后將拿到的文件對(duì)象在done回調(diào)中傳給開發(fā)者, 文件對(duì)象有以下幾種
  • 圖片對(duì)象
  • 音頻對(duì)象
  • 視頻對(duì)象
  • 文件對(duì)象
  • 開發(fā)者在拿到文件對(duì)象之后, 可以調(diào)用發(fā)送文件消息來發(fā)送文件消息页屠。
  • 文件大小限制為最大100M
  • 高級(jí)瀏覽器會(huì)在上傳前就檢測(cè)文件大小
  • IE8/IE9 會(huì)在上傳完成后檢測(cè)文件大小
nim.previewFile({
type: 'image',
fileInput: fileInput,
uploadprogress: function(obj) {
console.log('文件總大小: ' + obj.total + 'bytes');
console.log('已經(jīng)上傳的大小: ' + obj.loaded + 'bytes');
console.log('上傳進(jìn)度: ' + obj.percentage);
console.log('上傳進(jìn)度文本: ' + obj.percentageText);
},
done: function(error, file) {
console.log('上傳image' + (!error?'成功':'失敗'));
// show file to the user
if (!error) {
var msg = nim.sendFile({
scene: 'p2p',
to: 'account',
file: file,
done: sendMsgDone
});
console.log('正在發(fā)送p2p image消息, id=' + msg.idClient);
pushMsg(msg);
}
}
});

發(fā)送文件消息

  • 文件消息是消息的一種
  • 開發(fā)者可以直接發(fā)送文件消息
  • 支持以下幾種場(chǎng)景
  • 通過參數(shù)fileInput傳入文件選擇 dom 節(jié)點(diǎn)或者節(jié)點(diǎn) ID
  • 通過參數(shù)blob傳入 Blob 對(duì)象
  • 通過參數(shù)dataURL傳入包含 MIME type 和 base64 數(shù)據(jù)的 data URL, 此用法需要瀏覽器支持 window.Blob
  • 通過參數(shù)wxFilePath傳入臨時(shí)文件路徑, 僅供微信小程序使用, 通過 wx.chooseImage 或者 wx.startRecord 拿到的臨時(shí)文件路徑
  • SDK會(huì)先將文件上傳到文件服務(wù)器, 然后把拿到的文件對(duì)象在uploaddone回調(diào)中傳給用戶, 然后將其拼裝成文件消息發(fā)送出去。
  • 開發(fā)者也可以先預(yù)覽文件來獲取文件對(duì)象, 然后調(diào)用此接口發(fā)送文件消息蓖柔。
  • 直接發(fā)送文件消息的話會(huì)在beforesend回調(diào)里面?zhèn)魅隨DK生成的idClient, 如果先預(yù)覽文件再發(fā)送, 那么此接口會(huì)直接返回idClient
  • 參數(shù)type指定了要發(fā)送的文件類型, 包括圖片辰企、音頻、視頻和普通文件, 對(duì)應(yīng)的值分別為'image'况鸣、'audio'牢贸、'video''file', 不傳默認(rèn)為'file'
  • 圖片镐捧、音頻潜索、視頻和普通文件的區(qū)別在于具體的文件信息不一樣, 具體字段請(qǐng)參考
  • 圖片對(duì)象
  • 音頻對(duì)象
  • 視頻對(duì)象
  • 文件對(duì)象
  • 文件大小限制為最大100M
  • 高級(jí)瀏覽器會(huì)在上傳前就檢測(cè)文件大小
  • IE8和IE9會(huì)在上傳完成后檢測(cè)文件大小
nim.sendFile({
scene: 'p2p',
to: 'account',
type: 'image',
fileInput: fileInput,
beginupload: function(upload) {
// - 如果開發(fā)者傳入 fileInput, 在此回調(diào)之前不能修改 fileInput
// - 在此回調(diào)之后可以取消圖片上傳, 此回調(diào)會(huì)接收一個(gè)參數(shù) `upload`, 調(diào)用 `upload.abort();` 來取消文件上傳
},
uploadprogress: function(obj) {
console.log('文件總大小: ' + obj.total + 'bytes');
console.log('已經(jīng)上傳的大小: ' + obj.loaded + 'bytes');
console.log('上傳進(jìn)度: ' + obj.percentage);
console.log('上傳進(jìn)度文本: ' + obj.percentageText);
},
uploaddone: function(error, file) {
console.log(error);
console.log(file);
console.log('上傳' + (!error?'成功':'失敗'));
},
beforesend: function(msg) {
console.log('正在發(fā)送p2p image消息, id=' + msg.idClient);
pushMsg(msg);
},
done: sendMsgDone
});

圖片對(duì)象

當(dāng)發(fā)送圖片消息或收到圖片消息時(shí), 消息對(duì)象file字段代表圖片對(duì)象, 包含以下屬性:

  • name: 名字
  • size: 大小, 單位byte
  • md5: md5
  • url: url
  • ext: 擴(kuò)展名
  • w: 寬, 單位px
  • h: 高, 單位px

音頻對(duì)象

當(dāng)發(fā)送音頻消息或收到音頻消息時(shí), 消息對(duì)象file字段代表音頻對(duì)象, 包含以下屬性:

  • name: 名字
  • size: 大小, 單位byte
  • md5: md5
  • url: url
  • ext: 擴(kuò)展名
  • dur: 長(zhǎng)度, 單位ms

視頻對(duì)象

當(dāng)發(fā)送視頻消息或收到視頻消息時(shí), 消息對(duì)象file字段代表視頻對(duì)象, 包含以下屬性:

  • name: 名字
  • size: 大小, 單位byte
  • md5: md5
  • url: url
  • ext: 擴(kuò)展名
  • dur: 長(zhǎng)度, 單位ms
  • w: 寬, 分辨率, 單位px
  • h: 高, 分辨率, 單位px

文件對(duì)象

當(dāng)發(fā)送文件消息或收到文件消息時(shí), 消息對(duì)象file字段代表文件對(duì)象, 包含以下屬性:

  • name: 名字
  • size: 大小, 單位byte
  • md5: md5
  • url: url
  • ext: 擴(kuò)展名

發(fā)送地理位置消息

var msg = nim.sendGeo({
scene: 'p2p',
to: 'account',
geo: {
lng: '116.3833',
lat: '39.9167',
title: 'Beijing'
},
done: sendMsgDone
});
console.log('正在發(fā)送p2p geo消息, id=' + msg.idClient);
pushMsg(msg);

地理位置對(duì)象

當(dāng)發(fā)送地理位置消息或收到地理位置消息時(shí), 消息對(duì)象geo字段代表地理位置對(duì)象, 包含以下屬性:

  • lng: 經(jīng)度
  • lat: 緯度
  • title: 地址描述

發(fā)送提醒消息

  • 提醒消息是消息的一種
  • 提醒消息用于會(huì)話內(nèi)的狀態(tài)提醒,如進(jìn)入會(huì)話時(shí)出現(xiàn)的歡迎消息懂酱,或者會(huì)話命中敏感詞后的提示消息等等.
var msg = nim.sendTipMsg({
scene: 'p2p',
to: 'account',
tip: 'tip content',
done: sendMsgDone
});
console.log('正在發(fā)送p2p提醒消息, id=' + msg.idClient);
pushMsg(msg);

發(fā)送自定義消息

  • 自定義消息是消息的一種
  • 在網(wǎng)易云信開放的web-demo源碼中竹习,type-1為[石頭剪刀布],type-2為[閱后即焚]列牺,type-3為[貼圖表情]整陌,type-4為[白板教學(xué)]
  • 下面的代碼用自定義消息實(shí)現(xiàn)了石頭剪刀布游戲
var value = Math.ceil(Math.random()*3);
var content = {
type: 1,
data: {
value: value
}
};
var msg = nim.sendCustomMsg({
scene: 'p2p',
to: 'account',
content: JSON.stringify(content),
done: sendMsgDone
});
console.log('正在發(fā)送p2p自定義消息, id=' + msg.idClient);
pushMsg(msg);

發(fā)送機(jī)器人消息

  • 機(jī)器人消息是消息的一種
  • 注意 這里的機(jī)器人消息區(qū)別于開發(fā)者業(yè)務(wù)后臺(tái)自行設(shè)定的機(jī)器人,而是網(wǎng)易云智能AI中配置的機(jī)器人消息瞎领,可以在網(wǎng)易云智能AI服務(wù)開通機(jī)器人服務(wù)
  • 機(jī)器人內(nèi)容格式規(guī)范可參考機(jī)器人消息體模板說明
  • 機(jī)器人消息參數(shù):
  • robotAccid 機(jī)器人帳號(hào)id
  • 如果是直接p2p與機(jī)器人聊天泌辫,此項(xiàng)可不填,to字段即為robotAccid九默。
  • body 用于記錄原始文本數(shù)據(jù)震放,在UI中展現(xiàn),如"@機(jī)器人 你好"驼修,實(shí)際發(fā)給機(jī)器人的字段則是"你好"二字澜搅。
  • content 機(jī)器人消息體伍俘,為javascript對(duì)象
  • type 機(jī)器人消息類型,封裝有:
  • welcome: 歡迎消息
  • text: 文本消息勉躺,需要配合參數(shù)content
  • link: bot鏈接消息癌瘾,需要配合參數(shù)params、target
  • content 機(jī)器人文本消息內(nèi)容
  • params 機(jī)器人鏈接消息參數(shù)
  • target 機(jī)器人鏈接消息目標(biāo)
// 直接在p2p會(huì)話中發(fā)送機(jī)器人消息
var msg = nim.sendRobotMsg({
scene: 'p2p',
to: 'robotAccid',
content: {
type: 'text',
content: '機(jī)器人你好'
}
done: sendMsgDone
});

// 在于他人的會(huì)話中通過@機(jī)器人 發(fā)送機(jī)器人消息
var msg = nim.sendRobotMsg({
scene: 'p2p',
to: 'account',
robotAccid: 'robotAccid',
content: {
type: 'link',
params: 'a=1&b=2',
target: 'A511F4B67336BE45-954F87865D2205C8'
}
done: sendMsgDone
})

function sendMsgDone(error, msg) {
console.log(error, msg);
console.log('發(fā)送' + msg.scene + ' ' + msg.type + '消息' + (!error?'成功':'失敗') + ', id=' + msg.idClient);
// ...
}

機(jī)器人回復(fù)消息模板解析

  • 對(duì)于使用網(wǎng)易AI服務(wù)得到的機(jī)器人自動(dòng)回復(fù)消息饵溅,SDK預(yù)置了相關(guān)的模板解析函數(shù)(同步函數(shù))妨退,幫助開發(fā)者解析相應(yīng)的xml模板。
  • xml模板可參考機(jī)器人消息體模板說明
  • 對(duì)于如下格式的xml模板
<template>
    <LinearLayout>
        <text name="label">您好蜕企,我是網(wǎng)易云信咬荷,點(diǎn)擊下面的按鈕測(cè)試復(fù)雜交互</text>
    </LinearLayout>
    <LinearLayout>
        <link style="button" target="http://netease.im" type="url">
        <text name="label">訪問官網(wǎng)</text>
        </link>
        <link style="button" target="A511F4B67336BE45-954F87865D2205C8" type="block">
        <text name="label">測(cè)試動(dòng)態(tài)接口</text>
        </link>
        <link style="button" target="A511F4B67336BE45-598B5F469F035733" type="block">
        <text name="label">繼續(xù)對(duì)話</text>
        </link>
    </LinearLayout>
</template>
  • 調(diào)用sdk內(nèi)置的方法parseRobotTemplate,將其轉(zhuǎn)化為
{
json: [
{
type:"text",
name: "label"
text: "您好轻掩,我是網(wǎng)易云信幸乒,點(diǎn)擊下面的按鈕測(cè)試復(fù)雜交互",
},
{
type:"url",
style: "button",
target: "http://netease.im",
text: [
{
type:"text",
name:"label",
text:"訪問官網(wǎng)"
}
]
},
{
type:"block",
params:"",
style:"button",
target:"A511F4B67336BE45-954F87865D2205C8",
text: [
type:"text",
name:"label",
text:"測(cè)試動(dòng)態(tài)接口"
]
},
{
type:"block",
params:"",
style:"button",
target:"A511F4B67336BE45-598B5F469F035733",
text: {
type:"text",
name:"label",
text:"繼續(xù)對(duì)話"
}
}
],
raw: `原始的xml字符串。唇牧。罕扎。`
}
  • 代碼使用參考示例:
if (msg.type === 'robot') {
if (msg.content && msg.content.flag === 'bot') {
if (msg.content.message) {
msg.content.message = msg.content.message.map(item => {
switch (item.type) {
case 'template':
item.content = nim.parseRobotTemplate(item.content)
break
case 'text':
case 'image':
case 'answer':
break
}
return item
})
}
}
}

發(fā)送消息的配置選項(xiàng)

  • 上面的各個(gè)發(fā)送消息的接口都可以配置額外的選項(xiàng), 來滿足開發(fā)者對(duì)服務(wù)器的自定義需求。
  • custom: 擴(kuò)展字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • pushContent: 自定義推送文案
  • pushPayload: 自定義的推送屬性
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • needPushNick: 是否需要推送昵稱
  • apns: 特殊推送選項(xiàng), 只在群會(huì)話中使用
  • apns.accounts: 需要特殊推送的賬號(hào)列表, 不填表示推送給當(dāng)前會(huì)話內(nèi)的所有用戶
  • apns.content: 需要特殊推送的文案, 不填的話默認(rèn)為 pushContent
  • apns.forcePush 是否強(qiáng)制推送, 不填的話默認(rèn) true. true 表示即使推送列表中的用戶屏蔽了當(dāng)前會(huì)話(如靜音), 仍能夠推送當(dāng)前這條內(nèi)容給相應(yīng)用戶
  • isHistoryable: 是否存儲(chǔ)云端歷史
  • isRoamingable: 是否支持漫游
  • isSyncable: 是否支持發(fā)送者多端同步
  • cc: 是否支持抄送
  • isPushable: 是否需要推送
  • isOfflinable: 是否要存離線
  • isUnreadable: 是否計(jì)入消息未讀數(shù)
  • yidunEnable: 是否需要過易盾反垃圾
  • antiSpamContent: 在開啟yidunEnable后, 開發(fā)者自定義的反垃圾字段(json格式)丐重,格式如下:{"type": 1, "data": "custom content"} 字段說明:type:1.文本腔召,2.圖片,3視頻扮惦,data內(nèi)容:文本內(nèi)容or圖片地址or視頻地址
  • 下面給一個(gè)發(fā)送文本消息的例子, 發(fā)送其它消息的接口類似
var msg = nim.sendText({
scene: 'p2p',
to: 'account',
text: 'hello',
custom: '{}',
done: sendMsgDone
});

發(fā)送本地消息

  • 發(fā)送消息時(shí)可以指定參數(shù)isLocaltrue, 那么SDK并不會(huì)發(fā)送此條消息, 而是直接調(diào)用回調(diào)表示發(fā)送成功, 并更新對(duì)應(yīng)的會(huì)話
var value = Math.ceil(Math.random()*3);
var content = {
type: 1,
data: {
value: value
}
};
var msg = nim.sendCustomMsg({
scene: 'p2p',
to: 'account',
content: JSON.stringify(content),
isLocal: true,
done: sendMsgDone
});
console.log('正在發(fā)送p2p自定義消息, id=' + msg.idClient);
pushMsg(msg);

重發(fā)消息

如果消息發(fā)送失敗, 那么可以重發(fā)消息

nim.resendMsg({
msg: someMsg,
done: sendMsgDone
})
console.log('正在重發(fā)消息', someMsg)

轉(zhuǎn)發(fā)消息

  • msg: 待轉(zhuǎn)發(fā)的消息
  • scene: 新的場(chǎng)景
  • to: 新的接收方, 對(duì)方帳號(hào)或者群id
nim.forwardMsg({
msg: someMsg,
scene: 'p2p',
to: 'account',
done: sendMsgDone
})
console.log('正在轉(zhuǎn)發(fā)消息', someMsg)

消息撤回

  • 在會(huì)話時(shí)臀蛛,允許用戶撤回一定時(shí)間內(nèi)發(fā)送過的消息,這個(gè)時(shí)長(zhǎng)可以由云信管理后臺(tái)進(jìn)行配置。
  • 如果需要在撤回后顯示一條已撤回的提示 ( 見 Demo 交互 ) 崖蜜,開發(fā)者可以自行構(gòu)造一條提醒消息并插入本地?cái)?shù)據(jù)庫浊仆。
  • 撤回消息后, 消息接收方會(huì)收到一條類型為'deleteMsg'系統(tǒng)通知, 此類系統(tǒng)通知的 msg 為被刪除的消息的部分字段。如果是群消息, 那么群里的所有人都會(huì)收到這條系統(tǒng)通知. 如果同時(shí)在多個(gè)端登錄了同一個(gè)賬號(hào), 那么其它端也會(huì)收到這條系統(tǒng)通知.
  • msg: 待撤回的消息
nim.deleteMsg({
msg: someMsg,
done: deleteMsgDone
})
console.log('正在撤回消息', someMsg)
function deleteMsgDone (error) {
console.log('撤回消息' + (!error?'成功':'失敗'), error);
}

標(biāo)記消息為已收到

  • 先解釋一下消息發(fā)送和接收的流程, A 發(fā)消息給 B, 實(shí)際的流程是:
  • A 將消息發(fā)送給服務(wù)器, 如果 B 在線, 服務(wù)器會(huì)將消息推給 B; 如果 B 不在線, 服務(wù)器會(huì)在 B 上線的時(shí)候?qū)⒋讼⒆鳛殡x線消息推給 B
  • B 在收到在線消息和離線消息之后, 需要告訴服務(wù)器收到了這些消息, 這樣 B 下次登錄時(shí)服務(wù)器就不會(huì)再次推這些消息
  • 如果 B 沒有告訴服務(wù)器收到了這些消息, 那么 B 下次登錄時(shí), 服務(wù)器會(huì)再次將這些消息推給 B
  • 默認(rèn)情況下, SDK 在收到消息(包括在線消息和離線消息)之后就將消息標(biāo)記為已收到, 這樣下次登錄時(shí)就不會(huì)再收到這些消息, 一般情況下開發(fā)者不需要關(guān)心此接口
  • 支持?jǐn)?shù)據(jù)庫時(shí), SDK 會(huì)將消息存儲(chǔ)于數(shù)據(jù)庫中, 如果開發(fā)者發(fā)現(xiàn)會(huì)話的未讀數(shù)大于收到的離線消息數(shù), 那么需要從本地拉取未讀取的消息.
  • 在不支持?jǐn)?shù)據(jù)庫時(shí), 如果開發(fā)者想控制標(biāo)記消息為已收到的時(shí)機(jī), 那么可以設(shè)置初始化參數(shù)autoMarkReadfalse, 這樣SDK就不會(huì)自動(dòng)標(biāo)記消息為已收到, 此時(shí)需要開發(fā)者在適當(dāng)?shù)臅r(shí)機(jī)調(diào)用此接口來標(biāo)記消息為已收到, 否則下次登錄后還是會(huì)收到未標(biāo)記為已收到的消息.

示例代碼

var nim = NIM.getInstance({
autoMarkRead: false
});
nim.markMsgRead(someMsg);
// or
nim.markMsgRead([someMsg]);

已讀回執(zhí)

  • 會(huì)話對(duì)象加了一個(gè)屬性msgReceiptTime表示消息已讀回執(zhí)時(shí)間戳, 如果有此字段, 說明此時(shí)間戳之前的所有消息對(duì)方均已讀
  • 目前僅對(duì)'p2p'會(huì)話起作用
  • 此字段不一定有, 只有對(duì)方發(fā)送過已讀回執(zhí)之后才會(huì)有
  • 調(diào)用接口發(fā)送消息已讀回執(zhí)來發(fā)送消息已讀回執(zhí)
  • 調(diào)用接口查詢消息是否被對(duì)方讀過了來查詢消息是否被對(duì)方讀過了

發(fā)送消息已讀回執(zhí)

  • 目前只支持'p2p'會(huì)話
  • 如果沒有傳入消息, 則直接返回成功
  • 如果已經(jīng)發(fā)送過比傳入的消息的時(shí)間戳大的已讀回執(zhí), 那么直接返回成功
  • 參數(shù)msg為要發(fā)送已讀回執(zhí)的會(huì)話的最后一條收到的消息, 可以直接通過session.lastMsg來獲取此消息
nim.sendMsgReceipt({
msg: session.lastMsg,
done: sendMsgReceiptDone
});
function sendMsgReceiptDone(error, obj) {
console.log('發(fā)送消息已讀回執(zhí)' + (!error?'成功':'失敗'), error, obj);
}

查詢消息是否被對(duì)方讀過了

  • 目前只支持'p2p'會(huì)話
var isRemoteRead = nim.isMsgRemoteRead(msg);

歷史記錄

本地歷史記錄

獲取本地歷史記錄

  • sessionId 如果提供該參數(shù), 那么查詢?cè)摃?huì)話的消息
  • sessionIds 如果提供該參數(shù), 那么查詢這幾個(gè)會(huì)話的消息
  • start=0 開始時(shí)間
  • end=Infinity 結(jié)束時(shí)間
  • desc=true true 表示從 end 開始查, false 表示從 begin 開始查
  • limit=100 limit 數(shù)量限制
  • type 消息類型, 如果提供該參數(shù), 那么查詢?cè)擃愋偷南?/li>
  • types 如果提供該參數(shù), 那么查詢這幾種類型的消息
  • keyword 如果提供參數(shù), 那么查詢匹配該關(guān)鍵詞的消息
nim.getLocalMsgs({
sessionId: 'p2p-account'
limit: 100,
done: getLocalMsgsDone
})
function getLocalMsgsDone(error, obj) {
console.log('獲取本地消息' + (!error?'成功':'失敗'), error, obj)
}

獲取 idClient 對(duì)應(yīng)的本地消息

nim.getLocalMsgByIdClient({
idClient: 'd7a1b2c63066e1038e9aa01321652370',
done: getLocalMsgByIdClientDone
});
function getLocalMsgByIdClientDone(error, obj) {
console.log(error);
console.log(obj);
console.log('獲取本地消息' + (!error?'成功':'失敗'));
if (!error) {
console.log(obj.msg);
}
}

獲取 idClients 對(duì)應(yīng)的本地消息

nim.getLocalMsgsByIdClients({
idClients: [
'd7a1b2c63066e1038e9aa01321652370',
'22e604c7811c23586355f63f24658525'
],
done: getLocalMsgsByIdClientsDone
});
function getLocalMsgsByIdClientsDone(error, obj) {
console.log(error);
console.log(obj);
console.log('獲取本地消息' + (!error?'成功':'失敗'));
if (!error) {
console.log(obj.msgs);
}
}

更新本地消息

  • 更新 idClient 對(duì)應(yīng)的本地消息
  • 如果不支持?jǐn)?shù)據(jù)庫, 算成功
  • 如果對(duì)應(yīng)的消息不存在, 算成功, 返回 null
  • 這些字段只會(huì)被更新到本地?cái)?shù)據(jù)庫, 不會(huì)被更新到服務(wù)器上
nim.updateLocalMsg({
id: 'p2p-account',
localCustom: '{"key","value"}',
done: updateLocalMsgDone
});
function updateLocalMsgDone(error, obj) {
console.log(error);
console.log(obj);
console.log('更新本地消息' + (!error?'成功':'失敗'));
}

刪除本地消息

nim.deleteLocalMsg({
msg: msg,
done: deleteLocalMsgDone
});
function deleteLocalMsgDone(error, obj) {
console.log('刪除本地消息' + (!error?'成功':'失敗'), error, obj);
}

刪除某個(gè)會(huì)話的本地消息

nim.deleteLocalMsgsBySession({
scene: 'p2p',
to: 'account',
done: deleteLocalMsgsBySessionDone
});
function deleteLocalMsgsBySession(error, obj) {
console.log(error);
console.log(obj);
console.log('刪除會(huì)話本地消息' + (!error?'成功':'失敗'));
}

刪除所有本地消息

  • 如果不支持?jǐn)?shù)據(jù)庫, 算成功
  • 此方法同時(shí)會(huì)清空所有的會(huì)話, 請(qǐng)開發(fā)者自己清空內(nèi)存里面的會(huì)話列表
nim.deleteAllLocalMsgs({
done: deleteAllLocalMsgsDone
});
function deleteAllLocalMsgsDone(error, obj) {
console.log(error);
console.log(obj);
console.log('刪除所有本地消息' + (!error?'成功':'失敗'));
}

云端歷史記錄

獲取云端歷史記錄

  • 獲取某個(gè)會(huì)話的歷史記錄, 會(huì)在結(jié)果回調(diào)函數(shù)done里面接收到消息數(shù)組
  • 參數(shù)解釋
  • scene: 請(qǐng)參考消息場(chǎng)景
  • to: 帳號(hào)或者群id
  • beginTime: 時(shí)間戳, 開始時(shí)間, 精確到ms, 默認(rèn)為0
  • endTime: 時(shí)間戳, 結(jié)束時(shí)間, 精確到ms, 默認(rèn)為服務(wù)器的當(dāng)前時(shí)間
  • lastMsgId: 上次查詢的最后一條消息的idServer, 第一次不填
  • limit: 本次查詢的消息數(shù)量限制, 最多100條, 默認(rèn)100條
  • reverse: 默認(rèn)false表示從endTime開始往前查找歷史消息; true表示從beginTime開始往后查找歷史消息
  • asc: 默認(rèn)false表示返回的消息按時(shí)間逆序排序; true表示按時(shí)間正序排序
  • 該接口用于獲取一段時(shí)間內(nèi)的歷史消息, 由參數(shù)beginTimeendTime來控制時(shí)間范圍豫领。
  • 當(dāng)reversefalse時(shí), 后續(xù)查詢的endTime對(duì)應(yīng)上次查詢的最后一條消息的time字段
  • 當(dāng)reversetrue時(shí), 后續(xù)查詢的beginTime對(duì)應(yīng)上次查詢的最后一條消息的time字段
nim.getHistoryMsgs({
scene: 'p2p',
to: 'a2',
done: getHistoryMsgsDone
});
function getHistoryMsgsDone(error, obj) {
console.log('獲取p2p歷史消息' + (!error?'成功':'失敗'));
console.log(error);
console.log(obj);
if (!error) {
console.log(obj.msgs);
}
}

系統(tǒng)通知

系統(tǒng)通知初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onofflinesysmsgs: onOfflineSysMsgs,
onsysmsg: onSysMsg,
onupdatesysmsg: onUpdateSysMsg,
onsysmsgunread: onSysMsgUnread,
onupdatesysmsgunread: onUpdateSysMsgUnread,
onofflinecustomsysmsgs: onOfflineCustomSysMsgs,
oncustomsysmsg: onCustomSysMsg
});
function onOfflineSysMsgs(sysMsgs) {
console.log('收到離線系統(tǒng)通知', sysMsgs);
pushSysMsgs(sysMsgs);
}
function onSysMsg(sysMsg) {
console.log('收到系統(tǒng)通知', sysMsg)
pushSysMsgs(sysMsg);
}
function onUpdateSysMsg(sysMsg) {
pushSysMsgs(sysMsg);
}
function pushSysMsgs(sysMsgs) {
data.sysMsgs = nim.mergeSysMsgs(data.sysMsgs, sysMsgs);
refreshSysMsgsUI();
}
function onSysMsgUnread(obj) {
console.log('收到系統(tǒng)通知未讀數(shù)', obj);
data.sysMsgUnread = obj;
refreshSysMsgsUI();
}
function onUpdateSysMsgUnread(obj) {
console.log('系統(tǒng)通知未讀數(shù)更新了', obj);
data.sysMsgUnread = obj;
refreshSysMsgsUI();
}
function refreshSysMsgsUI() {
// 刷新界面
}
function onOfflineCustomSysMsgs(sysMsgs) {
console.log('收到離線自定義系統(tǒng)通知', sysMsgs);
}
function onCustomSysMsg(sysMsg) {
console.log('收到自定義系統(tǒng)通知', sysMsg);
}

參數(shù)解釋

  • onofflinesysmsgs, 同步離線系統(tǒng)通知的回調(diào), 會(huì)傳入系統(tǒng)通知數(shù)組
  • 支持?jǐn)?shù)據(jù)庫時(shí)并且啟用了多 tab 同時(shí)登錄, 那么如果多個(gè) tab 頁同時(shí)斷線重連之后, 只會(huì)有一個(gè) tab 頁負(fù)責(zé)存儲(chǔ)離線系統(tǒng)通知, 即只會(huì)有一個(gè) tab 頁會(huì)收到 onofflinesysmsgs回調(diào), 其它 tab 頁在同步完成之后, 需要調(diào)用獲取本地系統(tǒng)通知來從本地緩存中拉取系統(tǒng)通知
  • onsysmsg, 收到系統(tǒng)通知的回調(diào), 會(huì)傳入系統(tǒng)通知
  • 收到系統(tǒng)通知后需要調(diào)用標(biāo)記系統(tǒng)通知為已讀狀態(tài)來將系統(tǒng)通知標(biāo)記為已讀狀態(tài)
  • onupdatesysmsg, 更新系統(tǒng)通知后的回調(diào), 會(huì)傳入{@link SystemMessage|系統(tǒng)通知}
  • 以下情況會(huì)收到此回調(diào)
  • 通過好友申請(qǐng)
  • 拒絕好友申請(qǐng)
  • 接受入群邀請(qǐng)
  • 拒絕入群邀請(qǐng)
  • 通過入群申請(qǐng)
  • 拒絕入群申請(qǐng)
  • 這些操作的發(fā)起方會(huì)收到此回調(diào), 接收被更新的系統(tǒng)通知, 根據(jù)操作的類型系統(tǒng)通知會(huì)被更新為下面兩種狀態(tài)
  • 'passed': 已通過
  • 'rejected': 已拒絕
  • onsysmsgunread: 收到系統(tǒng)通知未讀數(shù)的回調(diào)
  • SDK 會(huì)管理內(nèi)建系統(tǒng)通知的未讀數(shù), 此回調(diào)接收的對(duì)象包括以下字段
  • friend: 所有跟好友相關(guān)的系統(tǒng)通知的未讀數(shù)
  • addFriend: 直接加為好友的未讀數(shù)
  • applyFriend: 申請(qǐng)加為好友的未讀數(shù)
  • passFriendApply: 通過好友申請(qǐng)的未讀數(shù)
  • rejectFriendApply: 拒絕好友申請(qǐng)的未讀數(shù)
  • deleteFriend: 刪除好友的未讀數(shù)
  • team: 所有跟群相關(guān)的系統(tǒng)通知的未讀數(shù)
  • teamInvite: 入群邀請(qǐng)的未讀數(shù)
  • rejectTeamInvite: 接受入群邀請(qǐng)的未讀數(shù)
  • applyTeam: 入群申請(qǐng)的未讀數(shù)
  • rejectTeamApply: 拒絕入群申請(qǐng)的未讀數(shù)
  • deleteMsg: 撤回消息的未讀數(shù)
  • onupdatesysmsgunread: 更新系統(tǒng)通知未讀數(shù)的回調(diào)
  • onofflinecustomsysmsgs, 同步離線自定義系統(tǒng)通知的回調(diào), 會(huì)傳入系統(tǒng)通知數(shù)組
  • oncustomsysmsg, 收到自定義系統(tǒng)通知的回調(diào), 會(huì)傳入系統(tǒng)通知

系統(tǒng)通知分為兩種

  • 內(nèi)建系統(tǒng)通知
  • 目前所有的內(nèi)建系統(tǒng)通知都是與高級(jí)群相關(guān)的通知, 某些群操作后相關(guān)的群成員會(huì)收到相應(yīng)的系統(tǒng)通知氧卧。
  • 內(nèi)建系統(tǒng)通知與群通知消息的區(qū)別是系統(tǒng)通知是發(fā)給單人的通知, 群通知消息是發(fā)給所有群成員的消息。
  • 自定義系統(tǒng)通知

系統(tǒng)通知對(duì)象

系統(tǒng)通知對(duì)象有以下字段

  • time: 時(shí)間戳
  • type: 系統(tǒng)通知類型, 自定義系統(tǒng)通知無此字段
  • from: 系統(tǒng)通知的來源, 賬號(hào)或者群ID
  • to: 系統(tǒng)通知的目標(biāo), 賬號(hào)或者群ID
  • idServer: 內(nèi)建系統(tǒng)通知的 idServer
  • read: 內(nèi)建系統(tǒng)通知是否已讀
  • category: 內(nèi)建系統(tǒng)通知種類
  • state: 內(nèi)建系統(tǒng)通知狀態(tài)
  • error: 內(nèi)建系統(tǒng)通知的狀態(tài)為 'error' 時(shí), 此字段包含錯(cuò)誤的信息
  • localCustom: 內(nèi)建系統(tǒng)通知的本地自定義擴(kuò)展字段
  • 支持?jǐn)?shù)據(jù)庫時(shí)可以調(diào)用更新本地會(huì)話來更新此字段, 此字段只會(huì)被更新到本地?cái)?shù)據(jù)庫, 不會(huì)被更新到服務(wù)器上
  • ps: 內(nèi)建系統(tǒng)通知的附言
  • attach: 內(nèi)建系統(tǒng)通知的附加信息, 參考系統(tǒng)通知類型來查看不同類型的系統(tǒng)通知對(duì)應(yīng)的附加信息
  • scene: 自定義系系統(tǒng)通知的場(chǎng)景, 參考消息場(chǎng)景
  • content: 自定義系統(tǒng)通知的內(nèi)容
  • isPushable: 是否需要推送
  • apnsText: 自定義系統(tǒng)通知的apns推送文案, 僅對(duì)接收方為iOS設(shè)備有效
  • pushPayload: 自定義系統(tǒng)通知的推送屬性
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • needPushNick: 是否需要推送昵稱
  • sendToOnlineUsersOnly: 自定義系統(tǒng)通知是否只發(fā)送給在線用戶氏堤。
  • true時(shí)只發(fā)送給在線用戶, 適合發(fā)送即時(shí)通知, 比如正在輸入沙绝。
  • false時(shí)假如目標(biāo)用戶或群不在線, 會(huì)在其上線后推送過去。
  • 該參數(shù)只對(duì)點(diǎn)對(duì)點(diǎn)自定義系統(tǒng)通知有效, 對(duì)群自定義系統(tǒng)通知無效, 群自定義系統(tǒng)通知只會(huì)發(fā)給在線的群成員, 不會(huì)存離線鼠锈。
  • cc: 自定義系統(tǒng)通知是否抄送

系統(tǒng)通知類型

系統(tǒng)通知對(duì)象有一個(gè)字段type來標(biāo)明系統(tǒng)通知的類型, 自定義系統(tǒng)通知無此字段, 具體類型如下

  • 'teamInvite' (入群邀請(qǐng))
  • 高級(jí)群的群主和管理員在邀請(qǐng)成員加入群(通過操作創(chuàng)建群拉人入群)之后, 被邀請(qǐng)的人會(huì)收到一條類型為'teamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為邀請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 此類系統(tǒng)通知的attach有一個(gè)字段team的值為被邀請(qǐng)進(jìn)入的, 被邀請(qǐng)的人可以選擇接受邀請(qǐng)或者拒絕邀請(qǐng)闪檬。
  • 如果接受邀請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'acceptTeamInvite'群通知消息, 此類群通知消息的from字段的值為接受入群邀請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段members的值為接收入群邀請(qǐng)的群成員列表。
  • 如果拒絕邀請(qǐng), 那么邀請(qǐng)你的人會(huì)收到一條類型為'rejectTeamInvite'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕入群邀請(qǐng)的用戶的帳號(hào), to字段的值為對(duì)應(yīng)的群ID购笆。
  • 'rejectTeamInvite' (拒絕入群邀請(qǐng))
  • 'teamInvite'
  • 'applyTeam' (入群申請(qǐng))
  • 用戶可以申請(qǐng)加入高級(jí)群, 目標(biāo)群的群主和管理員會(huì)收到一條類型為'applyTeam'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, 高級(jí)群的群主和管理員在收到入群申請(qǐng)后, 可以選擇通過或者拒絕入群申請(qǐng)粗悯。
  • 如果通過申請(qǐng), 那么該群的所有群成員會(huì)收到一條類型為'passTeamApply'群通知消息, 此類群通知消息的from字段的值為通過入群申請(qǐng)的人的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的群對(duì)象, attach有一個(gè)字段account的值為申請(qǐng)方的帳號(hào), attach有一個(gè)字段members的值為被通過申請(qǐng)的群成員列表。
  • 如果拒絕申請(qǐng), 那么申請(qǐng)人會(huì)收到一條類型為'rejectTeamApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為對(duì)應(yīng)的群ID, attach有一個(gè)字段team的值為對(duì)應(yīng)的同欠。
  • 'rejectTeamApply' (拒絕入群申請(qǐng))
  • 'applyTeam'
  • 'addFriend'
  • 直接加某個(gè)用戶為好友后, 對(duì)方不需要確認(rèn), 直接成為當(dāng)前登錄用戶的好友
  • 對(duì)方會(huì)收到一條類型為'addFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為接收方的賬號(hào)样傍。
  • 'applyFriend'
  • 申請(qǐng)加某個(gè)用戶為好友后, 對(duì)方會(huì)收到一條類型為'applyFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為申請(qǐng)方的帳號(hào), to字段的值為接收方的賬號(hào), 用戶在收到好友申請(qǐng)后, 可以選擇通過或者拒絕好友申請(qǐng)横缔。
  • 如果通過好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'passFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為通過方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)。
  • 如果拒絕好友申請(qǐng), 那么申請(qǐng)方會(huì)收到一條類型為'rejectFriendApply'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為拒絕方的帳號(hào), to字段的值為申請(qǐng)方的賬號(hào)衫哥。
  • 'passFriendApply'
  • 'applyFriend'
  • 'rejectFriendApply'
  • 'applyFriend'
  • 'deleteFriend'
  • 刪除好友后, 被刪除的人會(huì)收到一條類型為'deleteFriend'系統(tǒng)通知, 此類系統(tǒng)通知的from字段的值為刪除方的帳號(hào), to字段的值為被刪除方的賬號(hào)茎刚。
  • 'deleteMsg'
  • 撤回消息后, 消息接收方會(huì)收到一條類型為'deleteMsg'系統(tǒng)通知, 此類系統(tǒng)通知的 msg 為被刪除的消息的部分字段。如果是群消息, 那么群里的所有人都會(huì)收到這條系統(tǒng)通知. 如果同時(shí)在多個(gè)端登錄了同一個(gè)賬號(hào), 那么其它端也會(huì)收到這條系統(tǒng)通知.
  • 'custom'
  • 自定義系統(tǒng)通知

內(nèi)建系統(tǒng)通知種類

上文中的系統(tǒng)通知類型除了'custom'之外的其它類型都屬于內(nèi)建系統(tǒng)通知, 這些類型歸為兩大種類

  • 'team'
  • 'friend'

內(nèi)建系統(tǒng)通知狀態(tài)

  • 'init': 未處理狀態(tài)
  • 'passed': 已通過
  • 'rejected': 已拒絕
  • 'error': 錯(cuò)誤

處理系統(tǒng)通知

這里涉及到了好友的處理, 請(qǐng)跟好友關(guān)系托管合在一起看

function handleSysMsgs(sysMsgs) {
if (!Array.isArray(sysMsgs)) {sysMsgs=[sysMsgs];}
sysMsgs.forEach(function(sysMsg) {
var idServer = sysMsg.idServer;
switch (sysMsg.type) {
case 'addFriend':
onAddFriend(sysMsg.friend);
break;
case 'applyFriend':
break;
case 'passFriendApply':
onAddFriend(sysMsg.friend);
break;
case 'rejectFriendApply':
break;
case 'deleteFriend':
onDeleteFriend(sysMsg.from);
break;
case 'applyTeam':
break;
case 'rejectTeamApply':
break;
case 'teamInvite':
break;
case 'rejectTeamInvite':
break;
default:
break;
}
});
}

標(biāo)記系統(tǒng)通知為已讀狀態(tài)

  • SDK 在收到系統(tǒng)通知后會(huì)更新系統(tǒng)通知未讀數(shù), 開發(fā)者需要調(diào)用此接口來通知 SDK 將某條系統(tǒng)通知標(biāo)記為已讀狀態(tài), 標(biāo)記后會(huì)觸發(fā)onupdatesysmsgunread回調(diào)
  • sysMsgs為通過onofflinesysmsgs或者onsysmsg接收到的系統(tǒng)通知或者系統(tǒng)通知數(shù)組
nim.markSysMsgRead({
sysMsgs: someSysMsg, // or [someSysMsg]
done: markSysMsgReadDone
});
function markSysMsgReadDone(error, obj) {
console.log(error);
console.log(obj);
console.log('標(biāo)記系統(tǒng)通知為已讀狀態(tài)' + (!error?'成功':'失敗'));
}

獲取本地系統(tǒng)通知

  • 支持?jǐn)?shù)據(jù)庫的時(shí)候, SDK 會(huì)將內(nèi)建系統(tǒng)通知存儲(chǔ)于數(shù)據(jù)庫中
  • 當(dāng)開發(fā)者發(fā)現(xiàn)系統(tǒng)通知的未讀數(shù)大于系統(tǒng)通知數(shù)量時(shí), 說明有未讀系統(tǒng)通知存儲(chǔ)于數(shù)據(jù)庫里面, 需要從本地拉取這部分系統(tǒng)通知
  • 默認(rèn)獲取所有種類的系統(tǒng)通知, 可以傳入?yún)?shù)category來限制系統(tǒng)通知種類
  • 默認(rèn)獲取所有類型的系統(tǒng)通知, 可以傳入?yún)?shù)type來限制系統(tǒng)通知類型
  • 默認(rèn)獲取所有已讀和未讀的系統(tǒng)通知, 可以傳入?yún)?shù)read來限制已讀狀態(tài)
  • 如果不傳, 默認(rèn)獲取所有已讀和未讀的系統(tǒng)通知
  • 如果傳 true, 那么只獲取已讀的系統(tǒng)通知
  • 如果傳 false, 那么只獲取未讀的系統(tǒng)通知
  • lastIdServer為上次查詢的最后一條系統(tǒng)通知的idServer, 第一次不填
  • limit為本次查詢的消息數(shù)量限制, 最多 100 條, 默認(rèn) 100 條
  • 默認(rèn)從最近的系統(tǒng)通知開始往前查找本地系統(tǒng)通知, 可以傳入?yún)?shù)reverse=true來從第一條系統(tǒng)通知開始往后查找本地系統(tǒng)通知
nim.getLocalSysMsgs({
lastIdServer: 'lastIdServer',
limit: 100,
done: getLocalSysMsgsDone
});
function getLocalSysMsgsDone(error, obj) {
console.log(error);
console.log(obj);
console.log('獲取本地系統(tǒng)通知' + (!error?'成功':'失敗'));
if (!error) {
console.log(obj.sysMsgs);
}
}

更新本地系統(tǒng)通知

  • 更新 idServer 對(duì)應(yīng)的本地系統(tǒng)通知
  • 如果不支持?jǐn)?shù)據(jù)庫, 算成功
  • 如果對(duì)應(yīng)的系統(tǒng)通知不存在, 算成功, 返回 null
  • 這些字段只會(huì)被更新到本地?cái)?shù)據(jù)庫, 不會(huì)被更新到服務(wù)器上
nim.updateLocalSysMsg({
idServer: '1234',
status: 'bingo',
localCustom: '{"key","value"}',
done: updateLocalSysMsgDone
});
function updateLocalSysMsgDone(error, obj) {
console.log(error);
console.log(obj);
console.log('更新本地系統(tǒng)通知' + (!error?'成功':'失敗'));
}

刪除本地系統(tǒng)通知

  • 刪除 idServer 對(duì)應(yīng)的本地系統(tǒng)通知
  • 如果不支持?jǐn)?shù)據(jù)庫, 算成功
  • 如果對(duì)應(yīng)的系統(tǒng)通知不存在, 算成功
nim.deleteLocalSysMsg({
idServer: '1234',
done: deleteLocalSysMsgDone
});
function deleteLocalSysMsgDone(error, obj) {
console.log(error);
console.log(obj);
console.log('刪除本地系統(tǒng)通知' + (!error?'成功':'失敗'));
}

刪除所有本地系統(tǒng)通知

  • 如果不支持?jǐn)?shù)據(jù)庫, 算成功
  • 此方法同時(shí)會(huì)清空系統(tǒng)通知未讀數(shù), 開發(fā)者會(huì)收到onupdatesysmsgunread
nim.deleteAllLocalSysMsgs({
done: deleteAllLocalSysMsgsDone
});
function deleteAllLocalSysMsgsDone(error, obj) {
console.log(error);
console.log(obj);
console.log('刪除所有本地系統(tǒng)通知' + (!error?'成功':'失敗'));
}

自定義系統(tǒng)通知

  • 開發(fā)者可以向其他用戶或群發(fā)送自定義系統(tǒng)通知, 默認(rèn)只發(fā)給在線用戶, 如果需要發(fā)送給離線用戶, 那么需要設(shè)置參數(shù)sendToOnlineUsersOnly=false, 請(qǐng)參考下面的示例代碼
  • 自定義系統(tǒng)通知和自定義消息的區(qū)別如下
  • 自定義消息屬于消息, 會(huì)存儲(chǔ)在云信的消息數(shù)據(jù)庫中, 需要跟其他消息一同展現(xiàn)給用戶撤逢。
  • 自定義系統(tǒng)通知屬于系統(tǒng)通知, 用于第三方通知自己, 不會(huì)存儲(chǔ)在云信的數(shù)據(jù)庫中, SDK不會(huì)解析這些通知, SDK僅僅負(fù)責(zé)傳遞這些通知膛锭。
  • SDK 不存儲(chǔ)自定義系統(tǒng)通知, 不管理自定義系統(tǒng)通知的未讀數(shù)
  • 可選參數(shù)有
  • yidunEnable: 是否需要過易盾反垃圾
  • antiSpamContent: 在開啟yidunEnable后, 開發(fā)者自定義的反垃圾字段(json格式),格式如下:{"type": 1, "data": "custom content"} 字段說明:type:1.文本蚊荣,2.圖片初狰,3視頻,data內(nèi)容:文本內(nèi)容or圖片地址or視頻地址
var content = {
type: 'type',
value: 'value'
};
content = JSON.stringify(content);
var msgId = nim.sendCustomSysMsg({
scene: 'p2p',
to: 'account',
content: content,
sendToOnlineUsersOnly: false,
apnsText: content,
done: sendCustomSysMsgDone
});
console.log('正在發(fā)送p2p自定義系統(tǒng)通知, id=' + msgId);
function sendCustomSysMsgDone(error, msg) {
console.log('發(fā)送' + msg.scene + '自定義系統(tǒng)通知' + (!error?'成功':'失敗') + ', id=' + msg.idClient);
console.log(error);
console.log(msg);
}

聊天室

請(qǐng)查閱開發(fā)準(zhǔn)備來下載并引入 SDK 文件

聊天室功能概述

  • 目前不支持通過 SDK 接口建立/解散聊天室互例。
  • 進(jìn)入聊天室時(shí)必須建立新的連接奢入,退出聊天室或者被踢會(huì)斷開連接,在聊天室中掉線會(huì)有自動(dòng)重連媳叨,開發(fā)者需要監(jiān)聽聊天室連接狀態(tài)來做出正確的界面表現(xiàn)腥光。
  • 支持聊天人數(shù)無上限。
  • 聊天室只允許用戶手動(dòng)進(jìn)入肩杈,無法進(jìn)行邀請(qǐng)柴我。
  • 支持同時(shí)進(jìn)入多個(gè)聊天室解寝,會(huì)建立多個(gè)連接扩然。
  • 斷開聊天室連接后,服務(wù)器不會(huì)再推送該聊天室的消息給此用戶聋伦。
  • 在進(jìn)行一切操作之前夫偶,必須先進(jìn)入聊天室。即必須先初始化好聊天室并且收到onconnect回調(diào)觉增。
  • 用戶進(jìn)入聊天室之后兵拢,不會(huì)收到此聊天室的歷史消息推送。如有歷史消息需求逾礁,可以調(diào)用消息查詢接口進(jìn)行顯示。
  • 聊天室成員分固定成員和游客兩種類型

獲取聊天室服務(wù)器地址

初始化聊天室之前要先獲取聊天室服務(wù)器地址, 有兩種方式

  • 如果開發(fā)者有 NIM 的實(shí)例, 那么可以直接從 IM 連接上獲取聊天室服務(wù)器地址, 示例代碼如下
nim.getChatroomAddress({
chatroomId: 'chatroomId',
done: getChatroomAddressDone
});
function getChatroomAddressDone(error, obj) {
console.log('獲取聊天室地址' + (!error?'成功':'失敗'), error, obj);
}

初始化聊天室

  • 初始化聊天室之前朋腋,必須拿到聊天室服務(wù)器地址
  • 此接口為單例模式, 對(duì)于同一個(gè)賬號(hào), 永遠(yuǎn)返回同一份實(shí)例, 即只有第一次調(diào)用會(huì)初始化一個(gè)實(shí)例
  • 后續(xù)調(diào)用此接口會(huì)直接返回初始化過的實(shí)例, 同時(shí)也會(huì)調(diào)用接口更新聊天室配置更新傳入的配置
  • 后續(xù)調(diào)用此接口時(shí), 如果連接已斷開, 會(huì)自動(dòng)建立連接
  • 當(dāng)發(fā)生掉線時(shí)轴脐,SDK會(huì)自動(dòng)進(jìn)行重連
  • 在收到onconnect回調(diào)之后說明成功進(jìn)入聊天室, 此時(shí)可以進(jìn)行其他的聊天室操作了.

示例代碼

// 注意這里, 引入的 SDK 文件不一樣的話, 你可能需要使用 SDK.Chatroom.getInstance 來調(diào)用接口
var chatroom = Chatroom.getInstance({
appKey: 'appKey',
account: 'account',
token: 'token',
chatroomId: 'chatroomId',
chatroomAddresses: [
'address1',
'address2'
],
onconnect: onChatroomConnect,
onerror: onChatroomError,
onwillreconnect: onChatroomWillReconnect,
ondisconnect: onChatroomDisconnect,
// 消息
onmsgs: onChatroomMsgs
});
function onChatroomConnect(chatroom) {
console.log('進(jìn)入聊天室', chatroom);
}
function onChatroomWillReconnect(obj) {
// 此時(shí)說明 `SDK` 已經(jīng)斷開連接, 請(qǐng)開發(fā)者在界面上提示用戶連接已斷開, 而且正在重新建立連接
console.log('即將重連', obj);
}
function onChatroomDisconnect(error) {
// 此時(shí)說明 `SDK` 處于斷開狀態(tài), 開發(fā)者此時(shí)應(yīng)該根據(jù)錯(cuò)誤碼提示相應(yīng)的錯(cuò)誤信息, 并且跳轉(zhuǎn)到登錄頁面
console.log('連接斷開', error);
if (error) {
switch (error.code) {
// 賬號(hào)或者密碼錯(cuò)誤, 請(qǐng)?zhí)D(zhuǎn)到登錄頁面并提示錯(cuò)誤
case 302:
break;
// 被踢, 請(qǐng)?zhí)崾惧e(cuò)誤后跳轉(zhuǎn)到登錄頁面
case 'kicked':
break;
default:
break;
}
}
}
function onChatroomError(error, obj) {
console.log('發(fā)生錯(cuò)誤', error, obj);
}
function onChatroomMsgs(msgs) {
console.log('收到聊天室消息', msgs);
}

參數(shù)解釋

  • appKey: 在云信管理后臺(tái)查看應(yīng)用的 appKey
  • account: 帳號(hào), 應(yīng)用內(nèi)唯一
  • token: 帳號(hào)的 token, 用于建立連接
  • chatroomId: 聊天室 id
  • chatroomAddresses: 聊天室地址列表
  • chatroomNick: 進(jìn)入聊天室后展示的昵稱, 如果不設(shè)置并且托管了用戶資料, 那么使用用戶資料里面的昵稱
  • chatroomAvatar: 進(jìn)入聊天室后展示的頭像, 如果不設(shè)置并且托管了用戶資料, 那么使用用戶資料里面的頭像
  • chatroomCustom: 擴(kuò)展字段, 設(shè)置了之后, 通過獲取聊天室成員列表獲取的聊天室成員信息會(huì)包含此字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • chatroomEnterCustom: 擴(kuò)展字段, 如果填了, 那么其它聊天室成員收到的聊天室通知消息attach.custom的值為此字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • onconnect: 連接建立后的回調(diào), 會(huì)傳入聊天室信息
  • onwillreconnect: 即將重連的回調(diào)
  • 此時(shí)說明 SDK 已經(jīng)斷開連接, 請(qǐng)開發(fā)者在界面上提示用戶連接已斷開, 而且正在重新建立連接
  • 此回調(diào)會(huì)收到一個(gè)對(duì)象, 包含額外的信息, 有以下字段
  • duration: 距離下次重連的時(shí)間
  • retryCount: 重連嘗試的次數(shù)
  • ondisconnect: 斷開連接后的回調(diào)
  • 此時(shí)說明 SDK 處于斷開狀態(tài), 開發(fā)者此時(shí)應(yīng)該根據(jù)錯(cuò)誤碼提示相應(yīng)的錯(cuò)誤信息, 并且跳轉(zhuǎn)到登錄頁面
  • 此回調(diào)會(huì)收到一個(gè)對(duì)象, 包含錯(cuò)誤的信息, 有以下字段
  • code: 出錯(cuò)時(shí)的錯(cuò)誤碼, 可能為空
  • 302: 賬號(hào)或者密碼錯(cuò)誤
  • 'kicked': 被踢
  • 當(dāng)code'kicked'的時(shí)候, 此對(duì)象會(huì)有以下字段
  • reason: 被踢的原因
  • chatroomClosed: 聊天室關(guān)閉了
  • managerKick: 被管理員踢出
  • samePlatformKick: 不允許同一個(gè)帳號(hào)重復(fù)登錄同一個(gè)聊天室
  • message: 文字描述的被踢的原因
  • onerror: 發(fā)生錯(cuò)誤的回調(diào), 會(huì)傳入錯(cuò)誤對(duì)象
  • onmsgs: 收到消息的回調(diào), 會(huì)傳入聊天室消息對(duì)象數(shù)組

退出聊天室

  • 初始化聊天室并收到onconnect回調(diào)之后, 表明進(jìn)入了聊天室
  • 在收到onconnect回調(diào)后可以調(diào)用chatroom.disconnect();來退出聊天室
  • 退出聊天室后可以調(diào)用chatroom.connect();來重新進(jìn)入聊天室

切換聊天室

如果需要切換聊天室, 操作步驟如下

更新聊天室配置

聊天室設(shè)計(jì)為單例模式, 如果需要更新當(dāng)前聊天室的配置, 那么可以調(diào)用此接口, 參數(shù)列表和格式跟Chatroom.getInstance保持一致, 以更新 token 為例

// 斷開聊天室
chatroom.disconnect()
// 更新 token
chatroom.setOptions({
token: 'newToken'
});
// 重新連接
chatroom.connect()

聊天室信息對(duì)象

聊天室信息對(duì)象有以下字段

  • id: 聊天室 id
  • name: 聊天室名字
  • announcement: 聊天室公告
  • broadcastUrl: 直播地址
  • custom: 第三方擴(kuò)展字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • createTime: 創(chuàng)建時(shí)間
  • updateTime: 更新時(shí)間
  • creator: 創(chuàng)建者賬號(hào)
  • onlineMemberNum: 當(dāng)前在線人數(shù)
  • mute 是否禁言, 禁言狀態(tài)下普通成員不能發(fā)送消息, 創(chuàng)建者和管理員可以發(fā)送消息

獲取聊天室信息

chatroom.getChatroom({
done: getChatroomDone
});
function getChatroomDone(error, obj) {
console.log('獲取聊天室信息' + (!error?'成功':'失敗'), error, obj);
}

更新聊天室信息

可更新的字段有

  • 'name': 聊天室名字
  • 'announcement': 聊天室公告
  • 'broadcastUrl': 直播地址
  • 'custom': 第三方擴(kuò)展字段
chatroom.updateChatroom({
chatroom: {
name: 'newName',
announcement: 'newAnnouncement',
broadcastUrl: 'newBroadcastUrl',
},
needNotify: true,
custom: 'biu',
custom: 'newCustom',
done: updateChatroomDone
})
function updateChatroomDone () {
console.log('更新聊天室信息' + (!error?'成功':'失敗'), error, obj);
}

更新自己在聊天室內(nèi)的信息

可更新的字段有

  • 'nick' 聊天室內(nèi)的昵稱
  • 'avatar' 聊天室內(nèi)的頭像
  • 'custom': 第三方擴(kuò)展字段
chatroom.updateMyChatroomMemberInfo({
member: {
nick: 'newNick',
avatar: 'newAvatar',
custom: 'newCustom',
},
needNotify: true,
custom: 'biu',
done: updateMyChatroomMemberInfoDone
})
function updateMyChatroomMemberInfoDone (error, obj) {
console.log('更新自己在聊天室內(nèi)的信息' + (!error?'成功':'失敗'), error, obj);
}

聊天室消息

聊天室消息對(duì)象

聊天室消息對(duì)象有以下字段

  • chatroomId: 聊天室 ID
  • idClient: SDK生成的消息id, 在發(fā)送消息之后會(huì)返回給開發(fā)者, 開發(fā)者可以在發(fā)送消息的結(jié)果回調(diào)里面根據(jù)這個(gè)ID來判斷相應(yīng)消息的發(fā)送狀態(tài), 到底是發(fā)送成功了還是發(fā)送失敗了, 然后根據(jù)此狀態(tài)來更新頁面的UI幼苛。如果發(fā)送失敗, 那么可以重新發(fā)送此消息
  • from: 消息發(fā)送方, 帳號(hào)
  • fromNick: 消息發(fā)送方的昵稱
  • fromAvatar: 消息發(fā)送方的頭像
  • fromCustom: 消息發(fā)送方的擴(kuò)展字段
  • fromClientType: 發(fā)送方的設(shè)備類型
  • type: 聊天室消息類型
  • flow: 消息的流向
  • 'in'表示此消息是收到的消息
  • 'out'表示此消息是發(fā)出的消息
  • text: 文本消息的文本內(nèi)容, 請(qǐng)參考發(fā)送聊天室文本消息
  • file: 文件消息的文件對(duì)象, 具體字段請(qǐng)參考圖片對(duì)象音頻對(duì)象焕刮、視頻對(duì)象舶沿、文件對(duì)象, 請(qǐng)參考發(fā)送聊天室文件消息
  • geo: 地理位置消息的地理位置對(duì)象, 請(qǐng)參考發(fā)送聊天室地理位置消息
  • tip: 提醒消息的內(nèi)容, 請(qǐng)參考發(fā)送聊天室提醒消息
  • content: 自定義消息的消息內(nèi)容, 開發(fā)者可以自行擴(kuò)展, 建議封裝成JSON格式字符串, 請(qǐng)參考發(fā)送聊天室自定義消息
  • attach: 聊天室通知消息的附加信息, 參考聊天室通知消息的類型來查看詳細(xì)解釋
  • custom: 擴(kuò)展字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • resend: 是否是重發(fā)的消息
  • time: 時(shí)間戳

聊天室消息類型

  • 'text' (文本)
  • 'image' (圖片)
  • 'audio' (音頻)
  • 'video' (視頻)
  • 'file' (文件)
  • 'geo' (地理位置)
  • 'custom' (自定義消息)
  • 'tip' (提醒消息)
  • 提醒消息用于會(huì)話內(nèi)的狀態(tài)提醒墙杯,如進(jìn)入會(huì)話時(shí)出現(xiàn)的歡迎消息,或者會(huì)話命中敏感詞后的提示消息等等.
  • 'notification' (聊天室通知消息)
  • 某些聊天室操作后所有聊天室成員會(huì)收到一條相應(yīng)的聊天室通知消息, 詳細(xì)介紹請(qǐng)參考聊天室通知消息的類型

聊天室通知消息的類型

  • 聊天室通知消息是聊天室消息的一種, 請(qǐng)參考聊天室消息類型, 某些聊天室操作后所有聊天室成員會(huì)收到一條相應(yīng)的聊天室通知消息
  • 聊天室通知消息有一個(gè)字段attach包含了額外的信息, attach有一個(gè)字段type來標(biāo)識(shí)聊天室通知消息的類型
  • memberEnter
  • 當(dāng)有人進(jìn)入聊天室時(shí), 所有聊天室成員會(huì)收到類型為'memberEnter'聊天室通知消息括荡。
  • memberExit
  • 當(dāng)有人退出聊天室時(shí), 所有聊天室成員會(huì)收到類型為'memberExit'聊天室通知消息高镐。
  • addManager
  • 當(dāng)有人被加為管理員時(shí), 所有聊天室成員會(huì)收到類型為'addManager'聊天室通知消息
  • removeManager
  • 當(dāng)有人被移除管理員時(shí), 所有聊天室成員會(huì)收到類型為'removeManager'聊天室通知消息一汽。
  • addCommon
  • 當(dāng)有人被加為普通成員時(shí), 所有聊天室成員會(huì)收到類型為'addCommon'聊天室通知消息避消。
  • removeCommon
  • 當(dāng)有人被移除普通成員時(shí), 所有聊天室成員會(huì)收到類型為'removeCommon'聊天室通知消息
  • blackMember
  • 當(dāng)有人被加入黑名單時(shí), 所有聊天室成員會(huì)收到類型為'blackMember'聊天室通知消息召夹。
  • unblackMember
  • 當(dāng)有人被移除黑名單時(shí), 所有聊天室成員會(huì)收到類型為'blackMember'聊天室通知消息岩喷。
  • gagMember
  • 當(dāng)有人被加入禁言名單時(shí), 所有聊天室成員會(huì)收到類型為'gagMember'聊天室通知消息
  • ungagMember
  • 當(dāng)有人被移除禁言名單時(shí), 所有聊天室成員會(huì)收到類型為'ungagMember'聊天室通知消息监憎。
  • kickMember
  • 當(dāng)有人被踢出聊天室時(shí), 所有聊天室成員會(huì)收到類型為'kickMember'聊天室通知消息纱意。
  • updateChatroom
  • 當(dāng)更新聊天室信息時(shí), 所有聊天室成員會(huì)收到類型為'updateChatroom'聊天室通知消息
  • updateMemberInfo
  • 當(dāng)更新自己在聊天室內(nèi)的信息時(shí), 所有聊天室成員會(huì)收到類型為'updateMemberInfo'聊天室通知消息鲸阔。
  • addTempMute
  • removeTempMute
  • 當(dāng)有人被設(shè)置聊天室臨時(shí)禁言時(shí)偷霉,所有聊天室成員會(huì)收到類型為'addTempMute' or 'removeTempMute'聊天室通知消息
  • muteRoom 聊天室被禁言了,只有管理員可以發(fā)言,其他人都處于禁言狀態(tài)
  • unmuteRoom 聊天室解除全體禁言狀態(tài)
  • attach的字段from為操作方的賬號(hào), fromNick為操作方的昵稱, to為被操作方的賬號(hào), toNick為被操作方的昵稱
  • 如果是addTempMute, attach的字段duration代表本次禁言的時(shí)長(zhǎng)
  • 如果是removeTempMute, attach的字段duration代表解禁提前的時(shí)長(zhǎng)

發(fā)送聊天室消息

包括以下接口

發(fā)送聊天室文本消息

var msg = chatroom.sendText({
text: 'hello',
done: sendChatroomMsgDone
});
console.log('正在發(fā)送聊天室text消息, id=' + msg.idClient);
function sendChatroomMsgDone(error, msg) {
console.log('發(fā)送聊天室' + msg.type + '消息' + (!error?'成功':'失敗') + ', id=' + msg.idClient, error, msg);
}

預(yù)覽聊天室文件

  • 開發(fā)者可以預(yù)覽文件, 支持以下幾種場(chǎng)景
  • 通過參數(shù)fileInput傳入文件選擇 dom 節(jié)點(diǎn)或者節(jié)點(diǎn) ID
  • 通過參數(shù)blob傳入 Blob 對(duì)象
  • 通過參數(shù)dataURL傳入包含 MIME type 和 base64 數(shù)據(jù)的 data URL, 此用法需要瀏覽器支持 window.Blob
  • SDK會(huì)將文件上傳到文件服務(wù)器, 然后將拿到的文件對(duì)象在done回調(diào)中傳給開發(fā)者, 文件對(duì)象有以下幾種
  • 圖片對(duì)象
  • 音頻對(duì)象
  • 視頻對(duì)象
  • 文件對(duì)象
  • 開發(fā)者在拿到文件對(duì)象之后, 可以調(diào)用發(fā)送聊天室文件消息來發(fā)送文件消息褐筛。
  • 文件大小限制為最大100M
  • 高級(jí)瀏覽器會(huì)在上傳前就檢測(cè)文件大小
  • IE8/IE9 會(huì)在上傳完成后檢測(cè)文件大小
chatroom.previewFile({
type: 'image',
fileInput: fileInput,
uploadprogress: function(obj) {
console.log('文件總大小: ' + obj.total + 'bytes');
console.log('已經(jīng)上傳的大小: ' + obj.loaded + 'bytes');
console.log('上傳進(jìn)度: ' + obj.percentage);
console.log('上傳進(jìn)度文本: ' + obj.percentageText);
},
done: function(error, file) {
console.log('上傳image' + (!error?'成功':'失敗'));
// show file to the user
if (!error) {
var msg = chatroom.sendFile({
scene: 'p2p',
to: 'account',
file: file,
done: sendChatroomMsgDone
});
console.log('正在發(fā)送聊天室image消息, id=' + msg.idClient);
}
}
});

發(fā)送聊天室文件消息

  • 文件消息是聊天室消息的一種
  • 開發(fā)者可以直接發(fā)送文件消息
  • 支持以下幾種場(chǎng)景
  • 通過參數(shù)fileInput傳入文件選擇 dom 節(jié)點(diǎn)或者節(jié)點(diǎn) ID
  • 通過參數(shù)blob傳入 Blob 對(duì)象
  • 通過參數(shù)dataURL傳入包含 MIME type 和 base64 數(shù)據(jù)的 data URL, 此用法需要瀏覽器支持 window.Blob
  • SDK會(huì)先將文件上傳到文件服務(wù)器, 然后把拿到的文件對(duì)象在uploaddone回調(diào)中傳給用戶, 然后將其拼裝成文件消息發(fā)送出去类少。
  • 開發(fā)者也可以先預(yù)覽聊天室文件來獲取文件對(duì)象, 然后調(diào)用此接口發(fā)送文件消息。
  • 直接發(fā)送文件消息的話會(huì)在beforesend回調(diào)里面?zhèn)魅隨DK生成的idClient, 如果先預(yù)覽文件再發(fā)送, 那么此接口會(huì)直接返回idClient
  • 參數(shù)type指定了要發(fā)送的文件類型, 包括圖片渔扎、音頻硫狞、視頻和普通文件, 對(duì)應(yīng)的值分別為'image''audio'晃痴、'video''file', 不傳默認(rèn)為'file'残吩。
  • 圖片、音頻倘核、視頻和普通文件的區(qū)別在于具體的文件信息不一樣, 具體字段請(qǐng)參考
  • 圖片對(duì)象
  • 音頻對(duì)象
  • 視頻對(duì)象
  • 文件對(duì)象
  • 文件大小限制為最大100M
  • 高級(jí)瀏覽器會(huì)在上傳前就檢測(cè)文件大小
  • IE8和IE9會(huì)在上傳完成后檢測(cè)文件大小
chatroom.sendFile({
type: 'image',
fileInput: fileInput,
uploadprogress: function(obj) {
console.log('文件總大小: ' + obj.total + 'bytes');
console.log('已經(jīng)上傳的大小: ' + obj.loaded + 'bytes');
console.log('上傳進(jìn)度: ' + obj.percentage);
console.log('上傳進(jìn)度文本: ' + obj.percentageText);
},
uploaddone: function(error, file) {
console.log('上傳' + (!error?'成功':'失敗'), error, file);
},
beforesend: function(msg) {
console.log('正在發(fā)送聊天室image消息, id=' + msg.idClient);
},
done: sendChatroomMsgDone
});

發(fā)送聊天室地理位置消息

var msg = chatroom.sendGeo({
scene: 'p2p',
to: 'account',
geo: {
lng: '116.3833',
lat: '39.9167',
title: 'Beijing'
},
done: sendChatroomMsgDone
});
console.log('正在發(fā)送聊天室geo消息, id=' + msg.idClient);

發(fā)送聊天室提醒消息

  • 提醒消息是聊天室消息的一種
  • 提醒消息用于會(huì)話內(nèi)的狀態(tài)提醒泣侮,如進(jìn)入會(huì)話時(shí)出現(xiàn)的歡迎消息,或者會(huì)話命中敏感詞后的提示消息等等.
var msg = chatroom.sendTipMsg({
scene: 'p2p',
to: 'account',
tip: 'tip content',
done: sendChatroomMsgDone
});
console.log('正在發(fā)送聊天室提醒消息, id=' + msg.idClient);

發(fā)送聊天室自定義消息

var value = Math.ceil(Math.random()*3);
var content = {
type: 1,
data: {
value: value
}
};
var msg = chatroom.sendCustomMsg({
content: JSON.stringify(content),
done: sendChatroomMsgDone
});
console.log('正在發(fā)送聊天室自定義消息, id=' + msg.idClient);

發(fā)送聊天室消息的配置選項(xiàng)

  • 上面的各個(gè)發(fā)送消息的接口都可以配置額外的選項(xiàng), 來滿足開發(fā)者對(duì)服務(wù)器的自定義需求紧唱。
  • custom: 擴(kuò)展字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • yidunEnable: 是否需要過易盾反垃圾
  • antiSpamContent: 在開啟yidunEnable后, 開發(fā)者自定義的反垃圾字段(json格式)活尊,格式如下:{"type": 1, "data": "custom content"} 字段說明:type:1.文本,2.圖片漏益,3視頻蛹锰,data內(nèi)容:文本內(nèi)容or圖片地址or視頻地址
  • 下面給一個(gè)發(fā)送文本消息的例子, 發(fā)送其它消息的接口類似
var msg = chatroom.sendText({
text: 'hello',
custom: '{}',
done: sendChatroomMsgDone
});
console.log('正在發(fā)送聊天室text消息, id=' + msg.idClient);

獲取聊天室歷史消息

  • 獲取從 timetag 對(duì)應(yīng)的時(shí)間點(diǎn)往前的若干條數(shù)據(jù)
  • 不填 timetag 的話默認(rèn)為服務(wù)器當(dāng)前時(shí)間
  • limit 不填的話默認(rèn) 100 條
  • reverse: 默認(rèn)false表示從timetag開始往前查找歷史消息; true表示從timetag開始往后查找歷史消息
chatroom.getHistoryMsgs({
timetag: 1451393192478,
limit: 100,
done: getHistoryMsgsDone
});
function getHistoryMsgsDone(error, obj) {
console.log('獲取聊天室歷史' + (!error?'成功':'失敗'), error, obj.msgs);
}

聊天室成員

聊天室成員對(duì)象

聊天室成員對(duì)象有以下字段

  • chatroomId: 聊天室 ID
  • account: 賬號(hào)
  • nick: 聊天室內(nèi)的昵稱
  • avatar: 聊天室內(nèi)的頭像
  • type: 聊天室成員類型
  • guest 是否是游客
  • blacked 是否被拉黑
  • gaged 是否被禁言
  • level: 級(jí)別
  • online: 是否在線, 只有固定成員才能離線, 對(duì)游客而言只能是在線
  • enterTime: 進(jìn)入聊天室的時(shí)間, 如果離線, 無該字段
  • custom: 擴(kuò)展字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • updateTime: 更新時(shí)間
  • tempMuted: 是否被臨時(shí)禁言
  • tempMuteDuration: 臨時(shí)禁言剩余時(shí)長(zhǎng)

聊天室成員類型

聊天室成員分為固定成員和游客兩種。固定成員又分為房主遭庶、管理員宁仔、普通成員和受限成員四種。禁言用戶和拉黑用戶都屬于受限用戶峦睡。

  • 'owner' (房主)
  • 'manager' (管理員)
  • 'restricted' (受限制, 被拉黑或者禁言)
  • 'common' (普通成員)
  • 'guest' (游客)

獲取聊天室成員列表

  • guest: true表示獲取游客, false表示獲取非游客成員
  • 游客列表按照游客進(jìn)入聊天室的時(shí)間倒序排列
  • 非游客(即固定成員)列表按照成為固定成員的時(shí)間倒序排列
  • 當(dāng)設(shè)置guest=false來獲取非游客成員時(shí), 默認(rèn)會(huì)獲取所有的固定成員, 包括不在線的, 可以設(shè)置onlyOnline=true來只獲取在線的固定成員
  • time 分頁用, 查找該時(shí)間戳之前的成員
  • 默認(rèn) 0 代表當(dāng)前服務(wù)器時(shí)間
  • 獲取游客時(shí), 此字段填上次獲取的最后一個(gè)游客的enterTime
  • 獲取非游客時(shí), 此字段填上次獲取的最后一個(gè)非游客的updateTime
  • limit 分頁用, 默認(rèn) 100
chatroom.getChatroomMembers({
guest: false,
limit: 100,
done: getChatroomMembersDone
});
function getChatroomMembersDone(error, obj) {
console.log('獲取聊天室成員' + (!error?'成功':'失敗'), error, obj.members);
}

獲取聊天室成員信息

  • accounts: 待查詢的賬號(hào)列表, 每次最多20個(gè)
chatroom.getChatroomMembersInfo({
accounts: ['account1', 'account2'],
done: getChatroomMembersInfoDone
});
function getChatroomMembersInfoDone(erorr, obj) {
console.log('獲取聊天室成員信息' + (!error?'成功':'失敗'), error, obj);
}

管理聊天室成員

包括以下接口

設(shè)置聊天室管理員

chatroom.markChatroomManager({
account: 'account',
isAdd: true,
done: markChatroomManagerDone
});
function markChatroomManagerDone(error, obj) {
console.log('添加聊天室管理員' + (!error?'成功':'失敗'), error, obj.member);
}

設(shè)置聊天室普通成員

  • account: 待設(shè)置的賬號(hào)
  • isAdd: 是否加為普通成員
  • 當(dāng)有人被加為普通成員時(shí), 所有聊天室成員會(huì)收到類型為'addCommon'聊天室通知消息
  • 當(dāng)有人被移除普通成員時(shí), 所有聊天室成員會(huì)收到類型為'removeCommon'聊天室通知消息煎谍。
  • level: 等級(jí)
  • custom: 擴(kuò)展字段, 如果填了, 那么其它聊天室成員收到的聊天室通知消息attach.custom的值為此字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
chatroom.markChatroomCommonMember({
account: 'account',
level: 1,
done: markChatroomCommonMemberDone
});
function markChatroomCommonMemberDone(error) {
console.log('設(shè)置聊天室普通成員' + (!error?'成功':'失敗'), error);
}

設(shè)置聊天室黑名單

  • 被加入黑名單的人將不能進(jìn)入此聊天室
  • account: 待設(shè)置的賬號(hào)
  • isAdd: true表示添加, false表示移除
  • 當(dāng)有人被加入黑名單時(shí), 所有聊天室成員會(huì)收到類型為'blackMember'聊天室通知消息攘蔽。
  • 當(dāng)有人被移除黑名單時(shí), 所有聊天室成員會(huì)收到類型為'blackMember'聊天室通知消息
  • custom: 擴(kuò)展字段, 如果填了, 那么其它聊天室成員收到的聊天室通知消息attach.custom的值為此字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
chatroom.markChatroomBlacklist({
account: 'account',
isAdd: true,
done: markChatroomBlacklistDone
});
function markChatroomBlacklistDone(error, obj) {
console.log('添加聊天室黑名單' + (!error?'成功':'失敗'), error, obj.member);
}

設(shè)置聊天室禁言名單

  • 被加入禁言名單的人將不能在該聊天室發(fā)送消息
  • account: 待設(shè)置的賬號(hào)
  • isAdd: true表示添加, false表示移除
  • 當(dāng)有人被加入禁言名單時(shí), 所有聊天室成員會(huì)收到類型為'gagMember'聊天室通知消息呐粘。
  • 當(dāng)有人被移除禁言名單時(shí), 所有聊天室成員會(huì)收到類型為'ungagMember'聊天室通知消息满俗。
  • custom: 擴(kuò)展字段, 如果填了, 那么其它聊天室成員收到的聊天室通知消息attach.custom的值為此字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
chatroom.markChatroomGaglist({
account: 'account',
isAdd: true,
done: markChatroomGaglistDone
});
function markChatroomGaglistDone(error, obj) {
console.log('添加聊天室禁言名單' + (!error?'成功':'失敗'), error, obj.member);
}

設(shè)置聊天室臨時(shí)禁言

  • 當(dāng)有人被設(shè)置聊天室臨時(shí)禁言時(shí),所有聊天室成員會(huì)收到類型為'addTempMute' or 'removeTempMute'聊天室通知消息作岖。
  • account: 帳號(hào)
  • duration: 禁言時(shí)長(zhǎng)唆垃,單位秒,傳0表示解除禁言
  • needNotify: 是否需要下發(fā)對(duì)應(yīng)的通知消息
  • custom: 對(duì)應(yīng)的通知消息的擴(kuò)展字段
chatroom.updateChatroomMemberTempMute({
account: 'account',
duration: 60,
needNotify: true,
custom: 'biu',
done: updateChatroomMemberTempMuteDone
})
function updateChatroomMemberTempMuteDone(error, obj) {
console.log('設(shè)置聊天室臨時(shí)禁言' + (!error?'成功':'失敗'), error, obj);
}

踢聊天室成員

  • account: 待踢的賬號(hào)
  • custom: 擴(kuò)展字段, 如果填了, 那么其它聊天室成員收到的聊天室通知消息attach.custom的值為此字段, 被踢的人收到的ondisconnect回調(diào)接收的參數(shù)的custom的值為此字段
  • 推薦使用JSON格式構(gòu)建, 非JSON格式的話, Web端會(huì)正常接收, 但是會(huì)被其它端丟棄
  • 當(dāng)有人被踢出聊天室時(shí), 所有聊天室成員會(huì)收到類型為'kickMember'聊天室通知消息痘儡。
chatroom.kickChatroomMember({
account: 'account',
done: kickChatroomMemberDone
});
function kickChatroomMember(error, obj) {
console.log('踢人' + (!error?'成功':'失敗'), error, obj);
}

事件發(fā)布及訂閱

用戶可以通過事件發(fā)布及訂閱辕万,來實(shí)現(xiàn)"發(fā)布-訂閱"的設(shè)計(jì)模式編程方法〕辽荆可應(yīng)用于多端登錄狀態(tài)同步渐尿、用戶個(gè)性化信息訂閱、邏輯異步流處理等場(chǎng)景矾瑰。

發(fā)布訂閱事件

  • 向各個(gè)客戶端發(fā)布獨(dú)立事件

示例代碼

nim.publishEvent({
type: 100000,
value: 2,
custom: 'hello world',
vaildTime: 60,
sync: false,
done: publishEventDone
});
function publishEventDone(error, obj) {
console.log('發(fā)布事件' + (!error?'成功':'失敗'), error, obj);
}

參數(shù)解釋

  • type, 事件類型砖茸,用戶自定義可發(fā)布事件類型值為100000以上,通過上層邏輯定義其含義
  • value, 事件值殴穴,與對(duì)應(yīng)事件類型一一對(duì)應(yīng)凉夯,用上層訂閱其含義,必須是自然數(shù)
  • custom, 用戶自定義事件的擴(kuò)展屬性推正,可選參數(shù)恍涂,最大256字節(jié)
  • vaildTime, 用戶發(fā)布事件的有效時(shí)間宝惰,可選參數(shù)植榕,以秒為單位,范圍在60s~7天(604800s)尼夺,默認(rèn)7天
  • broadcastType, 事件廣播類型尊残,可選參數(shù),1:僅在線 2:在線和離線淤堵,默認(rèn)2(在線和離線)
  • sync, 是否同步給自己寝衫,可選參數(shù),true/false拐邪,默認(rèn)false
  • done, 用戶自定義的結(jié)果回調(diào)函數(shù)慰毅,第一個(gè)參數(shù)為error,如果成功則error為null

訂閱事件

  • 向特定用戶訂閱特定事件

示例代碼

nim.subscribeEvent({
type: 100000,
accounts: ['cs3', 'cs4'],
subscribeTime: 70,
sync: true,
done: subscribeEventDone
});
function subscribeEventDone(error, obj) {
console.log('訂閱事件' + (!error?'成功':'失敗'), error, obj);
}

參數(shù)解釋

  • type, 事件類型扎阶,用戶自定義可發(fā)布事件類型值為100000以上汹胃,通過上層邏輯定義其含義;1為服務(wù)器特殊事件婶芭,即多端登錄狀態(tài),可訂閱不可發(fā)布着饥。
  • subscribeTime, 訂閱關(guān)系的有效時(shí)間犀农,單位秒 60s~30天(2592000),默認(rèn)30天
  • sync 訂閱后是否立即同步最新事件宰掉,true:同步呵哨,false:不同步,默認(rèn)同步
  • vaildTime, 用戶發(fā)布事件的有效時(shí)間轨奄,可選參數(shù)孟害,以秒為單位,范圍在60s~7天(604800s)挪拟,默認(rèn)7天
  • broadcastType, 事件廣播類型纹坐,可選參數(shù),1:僅在線 2:在線和離線舞丛,默認(rèn)2(在線和離線)
  • sync, 是否同步給自己耘子,可選參數(shù),true/false球切,默認(rèn)false
  • done, 用戶自定義的結(jié)果回調(diào)函數(shù)
  • 此回調(diào)包含兩個(gè)參數(shù)谷誓,第一個(gè)參數(shù)為error,如果成功則error為null吨凑;第二個(gè)參數(shù)為obj, 它有一個(gè)字段failedAccounts的值為操作的類型, 具體類型如下:
  • failedAccounts, 失敗的賬號(hào)數(shù)組捍歪,如果為空數(shù)組則表示操作全部成功

按賬號(hào)取消訂閱事件

  • 向特定用戶取消訂閱特定事件

示例代碼

nim.unSubscribeEventsByAccounts({
type: 100000,
accounts: ['cs3'],
done: unSubscribeEventDone
});
function unSubscribeEventDone(error, obj) {
console.log('取消訂閱事件' + (!error?'成功':'失敗'), error, obj);
}

參數(shù)解釋

  • type, 事件類型,用戶自定義可發(fā)布事件類型值為100000以上鸵钝,通過上層邏輯定義其含義;1為服務(wù)器特殊事件糙臼,即多端登錄狀態(tài),可訂閱不可發(fā)布恩商。
  • accounts, 取消訂閱好友的賬號(hào)列表变逃。當(dāng)accounts元素?cái)?shù)量大于100時(shí)籽慢,SDK會(huì)以每100個(gè)帳號(hào)做為一組事務(wù)進(jìn)行處理柠并,按組并行執(zhí)行操作(每組操作為一個(gè)事務(wù)),任意一組失敗都會(huì)拋出異常弦讽,但之前成功的組不會(huì)因后續(xù)失敗的組而異乘诳螅回滾凰棉;若用戶有較強(qiáng)烈的事務(wù)處理要求,可多次調(diào)用此接口陌粹,且每次accounts元素?cái)?shù)量小于100撒犀,進(jìn)行上層實(shí)現(xiàn)
  • done, 用戶自定義的結(jié)果回調(diào)函數(shù)
  • 此回調(diào)包含兩個(gè)參數(shù),第一個(gè)參數(shù)為error,如果成功則error為null或舞;第二個(gè)參數(shù)為obj, 它有一個(gè)字段failedAccounts的值為操作的類型, 具體類型如下:
  • failedAccounts, 失敗的賬號(hào)數(shù)組隧膏,如果為空數(shù)組則表示操作全部成功

取消指定事件的全部訂閱關(guān)系

  • 取消指定事件的全部訂閱關(guān)系

示例代碼

nim.unSubscribeEventsByType({
type: 100000,
done: unSubscribeEventDone
});
function unSubscribeEventDone(error, obj) {
console.log('取消訂閱事件' + (!error?'成功':'失敗'), error, obj);
}

參數(shù)解釋

  • type, 事件類型,用戶自定義可發(fā)布事件類型值為100000以上嚷那,通過上層邏輯定義其含義;1為服務(wù)器特殊事件胞枕,即多端登錄狀態(tài),可訂閱不可發(fā)布魏宽。
  • done, 用戶自定義的結(jié)果回調(diào)函數(shù)
  • 此回調(diào)包含兩個(gè)參數(shù)腐泻,第一個(gè)參數(shù)為error,如果成功則error為null队询;第二個(gè)參數(shù)為obj, 它有一個(gè)字段failedAccounts的值為操作的類型, 具體類型如下:
  • failedAccounts, 失敗的賬號(hào)數(shù)組派桩,如果為空數(shù)組則表示操作全部成功

按賬號(hào)獲取指定事件的訂閱關(guān)系

  • 按賬號(hào)獲取指定事件的訂閱關(guān)系

示例代碼

nim.querySubscribeEventsByAccounts({
type: 100000,
accounts: ['cs3'],
done: querySubscribeEventDone
});
function querySubscribeEventDone(error, obj) {
console.log('獲取訂閱列表' + (!error?'成功':'失敗'), error, obj);
}

參數(shù)解釋

  • type, 事件類型,用戶自定義可發(fā)布事件類型值為100000以上蚌斩,通過上層邏輯定義其含義;1為服務(wù)器特殊事件铆惑,即多端登錄狀態(tài),可訂閱不可發(fā)布送膳。
  • accounts, 查詢訂閱好友的賬號(hào)列表员魏。當(dāng)accounts元素?cái)?shù)量大于100時(shí),SDK會(huì)以每100個(gè)帳號(hào)做為一組事務(wù)進(jìn)行處理叠聋,按組并行執(zhí)行操作(每組操作為一個(gè)事務(wù))撕阎,任意一組失敗都會(huì)拋出異常,但之前成功的組不會(huì)因后續(xù)失敗的組而異陈挡梗回滾虏束;若用戶有較強(qiáng)烈的事務(wù)處理要求,可多次調(diào)用此接口厦章,且每次accounts元素?cái)?shù)量小于100镇匀,進(jìn)行上層實(shí)現(xiàn)
  • done, 用戶自定義的結(jié)果回調(diào)函數(shù)
  • 此回調(diào)會(huì)收到兩個(gè)參數(shù),第一個(gè)參數(shù)為error袜啃,如果成功則error為null汗侵;第二個(gè)參數(shù)為obj, 它有一個(gè)字段msgEventSubscribes的值為操作的類型, 具體類型如下:
  • msgEventSubscribes, 事件訂閱對(duì)象數(shù)組,數(shù)組對(duì)象中包含以下一些字段
  • msgEventSubscribes[i].time 訂閱時(shí)間
  • msgEventSubscribes[i].to 訂閱者
  • msgEventSubscribes[i].type 訂閱事件類型

服務(wù)器推送的訂閱事件(初始化)

  • 這里的參數(shù)并不是所有的初始化參數(shù), 請(qǐng)查閱初始化 SDK, 以及其它章節(jié)的初始化參數(shù)

示例代碼

var nim = NIM.getInstance({
onpushevents: onPushEvents
});
function onPushEvents(param) {
console.log('訂閱事件', param.msgEvents);
}

參數(shù)解釋

  • onpushevents, 服務(wù)器推送事件的回調(diào)函數(shù)囊骤,以下情況會(huì)收到此回調(diào):
  • 訂閱了對(duì)應(yīng)賬號(hào)對(duì)應(yīng)類型的事件晃择,且訂閱關(guān)系在有效期內(nèi)冀值,對(duì)方發(fā)布了相應(yīng)時(shí)間
  • 此回調(diào)會(huì)收到一個(gè)參數(shù)param, 它有一個(gè)字段msgEvents的值為操作的類型, 具體類型如下:
  • msgEvents, 推送事件對(duì)象數(shù)組也物,數(shù)組對(duì)象中包含以下一些字段
  • msgEvents[i].account,發(fā)布對(duì)應(yīng)事件的賬號(hào)
  • msgEvents[i].type列疗,事件類型
  • msgEvents[i].value滑蚯,事件值
  • msgEvents[i].clientType,客戶端類型
  • msgEvents[i].custom,用戶發(fā)布事件的自定義消息
  • msgEvents[i].idClient告材,消息本地客戶端id
  • msgEvents[i].idServer坤次,消息服務(wù)器id
  • msgEvents[i].serverConfig,服務(wù)器下推的配置消息(客戶端不可發(fā)布)

多端在線狀態(tài)同步

多端在線狀態(tài)同步基于事件的發(fā)布與訂閱模型斥赋,參見事件發(fā)布及訂閱

實(shí)現(xiàn)方式

  • 首先定義對(duì)應(yīng)賬號(hào)的登錄事件缰猴,登錄事件的type為1,示例代碼如下:
this.nim.subscribeEvent({
// type 1 為登錄事件疤剑,用于同步多端登錄狀態(tài)
type: 1,
accounts: ['cs1', 'cs2'],
subscribeTime: 3600 * 24 * 30,
// 同步訂閱事件滑绒,保證每次登錄時(shí)會(huì)收到推送消息
sync: true,
done: function onSubscribeEvent (err, res) {
if (err) {
console.error('訂閱好友事件失敗', err)
} else {
console.info('訂閱好友事件', res)
}
}
});
function onPushEvents (param) {
if (param.msgEvents) {
param.msgEvents.forEach(data => {
console.log(updateMultiPortStatus(data))
})
}
}
function updateMultiPortStatus (data) {
if (data.account) {
var account = data.account
var multiPortStatus = ''

function getMultiPortStatus (customType, custom) {
// 服務(wù)器下推多端事件標(biāo)記的特定序號(hào)對(duì)應(yīng)值
var netState = {
0: '',
1: 'Wifi',
2: 'WWAN',
3: '2G',
4: '3G',
5: '4G'
}
var onlineState = {
0: '在線',
1: '忙碌',
2: '離開'
}

var custom = custom || {}
if (customType !== 0) {
// 有serverConfig.online屬性,已被賦值端名稱
custom = custom[customType]
} else if (custom[4]) {
custom = custom[4]
multiPortStatus = '電腦'
} else if (custom[2]) {
custom = custom[2]
multiPortStatus = 'iOS'
} else if (custom[1]) {
custom = custom[1]
multiPortStatus = 'Android'
} else if (custom[16]) {
custom = custom[16]
multiPortStatus = 'Web'
} else if (custom[64]) {
custom = custom[64]
multiPortStatus = 'Mac'
}
if (custom) {
custom = JSON.parse(custom)
if (typeof custom['net_state'] === 'number') {
var tempNetState = netState[custom['net_state']]
if (tempNetState) {
multiPortStatus += ('[' + tempNetState + ']')
}
}
if (typeof custom['online_state'] === 'number') {
multiPortStatus += onlineState[custom['online_state']]
} else {
multiPortStatus += '在線'
}
}
return multiPortStatus
}

// demo自定義多端登錄同步事件
if (+data.type === 1) {
if (+data.value === 1 || +data.value === 2 || +data.value === 3 || +data.value === 10001) {
var serverConfig = JSON.parse(data.serverConfig)
var customType = 0
multiPortStatus = ''
// 優(yōu)先判斷serverConfig字段
if (serverConfig.online) {
if (serverConfig.online.indexOf(4) >= 0) {
multiPortStatus = '電腦'
customType = 4
} else if (serverConfig.online.indexOf(2) >= 0) {
multiPortStatus = 'iOS'
customType = 2
} else if (serverConfig.online.indexOf(1) >= 0) {
multiPortStatus = 'Android'
customType = 1
} else if (serverConfig.online.indexOf(16) >= 0) {
multiPortStatus = 'Web'
customType = 16
} else if (serverConfig.online.indexOf(64) >= 0) {
multiPortStatus = 'Mac'
customType = 64
}
}
if (data.custom && (Object.keys(data.custom).length > 0)) {
var portStatus = getMultiPortStatus(customType, data.custom)
// 如果serverConfig里有屬性而custom里沒有對(duì)應(yīng)屬性值
if ((multiPortStatus !== '') && (portStatus === '')) {
multiPortStatus += '在線'
} else {
multiPortStatus += portStatus
}
} else if (customType !== 0) {
multiPortStatus += '在線'
} else {
multiPortStatus = '離線'
}
}
}
return multiPortStatus
}
return '離線'
}

圖片操作

使用預(yù)覽文件發(fā)送文件消息拿到圖片 url 之后弯菊,可以調(diào)用 SDK 提供的圖片操作來處理圖片, 所有的操作在 NIM 和 Chatroom 上都提供, 下文僅以 NIM 為例給出使用方法, 圖片操作分為兩大類

預(yù)覽圖片通用方法

var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var newImageUrl = nim.viewImageSync({
url: url, // 必填
strip: true, // 去除圖片元信息 true or false 可選填
quality: 80, // 圖片質(zhì)量 0 - 100 可選填
interlace: true, // 漸變清晰钦铁, 可選填
rotate: 90, // 旋轉(zhuǎn)角度,順時(shí)針才漆,可選填
thumbnail: { // 生成縮略圖育瓜, 可選填
width: 80,
height: 20,
mode: cover
}
});

預(yù)覽去除圖片元信息

var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var stripMetaUrl = nim.viewImageStripMeta({
url: url,
strip: true
});

預(yù)覽圖片質(zhì)量

  • 只支持通過預(yù)覽文件發(fā)送文件消息拿到的圖片 url, 或者經(jīng)過其他圖片操作后拿到的圖片 url
  • 默認(rèn)圖片質(zhì)量為100,開發(fā)者可以降低圖片質(zhì)量來省流量
var url = 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var qualityUrl = nim.viewImageQuality({
url: url,
quality: 20
});
// 預(yù)覽圖片質(zhì)量后的圖片 url 如下
// qualityUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&quality=20'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的預(yù)覽圖片質(zhì)量的結(jié)果

預(yù)覽interlace圖片

  • 只支持通過預(yù)覽文件發(fā)送文件消息拿到的圖片 url, 或者經(jīng)過其他圖片操作后拿到的圖片 url
  • 在網(wǎng)絡(luò)環(huán)境較差時(shí), interlace 后的圖片會(huì)以從模糊到清晰的方式呈現(xiàn)給用戶
var url = 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var interlaceUrl = nim.viewImageInterlace({
url: url
});
// interlace 后的圖片 url 如下
// interlaceUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&interlace=1'

預(yù)覽旋轉(zhuǎn)圖片

var url = 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var rotateUrl = nim.viewImageRotate({
url: url,
angle: 90
});
// 旋轉(zhuǎn)后的圖片的 url 如下
// rotateUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&rotate=90'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的旋轉(zhuǎn)結(jié)果

預(yù)覽高斯模糊圖片

var url = 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var blurUrl = nim.viewImageBlur({
url: url,
radius: 5,
sigma: 3
});
// 高斯模糊后的圖片 url 如下
// blurUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&blur=5x3'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的高斯模糊后的結(jié)果

預(yù)覽裁剪圖片

var url = 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var cropUrl = nim.viewImageCrop({
url: url,
x: 100,
y: 0,
width: 250,
height: 250
});
// 裁剪后的圖片的 url 如下
// cropUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&crop=100_0_250_250'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的裁剪結(jié)果

預(yù)覽生成縮略圖

var url = 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var thumbnailUrl = nim.viewImageThumbnail({
url: url,
mode: 'cover',
width: 80,
height: 100
});
// 縮略后的圖片的 url 如下
// thumbnailUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&thumbnail=80z100'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的裁剪結(jié)果
*
thumbnailUrl = nim.viewImageThumbnail({
url: url,
mode: 'contain',
width: 80,
height: 100
});
// 縮略后的圖片的 url 如下
// thumbnailUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&thumbnail=80x100'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的裁剪結(jié)果
*
thumbnailUrl = nim.viewImageThumbnail({
url: url,
mode: 'contain',
width: 80,
height: 100
});
// 縮略后的圖片的 url 如下
// thumbnailUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&thumbnail=80y100'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的裁剪結(jié)果

thumbnailUrl = nim.viewImageThumbnail({
url: url,
mode: 'contain',
width: 80,
height: 100,
axis: {
// x 可取的值請(qǐng)參考上文描述
x: 0
}
});
// 縮略后的圖片的 url 如下
// thumbnailUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&thumbnail=80y100&axis=0_5'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的裁剪結(jié)果

thumbnailUrl = nim.viewImageThumbnail({
url: url,
mode: 'contain',
width: 80,
height: 100,
axis: {
// y 可取的值請(qǐng)參考上文描述
y: 0
}
});
// 縮略后的圖片的 url 如下
// thumbnailUrl === 'https://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=?imageView&thumbnail=80y100&axis=5_0'
// 開發(fā)者在瀏覽器中打開上面的鏈接之后, 可以直接修改 url 里面的數(shù)字來觀察不同的裁剪結(jié)果

去除圖片元信息

var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
nim.stripImageMeta({
url: url,
strip: true,
done: stripImageMetaDone
});
function stripImageMetaDone(error, obj) {
console.log('去除圖片元信息' + (!error?'成功':'失敗'), error, obj);
}

修改圖片質(zhì)量

  • 只支持通過預(yù)覽文件發(fā)送文件消息拿到的圖片 url, 或者經(jīng)過其他圖片操作后拿到的圖片 url
  • 默認(rèn)圖片質(zhì)量為100腺办,開發(fā)者可以降低圖片質(zhì)量來省流量
var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var qualityUrl = nim.qualityImage({
url: url,
quality: 5,
done: qualityImageDone
});
function qualityImageDone(error, obj) {
console.log(error);
console.log(obj);
console.log('修改圖片質(zhì)量' + (!error?'成功':'失敗'));
}

interlace圖片

  • 只支持通過預(yù)覽文件發(fā)送文件消息拿到的圖片 url, 或者經(jīng)過其他圖片操作后拿到的圖片 url
  • 在網(wǎng)絡(luò)環(huán)境較差時(shí), interlace 后的圖片會(huì)以從模糊到清晰的方式呈現(xiàn)給用戶
var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var interlaceUrl = nim.interlaceImage({
url: url,
done: interlaceImageDone
});
function interlaceImageDone(error, obj) {
console.log(error);
console.log(obj);
console.log('interlace 圖片' + (!error?'成功':'失敗'));
}

旋轉(zhuǎn)圖片

var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var rotateUrl = nim.rotateImage({
url: url,
angle: 90,
done: rotateImageDone
});
function rotateImageDone(error, obj) {
console.log(error);
console.log(obj);
console.log('旋轉(zhuǎn)圖片' + (!error?'成功':'失敗'));
}

高斯模糊圖片

var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var blurUrl = nim.blurImage({
url: url,
radius: 5,
sigma: 3,
done: blurImageDone
});
function blurImageDone(error, obj) {
console.log(error);
console.log(obj);
console.log('高斯模糊圖片' + (!error?'成功':'失敗'));
}

裁剪圖片

  • 只支持通過預(yù)覽文件發(fā)送文件消息拿到的圖片 url, 或者經(jīng)過其他圖片操作后拿到的圖片 url
  • 從坐標(biāo) (x, y) 處截取尺寸為 width*height 的圖片焰手,(0, 0) 代表左上角
  • width/height 不能小于0, 如果 width/height 大于圖片的原始寬度/高度, 那么將被替換為圖片的原始寬度/高度
var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var cropUrl = nim.cropImage({
url: url,
x: 100,
y: 0,
width: 250,
height: 250,
done: function cropImageDone
});
function cropImageDone(error, obj) {
console.log(error);
console.log(obj);
console.log('裁剪圖片' + (!error?'成功':'失敗'));
}

生成縮略圖

  • 只支持通過預(yù)覽文件發(fā)送文件消息拿到的圖片 url, 或者經(jīng)過其他圖片操作后拿到的圖片 url
  • width/height 限制了縮略圖的尺寸
  • width/height 必須大于等于 0, 不能同時(shí)為 0, 必須小于 4096
  • 不同模式下生成的縮略圖是不一樣的, 目前支持以下三種模式
  • 'cover': 原圖片等比縮略, 縮略圖一邊等于請(qǐng)求的尺寸, 另一邊大于請(qǐng)求的尺寸, 即縮略圖剛好能覆蓋住尺寸為 width*height 的矩形
  • 'contain': 原圖片等比縮略, 縮略圖一邊等于請(qǐng)求的尺寸, 另一邊大于請(qǐng)求的尺寸, 即尺寸為 width*height 的矩形剛好能覆蓋住縮略圖
  • 'crop': 先等比縮略原圖片, 使得一邊等于請(qǐng)求的尺寸, 另一邊大于請(qǐng)求的尺寸, 然后對(duì)大于請(qǐng)求尺寸的那條邊進(jìn)行裁剪, 使得最終的圖片大小剛好等于請(qǐng)求的尺寸
  • 如果縮略圖尺寸大于圖片尺寸,默認(rèn)情況下圖片不會(huì)被放大怀喉,可以傳入?yún)?shù)enlarge=true來放大圖片
  • 'crop' 模式下可以傳入?yún)?shù) axis.x 或 axis.y 來控制最后一步裁剪的位置
  • x/y 必須為整數(shù), 取值范圍為 0-10, 此方法內(nèi)部使用 Math.round 來格式化 x/y
  • x 為 0 時(shí)表示裁取最左端, x 為 10 時(shí)表示裁取最右端
  • y 為 0 時(shí)表示裁取最上端, y 為 10 時(shí)表示裁取最下端
  • x/y 默認(rèn)值均為 5, 即裁取正中間
var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var thumbnailUrl = nim.thumbnailImage({
url: url,
mode: 'cover',
width: 80,
height: 100,
done: thumbnailImageDone
});
function thumbnailImageDone(error, obj) {
console.log(error);
console.log(obj);
console.log('生成縮略圖' + (!error?'成功':'失敗'));
}

處理圖片

此方法接收一組圖片操作, 按操作順序依次處理圖片, 可選的操作包括:

每個(gè)操作所需的參數(shù)請(qǐng)參考上面的各個(gè)方法, 除了上面方法列出來的參數(shù)之外, 每個(gè)操作需要提供操作類型, 分別是

  • 'quality'
  • 'interlace'
  • 'rotate'
  • 'blur'
  • 'crop'
  • 'thumbnail'
// 裁剪后旋轉(zhuǎn)
var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
nim.processImage({
url: url,
ops: [
{
type: 'crop',
x: 100,
y: 0,
width: 250,
height: 250,
},
{
type: 'thumbnail',
mode: 'cover',
width: 80,
height: 80
}
],
done: processImageDone
});
function processImageDone(error, obj) {
console.log(error);
console.log(obj);
console.log('處理圖片' + (!error?'成功':'失敗'));
}

工具方法

修改圖片下載的名字

  • 此方法會(huì)返回一個(gè)新的地址
var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ0MzE0NTgyNDI0M184YjFkYTMwMS02NjcxLTRiYjktYTUwZC04ZTVlZjZlNzZjMzA=';
var nameUrl = nim.packFileDownloadName({
url: url,
name: '測(cè)試.jpg'
});
console.log(nameUrl);

將音頻url轉(zhuǎn)為mp3

  • 此方法會(huì)返回一個(gè)新的地址
var url = 'http://b12026.nos.netease.com/MTAxMTAxMA==/bmltYV8xMTQwMzFfMTQ1MTg4ODk5MjMxMV9mNmI1Y2QyZC03N2UzLTQxNmUtYWY5NC1iODlhZGY4ZTYzYWQ=';
var mp3Url = nim.audioToMp3({
url: url
});
console.log(mp3Url);

語音轉(zhuǎn)文字

var url = 'http://nim.nos.netease.com/MTAxMTAwMg==/bmltYV8xNDc5OTNfMTQ1MTg5MDI2MjY0MF9lYzk1MWMyZC1hMzRmLTQ1YzctYWI2ZS1kZWE2NTA2M2Q4NjY=';
nim.audioToText({
url: url,
done: audioToTextDone
});
function audioToTextDone(error, obj) {
console.log('語音轉(zhuǎn)文字' + (!error?'成功':'失敗'), error, obj);
}

Blob

  • 將包含 MIME type 和 base64 數(shù)據(jù)的 data URL 轉(zhuǎn)換為 Blob 對(duì)象
var dataURL = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAyADIDASIAAhEBAxEB/8QAGgABAAMBAQEAAAAAAAAAAAAAAAIEBgUDAf/EACwQAAEEAQMCBQMFAQAAAAAAAAEAAgMRBAUSISIxBhNBUWEUMnEjkaGxstH/xAAaAQACAwEBAAAAAAAAAAAAAAAAAQIDBAUG/8QAIREAAgIBAwUBAAAAAAAAAAAAAAECERIEFCExM0FxodH/2gAMAwEAAhEDEQA/ANkiKtm5gxI203fK87Y2XVnv+w7lXNpK2ebLKhHMyUuDHbtpokdr9lksjPzM187pMowYEBIfKw7TIR3ArsL4vuquJNlYenYub9TPE2U1I272lx4cGngjtYPp8rPuoWLI3SLlaTqr8pz8XLa2PNiHW1vZw9CPhdVXxkpK0MIiKQBZzXcgxZGVJz+hh20D3cTf+QtE40LDS4+gaLJXE13FfFqNSxyRvkg8qTpI2HktPNe7gVRqe2x4tqzh5OP5PhAxMaDULXHn1sElWtQo+HJdvb6cEbvwP5VbLex3hzJxnSmSXHjDJKFciq49vlT1SYjw8xrTuknYyNu1v3E1dD8WuZza9kPwSymAaRnMNzF7GFx4LmubyCtoOyxpx/q9UwtMi3mPGAllcfgU3n3WyW/SJ4EkERFrA+EWORahkxszJnS5QEz3MEZMguwBX9eq9FFzA4EEWCk0n1HbqjN5GmQyajKxkhDiwxuO8dba+1xruOVX1DCZp2JFPNlDysZrY4uN5DjxurgE178LRnToDN5vXd9r4UpNPxZQBLE14BsB3ItZ9tF3Y4OKmnNWvPNfTx0zAxsKHdj9Zl63yu5dIT6n/ivqLWNY3a0ABSWhJJUiIRETAIiIAIiIAIiIAIiIA//Z';

var blob = NIM.blob.fromDataURL(dataURL);

// blob instanceof Blob === true;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末书妻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子躬拢,更是在濱河造成了極大的恐慌躲履,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聊闯,死亡現(xiàn)場(chǎng)離奇詭異工猜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)菱蔬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門篷帅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來史侣,“玉大人,你說我怎么就攤上這事魏身【鳎” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵箭昵,是天一觀的道長(zhǎng)税朴。 經(jīng)常有香客問我,道長(zhǎng)家制,這世上最難降的妖魔是什么掉房? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮慰丛,結(jié)果婚禮上卓囚,老公的妹妹穿的比我還像新娘。我一直安慰自己诅病,他們只是感情好哪亿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贤笆,像睡著了一般蝇棉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芥永,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天篡殷,我揣著相機(jī)與錄音,去河邊找鬼埋涧。 笑死板辽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棘催。 我是一名探鬼主播劲弦,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼醇坝!你這毒婦竟也來了邑跪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤呼猪,失蹤者是張志新(化名)和其女友劉穎画畅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宋距,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡轴踱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乡革。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寇僧。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稚照,死狀恐怖昌渤,靈堂內(nèi)的尸體忽然破棺而出桥状,到底是詐尸還是另有隱情热康,我是刑警寧澤宣赔,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布掀泳,位于F島的核電站懒熙,受9級(jí)特大地震影響罪针,放射性物質(zhì)發(fā)生泄漏蕾殴。R本人自食惡果不足惜笑撞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钓觉。 院中可真熱鬧茴肥,春花似錦、人聲如沸荡灾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽批幌。三九已至础锐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荧缘,已是汗流浹背皆警。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留截粗,地道東北人信姓。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像绸罗,于是被迫代替她去往敵國和親财破。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 2017.02.22 可以練習(xí)从诲,每當(dāng)這個(gè)時(shí)候左痢,腦袋就犯困,我這腦袋真是神奇呀系洛,一說讓你做事情俊性,你就犯困,你可不要太...
    Carden閱讀 1,328評(píng)論 0 1
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 10,868評(píng)論 6 13
  • 從三月份找實(shí)習(xí)到現(xiàn)在描扯,面了一些公司定页,掛了不少,但最終還是拿到小米绽诚、百度典徊、阿里杭煎、京東、新浪卒落、CVTE羡铲、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,184評(píng)論 11 349
  • 今天準(zhǔn)備繼續(xù)畫風(fēng)景,可惜手邊沒有合適的石頭儡毕,只好矮子里頭拔將軍也切,找個(gè)差不多的對(duì)付一下。 這么說來周末必須要去一趟大...
    柴門石繪閱讀 913評(píng)論 7 10
  • 作者介紹:書北,兒童戶外教育師费坊,自由詩人倒槐。 詩說:詩歌不是文字,它更像一段又一段美艷又凄涼的無聲影片附井,是花的綻放與...
    簡(jiǎn)書丨書北閱讀 444評(píng)論 0 1