diff --git a/docs/.vuepress/components/PlatformSwitch.vue b/docs/.vuepress/components/PlatformSwitch.vue index e23a553a5..aab20a1b5 100644 --- a/docs/.vuepress/components/PlatformSwitch.vue +++ b/docs/.vuepress/components/PlatformSwitch.vue @@ -54,39 +54,9 @@ const PLATFORM_ICON_MAP = { }, } -const platform = ref('android') -let version = '' -const platformIcon = computed(() => PLATFORM_ICON_MAP[platform.value]?.activeIcon) -const route = useRoute() -const router = useRouter() -watch(()=>route.path, ()=> { - if (route.path.indexOf('/document') == 0) { - version = route.path.split('/')[2] - platform.value = route.path.split('/')[3] - } -}, {immediate:true}) - +const V1_PLATFORM = ['android', 'ios', 'web', 'applet', 'electron', 'server-side'] -// 切换平台,如果有相同路径的route就直接跳转 -const onChange = (platform) => { - if (platform === 'privatization') { - router.push(`/document/${version}/privatization/uc_deploy.html`) - return - } - const nextPlatformDocRouters = router.options.routes.filter(item=>item.hasOwnProperty('name') && item?.path.indexOf(`/document/${version}/${platform}`) == 0).map(item=>item.path) - - let newPath = route.path.split('/') - newPath[3] = platform - const nextPathPath = newPath.join('/') - - if (nextPlatformDocRouters.indexOf(nextPathPath) > -1) { - router.push(nextPathPath) - } else { - router.push(`/document/${version}/${platform}/overview.html`) - } -} - -const options = [ +const OPTIONS = [ { label: '安装部署', options: [ @@ -147,6 +117,57 @@ const options = [ ], }, ] + +const platform = ref('android') +const platformOptions = ref(OPTIONS) +let version = '' +const platformIcon = computed(() => PLATFORM_ICON_MAP[platform.value]?.activeIcon) +const route = useRoute() +const router = useRouter() + + + +const handleVersionOptions = (version:string) =>{ + if (version === 'v2') { + platformOptions.value = OPTIONS + } + if (version === 'v1') { + let v1Options = JSON.parse(JSON.stringify(OPTIONS)) + v1Options[1].options = v1Options[1].options.filter((item) => + V1_PLATFORM.includes(item.value) + ) + platformOptions.value = v1Options + + } +} + +watch(()=>route.path, ()=> { + if (route.path.indexOf('/document') == 0) { + version = route.path.split('/')[2] + handleVersionOptions(version) + platform.value = route.path.split('/')[3] + } +}, {immediate:true}) + +// 切换平台,如果有相同路径的route就直接跳转 +const onChange = (platform) => { + if (platform === 'privatization') { + router.push(`/document/${version}/privatization/uc_deploy.html`) + return + } + const nextPlatformDocRouters = router.options.routes.filter(item=>item.hasOwnProperty('name') && item?.path.indexOf(`/document/${version}/${platform}`) == 0).map(item=>item.path) + + let newPath = route.path.split('/') + newPath[3] = platform + const nextPathPath = newPath.join('/') + + if (nextPlatformDocRouters.indexOf(nextPathPath) > -1) { + router.push(nextPathPath) + } else { + router.push(`/document/${version}/${platform}/overview.html`) + } +} + @@ -156,7 +177,7 @@ const options = [ diff --git a/docs/document/v1/electron/appendix.md b/docs/document/v1/electron/appendix.md new file mode 100644 index 000000000..08097e268 --- /dev/null +++ b/docs/document/v1/electron/appendix.md @@ -0,0 +1,53 @@ +# 附录 + +文档中用到的结构体定义 + +``` +Result +{ + code, //{Number} 0表示成功,其它值为失败 + description //{String} code为非0值时,表示失败原因 +} +ContactListResult +{ + code:result.errorCode, //{Number} 0表示成功,其它值为失败 + description:result.description, //{String} code为非0值时有效,表示失败原因 + data //{StringArray} 用户ID数组,code为0时有效,["ID1","ID2"] +} +GroupResult +{ + code:result.errorCode, //{Number} 0表示成功,其它值为失败 + description:result.description, //{String} code为非0值时有效,表示失败原因 + data //{StringArray} EMGroup对象,code为0时有效 +} +GroupListResult +{ + code:result.errorCode, //{Number} 0表示成功,其它值为失败 + description:result.description, //{String} code为非0值时有效,表示失败原因 + data //{Array} EMGroup对象数组,code为0时有效 +} +SharedFileResult +{ + code:result.errorCode, //{Number} 0表示成功,其它值为失败 + description:result.description, //{String} code为非0值时有效,表示失败原因 + data //{Object} EMMucSharedFile,code为0时有效 +} +SharedFileListResult +{ + code:result.errorCode, //{Number} 0表示成功,其它值为失败 + description:result.description, //{String} code为非0值时有效,表示失败原因 + data //{Array} EMMucSharedFile对象数组,code为0时有效 +} +AnnouncementResult +{ + code:result.errorCode, //{Number} 0表示成功,其它值为失败 + description:result.description, //{String} code为非0值时有效,表示失败原因 + data //{String} 群组公告内容,code为0时有效 +} +MessageListResult +{ + code:result.errorCode, //{Number} 0表示成功,其它值为失败 + description:result.description, //{String} code为非0值时有效,表示失败原因 + data //{Array} EMMessage对象数组,code为0时有效 +} +``` \ No newline at end of file diff --git a/docs/document/v1/electron/chatmanage.md b/docs/document/v1/electron/chatmanage.md new file mode 100644 index 000000000..cc5152285 --- /dev/null +++ b/docs/document/v1/electron/chatmanage.md @@ -0,0 +1,458 @@ +# 会话管理 + +环信桌面端 SDK 支持会话管理的集成,集成后可以进行如下操作: + +- 会话处理 + +- 获取消息 + +- 消息处理 + +通过这些操作,可以组合帮助您完成多种场景下的 IM 需求。 + +会话管理模块为 EMChatManager,由 EMClient 模块加载时主动创建,可以使用 EMClient 模块的 getChatManager 方法获取,代码如下: + +``` +var chatManager = emclient.getChatManager(); +``` + +------ + +## 会话处理 + +会话处理包含以下处理操作: + +- 获取会话列表 + +- 根据 ID 获取会话 + +- 删除会话 + +- 获取会话属性 + +- 会话属性扩展 + +所有处理操作的示例下面会一一说明。 + +------ + +### 获取会话列表 + +接口 API 如下: + +``` +/** + * 获取会话列表 + * return 返回会话列表,EMConversation 数组 + */ +getConversations() +``` + +调用方法如下: + +``` +var convlist = chatManager.getConversations(); +``` + +------ + +### 根据 ID 获取会话 + +根据会话 ID 获取会话,接口 API 如下: + +``` +/** + * 获取会话 + * param conversationId 会话 ID,输入参数,String + * param type 会话类型,输入参数,0为单聊,1为群聊 + * return 会话,EMConversation + */ +conversationWithType(conversationId,type) +``` + +调用方法如下: + +``` +let conversationlist = chatManager.conversationWithType(conversationId,type); +``` + +------ + +### 删除会话 + +接口 API 如下: + +``` +/** 根据 ID 删除会话 + * param conversationId 会话 ID,输入参数 + * param isRemoveMessages 是否删除消息,ture 为删除 + */ +removeConversation(conversationId,isRemoveMessages) +``` + +调用方法如下: + +``` +chatManager.removeConversation(conversationId,true); +``` + +------ + +### 获取会话属性 + +``` +// 获取会话 ID +console.log("conversationId" + conversation.conversationId()); +// 获取会话类型,0为单聊,1为群聊 +console.log("conversationType" + conversation.conversationType()); +``` + +------ + +### 会话扩展属性 + +接口 API 如下: + +``` +/** + * 设置会话扩展属性 + * param ext 扩展属性,String + */ +setExtField(strAttr) +/** + * 获取会话扩展属性 + * return 扩展属性,String + */ +extField() +``` + +调用方法如下: + +``` +conversation.setExtField(ext); +var strAttr = conversation.extField(); +``` + +------ + +## 获取消息 + +获取消息包含以下处理操作: + +- 获取历史消息 + +- 根据 ID 获取当前会话消息 + +- 获取会话中的消息计数 + +- 获取会话中的未读消息计数 + +- 获取最新消息 + +所有处理操作的示例下面会一一说明。 + +------ + +### 获取历史消息 + +接口 API 如下: + +``` +/** + * 分页获取历史消息,从服务器获取 + * param conversationId 会话 ID,输入参数 + * param type 会话类型,1为群组,0为单聊 + * param pageSize 每页的消息计数 + * param startMsgId 起始消息 ID + * return 返回 Promise 对象,response 参数为 MessageListResult + */ +chatManager.fetchHistoryMessages(conversationId, type, pageSize, startMsgId) +``` + +调用方法如下: + +``` +chatManager.fetchHistoryMessages(conversationId, type, pageSize, startMsgId).then((res) => {},(error) => {}); +``` + +------ + +### 根据 ID 获取当前会话消息 + +根据消息 ID 获取当前会话消息,接口 API 如下: + +``` +/** + * 根据消息 ID 获取消息 + * param msgid 消息 ID + * return 未读消息计数 + */ +loadMessage(msgid) +``` + +调用方法如下: + +``` +var msg = conversation.loadMessage(msgid); +``` + +------ + +### 获取会话中的消息计数 + +接口 API 如下: + +``` +/** + * 获取会话中的消息计数 + * return 消息计数,Number + */ +messagesCount() +``` + +调用方法如下: + +``` +var msgCount = conversation.messagesCount(); +``` + +------ + +### 获取会话中的未读消息计数 + +接口 API 如下: + +``` +/** + * 获取会话中的未读消息计数 + * return 未读消息计数,Number + */ +unreadMessagesCount() +``` + +调用方法如下: + +``` +var unreaddMsgCount = conversation.unreadMessagesCount(); +``` + +------ + +### 获取最新一条消息 + +接口 API 如下: + +``` +/** + * 获取会话中的最新一条消息 + * return EMMessage 消息对象 + */ +latestMessage() +``` + +调用方法如下: + +``` +var msg = conversation.latestMessage(); +``` + +------ + +## 消息处理 + +消息处理包含以下处理操作: + +- 插入消息 + +- 添加消息 + +- 修改消息 + +- 加载会话消息 + +- 删除会话消息 + +- 清空会话消息 + +- 下载图片、附件 + +- 设置消息已读状态 + +所有处理操作的示例下面会一一说明。 + +------ + +### 插入消息 + +接口 API 如下: + +``` +/** + * 不发送消息,只是插入到本地,按照时间插入到本地数据库 + * param messagelist 要插入的消息列表,EMMessage 数组 + * return 返回操作结果,Bool +*/ +insertMessages(messagelist); +``` + +调用方法如下: + +``` +chatManager.insertMessages(messagelist); +``` + +------ + +### 添加消息 + +接口 API 如下: + +``` +/** + * 在末尾添加一条消息 + * param message 要插入的消息,EMMessage 对象 + * return 返回操作结果,Bool +*/ +appendMessage(message); +``` + +调用方法如下: + +``` +chatManager.appendMessage(message); +``` + +------ + +### 修改消息 + +接口 API 如下: + +``` +/** + * 修改一条消息,不能改变消息 ID + * param message 要插入的消息,EMMessage 对象 + * return 返回操作结果,Bool +*/ +updateMessage(message); +``` + +调用方法如下: + +``` +chatManager.updateMessage(message); +``` + +------ + +### 加载会话消息 + +接口 API 如下: + +``` +/** + * 按照 ID 加载会话消息 + * param refMsgId 起始消息 ID,输入参数,空为最新消息,String + * param count 加载的消息数,输入参数,Number + * param direction 消息加载方向填0 + * return 返回为 EMMessage 数组 + */ +loadMoreMessagesByMsgId(refMsgId, count, direction); + +/** + * 按照时间加载会话消息 + * param timeStamp 起始消息时间,输入参数 + * param count 加载的消息数,输入参数 + * param direction 消息加载方向,填0 + * return 返回EMMessage数组 + */ +conversation.loadMoreMessagesByTime(timeStamp, count, direction); +``` + +调用方法如下: + +``` +conversation.loadMoreMessagesByMsgId("", 20,0); +conversation.loadMoreMessagesByTime(timeStamp, 20,0); +``` + +------ + +### 删除会话消息 + +接口 API 如下: + +``` +/** + * 按照 ID 移除会话消息,只操作缓存和本地数据库 + * param messageId 要删除的消息 ID + * return 返回操作结果,bool 型 + */ +removeMessage(messageId) +``` + +调用方法如下: + +``` +conversation.removeMessage(messageId).then((res)=>{},(error) => {}); +``` + +------ + +### 清空会话消息 + +接口 API 如下: + +``` +/** + * 清空会话消息,只操作缓存和本地数据库 + * return 返回操作结果,bool 型 + */ +clearAllMessages() +``` + +调用方法如下: + +``` +conversation.clearAllMessages(); +``` + +------ + +### 下载图片、附件 + +``` +// 下载附件消息,message 为 EMMessage 对象,可在 message 中设置回调 +chatManager.downloadMessageAttachments(message); +// 下载图片缩略,message 为 EMMessage 对象,可在 message 中设置回调 +chatManager.downloadMessageThumbnail(message); +``` + +------ + +### 设置消息已读状态 + +接口 API 如下: + +``` +/** + * 根据消息 ID 标记消息已读状态 + * param msgid,消息 ID + * isread bool,已读状态 + * return 返回操作结果,bool 型 + */ +markMessageAsRead(msgid,isread); +/** + * 标记会话中所有消息的已读状态 + * isread bool,已读状态 + * return 返回操作结果,bool 型 + */ +markAllMessagesAsRead(isread); +``` + +调用方法如下: + +``` +conversation.markMessageAsRead(msgid,isread); +conversation.markAllMessagesAsRead(isread); +``` \ No newline at end of file diff --git a/docs/document/v1/electron/demo.md b/docs/document/v1/electron/demo.md new file mode 100644 index 000000000..e5a62b9d7 --- /dev/null +++ b/docs/document/v1/electron/demo.md @@ -0,0 +1,6 @@ +# Demo 下载体验 + + +- [Windows Demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/DesktopDemo.3.8.4.win.setup.exe) +- [Mac Demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/DesktopDemo.3.8.4.mac.dmg) +- [Demo 源码](https://github.com/easemob/sdkdemoapp_windows/tree/electron) \ No newline at end of file diff --git a/docs/document/v1/electron/group_manage.md b/docs/document/v1/electron/group_manage.md new file mode 100644 index 000000000..475423c5d --- /dev/null +++ b/docs/document/v1/electron/group_manage.md @@ -0,0 +1,1018 @@ +# 群组管理 + +环信桌面端 SDK 支持群组功能的集成,集成后可以进行如下操作: + +- 获取群组 + +- 群组管理 + +- 群成员管理 + +- 加群处理 + +- 群消息 + +- 群文件 + +- 群组变更的监听 + +通过这些操作,可以组合帮助您完成多种场景下的 IM 需求。 + +群组管理模块为 EMGroupManager ,由 EMClient 模块加载时主动创建,可以使用 EMClient 模块的 getGroupManager 方法获取,代码如下 + +``` +var groupManager = emclient.getGroupManager(); +``` + +------ + +## 获取群组 + +获取群组包含以下处理操作: + +- 本地获取群组 + +- 服务器获取群组 + +- ID 获取群组 + +- 获取群组信息 + +- 获取公开群组 + +- 查找公开群组 + +所有处理操作的示例下面会一一说明。 + +------ + +### 本地获取群组 + +本地获取用户所在的所有群组,接口 API 如下: + +``` +/** + * 本地获取用户所有的组 + * return GroupListResult + */ +allMyGroups() +``` + +调用方法如下: + +``` +let res = groupManager.allMyGroups() +``` + +------ + +### 服务器获取群组 + +服务器获取用户所在的所有群组,接口 API 如下: + +``` +/** + * 服务器获取用户所有的组 + * return 返回 Promise 对象,response 参数为 GroupListResult + */ +fetchAllMyGroups() +``` + +调用方法如下: + +``` +groupManager.fetchAllMyGroups().then((res)=>{},(error) => {}); +``` + +------ + +### ID 获取群组 + +根据 ID 获取群组 + +``` +let group = groupManager.groupWithId(groupId); +``` + +------ + +### 获取群组信息 + +``` +// 获取组 ID +console.log("group.groupId" + group.groupId()); +// 获取组名 +console.log("group.groupSubject" + group.groupSubject()); +// 获取组描述 +console.log("group.groupDescription" + group.groupDescription()); +// 获取群主 +console.log("group.groupOwner" + group.groupOwner()); +// 获取成员计数 +console.log("group.groupMembersCount" + group.groupMembersCount()); +// 获取群设置类型 +console.log("group.groupMemberType" + group.groupMemberType()); +// 获取群成员 +console.log("members:"+group.groupMembers().join(' || ')); +// 获取群设置对象 +var set = group.groupSetting(); +console.log("set.style() = " + set.style()); +console.log("set.maxUserCount() = " + set.maxUserCount()); +console.log("set.extension() = " + set.extension()); +``` + +------ + +### 获取公开群组 + +接口 API 如下: + +``` +/** + * 分页获取公开群组 + * param pageNum 第几页,输入参数,Number,0表示不分页,获取所有公开组,1为分页起始 + * param pageSize 每页计数,输入参数,Number,最大200 + * return 返回 Promise 对象,response 参数为 GroupListResult + */ +fetchPublicGroupsWithPage(pageNum, pageSize); +``` + +调用方法如下: + +``` +groupManager.fetchPublicGroupsWithPage(1,20).then((res) => { + },(error) => {}) +``` + +------ + +### 查找公开群组 + +接口 API 如下: + +``` +/** + * 根据群 ID 查找公开群 + * param1 groupId 群组 ID,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +searchPublicGroup(groupId); +``` + +调用方法如下: + +``` +groupManager.searchPublicGroup(groupId).then((res) => { + },(error) => {}) +``` + +------ + +## 群组管理 + +群组管理包含以下处理操作: + +- 创建群组 + +- 解散群组 + +- 退出群组 + +- 转移群组 + +- 修改群信息 + +- 群组公告管理 + +所有处理操作的示例下面会一一说明。 + +------ + +### 创建群组 + +创建群组时,需要先实例化一个群组设置对象,然后创建群组。实例化群组设置接口 API 如下: + +``` +/** + * 实例化区群组设置 + * param style 组类型, Number ,0为私有群,只有群主可以邀请成员加入,1为私有群,成员也可以邀请成员加入,2为公开群,但申请入群需要群主同意,3为公开群,成员可以随意申请加入 + * param maxUserCount 最大成员数, Number ,最大200 + * param inviteNeedConfirm 邀请是否需要确认,Bool + * param extension 扩展信息,String + * return 返回组设置对象 + */ +EMMucSetting(style, maxUserCount, inviteNeedConfirm, extension) +``` + +调用方法如下: + +``` +var setting = new easemob.EMMucSetting(1, 20, false, "test"); +``` + +创建群组接口 API 如下: + +``` +/** + * 创建群组 api + * param subject 群组名称,输入参数,String + * param description 群组描述,输入参数,String + * param welcomeMessage 欢迎信息,输入参数,String + * param setting 群组设置,输入参数,Object + * param members 群组初始成员,输入参数,StringArray + * return 返回 Promise 对象,response 参数为 GroupResult + */ +createGroup(subject, description, welcomeMessage, setting, members) +``` + +调用方法如下: + +``` +groupManager.createGroup("subject","description","welcome message",setting,["jwfan1", "jwfan2"]).then((res) => {},(error) => {}) +``` + +------ + +### 解散群组 + +接口 API 如下: + +``` +/** + * 解散群组 api + * param groupId 组 ID,输入参数 + * return 返回 Promise 对象,response 参数为 Result + */ +destroyGroup(groupId); +``` + +调用方法如下: + +``` +groupManager.destroyGroup("55139673112577").then((res)=>{},(error) => {}) +``` + +------ + +### 退出群组 + +接口 API 如下: + +``` +/** + * 成员主动退出群组 + * param groupId 群组 ID,输入参数,String + * 返回 Promise 对象,response 参数为 Result + */ +leaveGroup(groupId) +``` + +调用方法如下: + +``` +groupManager.leaveGroup(groupId).then((res)=>{},(error) => {}) +``` + +------ + +### 转移群组 + +接口 API 如下: + +``` +/** + * 转移群主,只有群主能操作 + * param groupId 群组ID,输入参数,String + * param member 新群主用户名,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +transferGroupOwner(groupId, member) +``` + +调用方法如下: + +``` +groupManager.transferGroupOwner(groupId, member).then((res) =>{},(error) => {}); +``` + +------ + +### 修改群组信息 + +接口 API 如下: + +``` +/** + * 修改群标题 + * param groupId 群组 ID ,输入参数,String + * param newSubject 群组新组名,输入参数,String + * return 返回 Promise对象,response 参数为 GroupResult + */ +groupManager.changeGroupSubject(groupId, newSubject); + + +/** + * 修改群描述 + * param groupId 群组 ID,输入参数,String + * param newDescription 群组新描述,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +changeGroupDescription(groupId, newDescription) +``` + +调用方法如下: + +``` +groupManager.changeGroupSubject(groupId, "new Subject", error).then((res) =>{},(error) => {}); +groupManager.changeGroupDescription(groupId, "new Description", error).then((res) =>{},(error) => {}); +``` + +------ + +### 群组公告管理 + +接口 API 如下: + +``` +/** + * 设置群组公告 + * param groupId 群组 ID,输入参数,String + * param announcement 群组公告,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +updateGroupAnnouncement(groupId, announcement,error) + +/** + * 获取群组公告 + * param groupId 群组 ID,输入参数,String + * return 返回 Promise 对象,response 参数为 AnnouncementResult + */ +fetchGroupAnnouncement(groupId) +``` + +调用方法如下: + +``` +groupManager.fetchGroupAnnouncement(groupId).then((res) =>{},(error) => {}); groupManager.updateGroupAnnouncement(groupId, "new announcement").then((res) =>{},(error) => {}); +``` + +------ + +## 群成员管理 + +群成员管理包含以下处理操作: + +- 群成员邀请 + +- 群成员移除 + +- 添加管理员 + +- 删除管理员 + +- 获取禁言成员列表 + +- 成员禁言 + +- 取消成员禁言 + +- 加入群组黑名单 + +- 从群组黑名单移除 + +所有处理操作的示例下面会一一说明。 + +------ + +### 群成员邀请 + +接口 API 如下: + +``` +/** + * 邀请成员入群,一次可邀请多个成员 + * param groupId 群组 ID,输入参数,String + * param members 邀请的成员,输入参数,StringArray,["ID1","ID2"] + * param welcomeMessage 欢迎信息,输入参数,String + * 返回 Promise 对象,response 参数为 GroupResult + */ +addGroupMembers(groupId, members, welcomeMessage); +``` + +调用方法如下: + +``` +groupManager.addGroupMembers(groupId, ["jwfan3", "jwfan4"], "hahaha").then((res)=>{},(error) => {}) +``` + +------ + +### 群成员移除 + +接口 API 如下: + +``` +/** + * 将成员踢出群,同样可踢出多人 + * param groupId 群组ID,输入参数,String + * param members 踢出的成员,输入参数,StringArray,["ID1","ID2"] + * 返回 Promise 对象,response 参数为 Result + */ +removeGroupMembers(groupId, members, error); +``` + +调用方法如下: + +``` +groupManager.removeGroupMembers(groupId, ["jwfan3", "jwfan4"]).then((res)=>{},(error) => {}) +``` + +------ + +### 添加管理员 + +接口 API 如下: + +``` +/** + * 将普通群成员提升为管理员 + * param groupId 群组 ID,输入参数,String + * param member 成员用户名,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +addGroupAdmin(groupId, member) +``` + +调用方法如下: + +``` +groupManager.addGroupAdmin(groupId, member).then((res) =>{},(error) => {}); +``` + +------ + +### 删除管理员 + +接口 API 如下: + +``` +/** + * 将管理员降级为普通成员 + * param groupId 群组ID,输入参数,String + * param member 管理员用户名,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +removeGroupAdmin(groupId, member) +``` + +调用方法如下: + +``` +groupManager.removeGroupAdmin(groupId, member).then((res) =>{},(error) => {}); +``` + +------ + +### 获取禁言列表 + +接口API如下: + +``` +/** + * 获取禁言列表 + * param groupId 群组 ID,输入参数,String + * param pageNum 第几页,输入参数,Number,1为起始页 + * param pageSize 每页计数,输入参数,Number,最大200 + * return 返回 Promise 对象,response 参数为 GroupResult + */ +fetchGroupMutes(groupId, pageNum, pageSize) +``` + +------ + +### 群组禁言 + +接口API如下: + +``` +/** + * 将成员加入禁言列表,被禁言的成员无法在群组内发消息 + * param {String} groupId 群组ID,输入参数,String + * param {Array} members 成员列表,输入参数,String 数组 + * param {Number} muteDuration 禁言时间,单位毫秒 + * return 返回 Promise 对象,response 参数为 GroupResult + */ +muteGroupMembers(groupId,members,muteDuration) +``` + +------ + +### 取消禁言 + +接口API如下: + +``` +/** + * 将成员从禁言列表移除 + * param {String} groupId 群组ID,输入参数,String + * param {Array} members 成员列表,输入参数,String 数组 + * return 返回 Promise 对象,response 参数为 GroupResult + */ +unmuteGroupMembers(groupId,members) +``` + +------ + +### 获取群组黑名单列表 + +接口 API 如下: + +``` +/** + * 分页获取群组黑名单列表 + * param groupId 群组 ID,输入参数,String + * param pageNum 第几页,输入参数,Number,1为起始页 + * param pageSize 每页计数,输入参数,Number,最大200 + * return 返回 Promise 对象,response 参数为 GroupListResult + */ +fetchGroupBans(groupId,pageNum, pageSize) +``` + +调用方法如下: + +``` +groupManager.fetchGroupBans(groupId, 1, 20).then((res) =>{},(error) => {}); +``` + +------ + +### 加入群组黑名单 + +接口 API 如下: + +``` +/** + * 将成员加入群组黑名单,黑名单中的人员无法加入群组 + * param groupId 群组ID,输入参数,String + * param members 成员列表,输入参数,String 数组 + * param reason 加入黑名单原因,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +blockGroupMembers(groupId,members,reason) +``` + +调用方法如下: + +``` +groupManager.blockGroupMembers(groupId, members, "reason").then((res) =>{},(error) => {}); +``` + +------ + +### 从群组黑名单移除 + +接口 API 如下: + +``` +/** + * 将人员从群组黑名单移除 + * param groupId 群组 ID,输入参数,String + * param members 成员列表,输入参数,StringArray + * return 返回 Promise 对象,response 参数为 GroupResult + */ +unblockGroupMembers(groupId, members) +``` + +调用方法如下: + +``` +groupManager.unblockGroupMembers(groupId, members).then((res) =>{},(error) => {}); +``` + +------ + +## 加群处理 + +加群处理包含以下处理操作: + +- 加入公开群组 + +- 申请加入公开群组 + +- 接受群邀请 + +- 拒绝群邀请 + +- 接受入群申请 + +- 拒绝入群申请 + +所有处理操作的示例下面会一一说明。 + +------ + +### 加入公开群组 + +接口 API 如下: + +``` +/** + * 加入 PUBLIC_JOIN_OPEN 类型公开群组 + * param groupId 群组 ID,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +joinPublicGroup(groupId,error) +``` + +调用方法如下: + +``` +groupManager.joinPublicGroup(groupId,error).then((res) =>{},(error) => {}); +``` + +------ + +### 申请加入公开群组 + +接口 API 如下: + +``` +/** + * 申请加入 applyJoinPublicGroup 类型公开群组,需要群主或管理员同意 + * param groupId 群组 ID,输入参数,String + * param nickname 用户在群内的昵称,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +applyJoinPublicGroup(groupId,nickname,message) +``` + +调用方法如下: + +``` +groupManager.applyJoinPublicGroup(groupId,nickname,message).then((res) =>{},(error) => {}); +``` + +------ + +### 接受群邀请 + +接口 API 如下: + +``` +/** + * 接受群组发来的入群邀请 + * param groupId 群组ID,输入参数,String + * param inviter 邀请人,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +acceptInvitationFromGroup(groupId,inviter) +``` + +调用方法如下: + +``` +groupManager.acceptInvitationFromGroup(groupId,inviter).then((res) =>{},(error) => {}); +``` + +### 拒绝群邀请 + +接口 API 如下: + +``` +/** + * 拒绝群组发来的入群邀请 + * param groupId 群组 ID,输入参数,String + * param inviter 邀请人,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +declineInvitationFromGroup(groupId,inviter) +``` + +调用方法如下: + +``` +groupManager.declineInvitationFromGroup(groupId,inviter).then((res) =>{},(error) => {}); +``` + +------ + +### 接受加入群申请 + +接口 API 如下: + +``` +/** + * 同意成员的入群邀请,由群主操作 + * param groupId 群组ID,输入参数,String + * param from 入群申请人,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +acceptJoinGroupApplication(groupId,from) +``` + +调用方法如下: + +``` +groupManager.acceptJoinGroupApplication(groupId,from).then((res) =>{},(error) => {}); +``` + +------ + +### 拒绝加入群申请 + +接口 API 如下: + +``` +/** + * 拒绝成员的入群邀请,由群主操作 + * param groupId 群组 ID,输入参数,String + * param from 入群申请人,输入参数,String + * param reason 拒绝原因,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +declineJoinGroupApplication(groupId,from,reason) +``` + +调用方法如下: + +``` +groupManager.declineJoinGroupApplication(groupId,from,"decline reason").then((res) =>{},(error) => {}); +``` + +------ + +## 群消息 + +群消息包含以下处理操作: + +- 屏蔽群组消息 + +- 取消屏蔽群组消息 + +所有处理操作的示例下面会一一说明。 + +------ + +### 屏蔽群组消息 + +接口 API 如下: + +``` +/** + * 屏蔽群组消息 + * param groupId 群组ID,输入参数,String + * return 返回 Promise 对象,response 参数为 GroupResult + */ +blockGroupMessage(groupId) +``` + +调用方法如下: + +``` +groupManager.blockGroupMessage(groupId).then((res) =>{},(error) => {}); +``` + +------ + +### 取消屏蔽群组消息 + +接口 API 如下: + +``` +/** + * 取消屏蔽群组消息 + * param groupId 群组 ID,输入参数,String + * return 返回 Promise 对象,response 参数为GroupResult + */ +unblockGroupMessage(groupId) +``` + +调用方法如下: + +``` +groupManager.unblockGroupMessage(groupId).then((res) =>{},(error) => {}); +``` + +------ + +## 群文件 + +群文件包含以下处理操作: + +- 获取群文件列表 + +- 上传群文件 + +- 下载群文件 + +- 删除群文件 + +所有处理操作的示例下面会一一说明。 + +------ + +### 获取群文件列表 + +接口 API 如下: + +``` +/** + * 分页获取群文件列表 + * param groupId 群组ID,输入参数,String + * param pageNum 当前页数,从1开始 + * param pageSize 每页计数,最大200 + * return 返回 Promise 对象,response 参数为 SharedFileListResult + */ +fetchGroupSharedFiles(groupId, pageNum, pageSize) +``` + +调用方法如下: + +``` +groupManager.fetchGroupSharedFiles(groupId, 1, 20).then((res) => {},(error) => {}); +``` + +------ + +### 上传群文件 + +上传群文件过程中,需要使用回调监控上传进度及结果 + +``` +// 设置回调函数显示上传进度和结果 +var emUploadCallback = new easemob.EMCallback(); +console.log("create upload emCallback success"); + +// 上传成功 +emUploadCallback.onSuccess(() => { + console.log("upload emCallback call back success"); + return true; +}); +// 上传失败 +emUploadCallback.onFail((error) => { + console.log("upload emCallback call back fail"); + console.log(error.description); + console.log(error.errorCode); + return true; +}); +// 上传进度 +emUploadCallback.onProgress((progress) => { + if (progress >= 98) { + console.log("upload call back progress " + progress); + } +}); +``` + +接口 API 如下: + +``` +/** + * 上传群文件 + * param groupId 群组 ID,输入参数,String + * param filepath 文件路径,输入参数,String + * param emUploadCallback 设置回调,输入 + * 返回 Promise 对象,response 参数为 SharedFileResult + */ +uploadGroupSharedFile(groupId, filepath, emUploadCallback) +``` + +调用方法如下: + +``` +groupManager.uploadGroupSharedFile(groupId, filepath, emUploadCallback).then((res) => {},(error) => {}); +``` + +------ + +### 下载群文件 + +下载群文件过程中需要使用回调监控下载进度及结果 + +``` +var emDownloadCallback = new easemob.EMCallback(); +console.log("create download emCallback success"); + +// 下载成功 +emDownloadCallback.onSuccess(() => { + console.log("download emCallback call back success"); + return true; +}); +// 下载失败 +emDownloadCallback.onFail((error) => { + console.log("download emCallback call back fail"); + console.log(error.description); + console.log(error.errorCode); + return true; +}); +// 下载进度 +emDownloadCallback.onProgress((progress) => { + if (progress >= 98) { + console.log("download call back progress " + progress); + } +}); +``` + +接口 API 如下: + +``` +/** + * 下载群文件 + * param groupId 群组 ID,输入参数,String + * param filePath 文件本地存储路径,输入参数,String + * param fileId 文件 ID,输入参数,由文件列表数组获取 + * param callback 设置回调,输入 + * return 返回 Promise 对象,response 参数为 GroupResult + */ +downloadGroupSharedFile(groupId, filePath, fileId, callback) +``` + +调用方法如下: + +``` +let fileId = sharedFile.fileId(); +groupManager.downloadGroupSharedFile(groupid, filelocalpath, fileId, emDownloadCallback); +``` + +------ + +### 删除群文件 + +接口 API 如下: + +``` +/** + * 删除群文件 + * param groupId 群组 ID,输入参数,String + * param fileId 文件 ID,输入参数,由文件列表获取 + * return 返回 Promise 对象,response 参数为 GroupResult + */ +deleteGroupSharedFile(groupId, fileId) +``` + +调用方法如下: + +``` +let fileId = sharedFile.fileId(); +groupManager.deleteGroupSharedFile(groupId, fileId).then((res) =>{},(error) => {}); +``` + +------ + +## 群组变更的监听 + +``` +groupManager = emclient.getGroupManager(); +groupListener = new easemob.EMGroupManagerListener(groupManager); +// 添加群管理员时触发(只有是自己时才能收到通知) +// group : 发生操作的群组 +// admin : 被提升的群管理员 +groupListener.onAddAdminFromGroup((groupId, admin) => { + console.log("onAddAdminFromGroup:"+groupId+" admin:"+admin); +}); + +// 删除群管理员时触发(只有是自己时才能收到通知) +// group : 发生操作的群组 +// admin : 被删除的群管理员(群管理员变成普通群成员) +groupListener.onRemoveAdminFromGroup((groupId, admin) => { + console.log("onRemoveAdminFromGroup:"+groupId+" admin:"+admin); +}); + +// 转让群主的时候触发 +// group : 发生操作的群组 +// newOwner : 新群主 +// oldOwner : 原群主 +groupListener.onAssignOwnerFromGroup((groupId, newOwner, oldOwner) => { + console.log("onAssignOwnerFromGroup:"+groupId+" newOwner:"+newOwner + " oldOwner:" + oldOwner); +}); + +// 我接收到自动进群时被触发 +// group : 发生操作的群组 +// inviter : 邀请人 +// inviteMessage : 邀请信息 +groupListener.onAutoAcceptInvitationFromGroup((groupId, inviter, inviteMessage)=>{ + console.log("onAutoAcceptInvitationFromGroup:"+groupId+" inviter:"+inviter + " inviteMessage:" + inviteMessage); + }); + +// 成员加入群组时触发 +// group : 发生操作的群组 +// member : 加入群组的成员名称 +groupListener.onMemberJoinedGroup((groupId, member)=>{ + console.log("onMemberJoinedGroup:"+groupId+" member:"+member); +}); + +// 成员离开群组时触发 +// group : 发生操作的群组 +// member : 离开群组的成员名称 +groupListener.onMemberLeftGroup((groupId, member)=>{ + console.log("onMemberLeftGroup:"+groupId+" member:"+member); +}); + +// 离开群组时触发 +// group : 发生操作的群组 +// reason : 离开群组的原因(0: 被踢出 1:群组解散 2:被服务器下线) +groupListener.onLeaveGroup((groupId, reason)=>{ + console.log("onLeaveGroup:"+groupId+" reason:"+reason); +}); +groupManager.addListener(groupListener); +// 移除监听 +groupManager.removeListener(groupListener); +``` \ No newline at end of file diff --git a/docs/document/v1/electron/message.md b/docs/document/v1/electron/message.md new file mode 100644 index 000000000..c00b2af77 --- /dev/null +++ b/docs/document/v1/electron/message.md @@ -0,0 +1,257 @@ +# 消息管理 + +消息是桌面端集成中最重要的功能之一,消息的使用方法主要为 : + +- 发送消息 + +- 接受消息 + +同时对于发送不超过2分钟的消息,允许主动撤回。 + +通过对消息的集成,您可以最快速的集成体验 IM 收发消息的流畅体验。 + +------ + +## 发送消息 + +发送消息类型主要有以下几种: + +- 文本消息 + +- 文件消息 + +- 图片消息 + +- CMD 消息 +- 自定义 消息 + +- 位置消息 + +通过这些操作,可以组合帮助您完成多种场景下的 IM 需求。 + +发送文本、文件、图片等消息(单聊/群聊通用)。完整的消息发送过程,包括创建消息体,创建消息,设置属性,设置回调,然后发送消息,不同的消息类型只是在创建消息体过程不同,其他步骤一样。 + +------ + +### 发送文本消息 + +``` +/** + * 创建文本消息体 + * param1 文本消息正文,输入参数,String + * return 消息体 EMTextMessageBody + */ +var textMsgBody = new easemob.EMTextMessageBody("wahhahahaha"); +/** + * 创建消息 + * param1 发送者用户名,输入参数 + * param2 目的端,会话 ID,输入参数 + * param3 消息体 EMTextMessageBody + * return 消息 EMMessage + */ +var textSendMsg = easemob.createSendMessage("jwfan", "jwfan1", textMsgBody); +// 消息可以设置扩展属性,用户界面可通过自定义属性,实现自定义等功能 +textSendMsg.setAttribute("data", 120); +data = textSendMsg.getAttribute("data"); +// 设置消息类型,0为单聊,1为群聊,2为聊天室 +textSendMsg.setChatType(0); +// 设置回调 +var emCallback = new easemob.EMCallback(); +emCallback.onSuccess(() => { + console.log("emCallback call back success"); + if(me.cfr){ + console.log(sendMessage); + console.log(sendMessage.msgId()); + return true; + }); + emCallback.onFail((error) => { + console.log("emCallback call back fail"); + console.log(error.description); + console.log(error.errorCode); + return true; + }); + emCallback.onProgress((progress) => { + console.log(progress); + console.log("call back progress"); + }); +sendMessage.setCallback(emCallback); +// 发送消息 +chatManager.sendMessage(textMsg); +``` + +------ + +### 发送文件 + +``` +/** + * 创建文件消息体 + * param1 文件路径,输入参数,String + * return 消息体 EMFileMessageBody + */ +var fileMsgBody = new easemob.EMFileMessageBody("/Users/jiangwei/Code/fanjiangwei7/emclient-linux/testapp/file.txt"); +// 创建消息 +var fileMsg = easemob.createSendMessage("jwfan", "jwfan1", fileMsgBody); +//setCallback(callback) 设置消息回调函数,通过回调函数显示消息发送成功失败,以及附件上传百分比 +//callback easemob.EMCallback的实例,设置onSuccess、onFail和onProgress三个回调函数。 +fileMsg.setCallback(emCallback); +chatManager.sendMessage(fileMsg); +``` + +------ + +### 发送图片 + +``` +/** + * 创建图片消息体 + * param1 图片文件路径,输入参数,String + * param2 图片缩略图路径,输入参数 + * return 消息体EMFileMessageBody + */ +var imageMsgBody = new easemob.EMImageMessageBody('/Users/jiangwei/Code/fanjiangwei7/emclient-linux/testapp/image_960x718.jpg', '/Users/jiangwei/Code/fanjiangwei7/emclient-linux/testapp/thumb_image.jpg'); +var imageMsg = easemob.createSendMessage("jwfan", "jwfan1", imageMsgBody); +imageMsg.setCallback(emCallback); +chatManager.sendMessage(imageMsg); +``` + +------ + +### 发送 CMD 消息 + +``` +var cmdMsgBody = new easemob.EMCmdMessageBody("action"); +console.log("cmdMsgBody.type() = " + cmdMsgBody.type()); + +console.log("cmdMsgBody.action() = " + cmdMsgBody.action()); +cmdMsgBody.setAction("displayName"); +console.log("cmdMsgBody.action() = " + cmdMsgBody.action()); + +var obj1 = {"key" : "1", "value" : "1"}; +var obj2 = {"key" : "2", "value" : "2"}; +console.log("cmdMsgBody.params() = " + cmdMsgBody.params()); +cmdMsgBody.setParams([obj1, obj2]); +var cmdMsg = easemob.createSendMessage("jwfan", "jwfan1", cmdMsgBody); +chatManager.sendMessage(cmdMsg); +``` + +------ + +### 发送 自定义 消息 + +自定义消息包括消息event和消息扩展exts,构造及发送过程如下 + +``` +let customMsgBody = new easemob.EMCustomMessageBody("userCard"); +customMsgBody.setExts({'avatar':'https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/IMDemo/avatar/Image5.png','nickname':'xiaoming','uid':'uid'}); +let customMsg = easemob.createSendMessage('lxm9','lxm',customMsgBody); +chatManager.sendMessage(customMsg); +``` + +------ + +### 位置消息 + +``` +/** + * 创建位置消息体 + * param1 位置经度,输入参数,String + * param2 位置纬度,输入参数 + * param3 地址,输入参数 + * return 消息体EMFileMessageBody + */ +var locationMsgBody = new easemob.EMLocationMessageBody(123.45, 35.67, 'USA'); +console.log("locationMsgBody.type() = " + locationMsgBody.type()); +console.log("locationMsgBody.latitude() = " + locationMsgBody.latitude()); +console.log("locationMsgBody.longitude() = " + locationMsgBody.longitude()); +console.log("locationMsgBody.address() = " + locationMsgBody.address()); +locationMsgBody.setLatitude(87.87); +locationMsgBody.setLongitude(45.45); +locationMsgBody.setAddress('china'); +var locationMsg = easemob.createSendMessage("jwfan", "jwfan1", locationMsgBody); +chatManager.sendMessage(locationMsg); +``` + +------ + +## 撤回消息 + +默认发送两分钟内的消息可以撤回,撤回使用recallMessage接口 + +``` +/** + * 撤回消息 + * param msg {EMMessage} 要撤回的消息 + */ +chatManager.recallMessage(msg); +``` + +------ + +## 接收消息 + +接收消息在会话管理中通过设置回调函数实现,在回调函数中处理 + +``` +// 实例化监听回调,并添加到client +chatManager = emclient.getChatManager(); +listener = new easemob.EMChatManagerListener(); +chatManager.addListener(listener); + +// 收到会话消息 +listener.onReceiveMessages((messages) => { + console.log("onReceiveMessages messages.length = " + messages.length); + for (var index = 0, len = messages.length; index < len; index++) { + var msg = messages[index]; + var bodies = msg.bodies(); + console.log("bodies.length = " + bodies.length); + var body = bodies[0]; + var type = body.type(); + console.log("msg.from() = " + msg.from()); + console.log("msg.to() = " + msg.to()); + console.log("body.type() = " + type); + if (type == 0) { //text message + console.log("body.text() = " + body.text()); + } else if (type == 1) { //image message + console.log("body.displayName() = " + body.displayName()); + console.log("body.localPath() = " + body.localPath()); + chatManager.downloadMessageAttachments(msg); + chatManager.downloadMessageThumbnail(msg); + } else if (type == 5) { //file message + console.log("body.displayName() = " + body.displayName()); + console.log("body.localPath() = " + body.localPath()); + chatManager.downloadMessageAttachments(msg); + } +}); +// 收到命令消息 +listener.onReceiveCmdMessages ((messages) => { + for (var index = 0, len = messages.length; index < len; index++) { + var msg = messages[index]; + var bodies = msg.bodies(); + console.log("bodies.length = " + bodies.length); + var body = bodies[0]; + var type = body.type(); + console.log("msg.from() = " + msg.from()); + console.log("msg.to() = " + msg.to()); + console.log("msg.type() = " + type); + console.log("body.action() = " + body.action()); + var params = cmdMsgBody.params() + console.log("cmdMsgBody.params().length = " + params.length); + if (params.length > 0) { + console.log("cmdMsgBody.params()[0] = " + JSON.stringify(params[0])); + } +} +}); + +// 收到消息撤回 +listener.onReceiveRecallMessages ((message) => { + console.log("onReceiveRecallMessages messages.length = " + messages.length); + for (var index = 0, len = messages.length; index < len; index++) { + var message = messages[index]; + console.log("message.msgId() = " + message.msgId()); + console.log("message.from() = " + message.from()); + console.log("message.to() = " + message.to()); +} +}); +// addListener(listener) 添加消息回调监听,从监听中获取接收消息。 +``` \ No newline at end of file diff --git a/docs/document/v1/electron/multi_device.md b/docs/document/v1/electron/multi_device.md new file mode 100644 index 000000000..9012368e0 --- /dev/null +++ b/docs/document/v1/electron/multi_device.md @@ -0,0 +1,23 @@ +# 多设备管理监听 + +当同一账号同时使用桌面端,移动端登录时,需要使用多设备管理监听事件,使用回调实现 + +``` +// 实例化监听,并添加到客户端 +var listener = new easemob.EMMultiDevicesListener(); +emclient.addMultiDevicesListener(listener); + +// 设置回调 +// 收到其他设备的会话操作 +listener.onContactMultiDevicesEvent((operation, target, ext) => { + console.log('operation = ' + operation); + console.log('target = ' + target); + console.log('ext = ' + ext); +}); +// 收到其他设备的组操作 +listener.onGroupMultiDevicesEvent((operation, target, usernames) => { + console.log('operation = ' + operation); + console.log('target = ' + target); + console.log('usernames = ' + usernames); +}); +``` \ No newline at end of file diff --git a/docs/document/v1/electron/overview.md b/docs/document/v1/electron/overview.md new file mode 100644 index 000000000..800f8b9d6 --- /dev/null +++ b/docs/document/v1/electron/overview.md @@ -0,0 +1,152 @@ +# 集成概述说明 + +桌面端 SDK 为用户在 Windows/Mac OS 平台上进行开发的 js 接口及二进制文件,开发框架使用 electron 。 + +目前支持登录、注册、单聊、群聊、聊天室、文本消息、图片、语音、位置等消息以及透传消息,还可以实现好友管理、群组管理等功能。 + +**注意:**之前的 Windows SDK 将不再维护,同时对应的 demo ,文档也一并下线。如需查看旧版文档,点击[Windows SDK 集成说明](https://docs-im.easemob.com/im/windows/intro/integration) + +------ + +## 准备 + +### 开发环境需求 + +#### 操作系统 + +- win7/win8/win10 64位操作系统 + +- mac OS 10.10 及以上 + +#### 开发工具 + +- nodejs + +版本 10.0 以上,[官网地址](http://nodejs.cn/) + +- electron + +版本 4.0 以上,[官网地址](https://electronjs.org/),nodejs 安装完成后,可以在命令行使用 npm 命令安装,安装命令: + +``` +npm install electron -g +``` + +------ + +## SDK 目录结构 + +Windows SDK 目录结构如下。使用时将 SDK 拷贝到工程目录下。 + +``` +|-node + |-modules + |-message + index.js + load.js +|-easemob + easemobMac.node + easemobWin.node + libcurl.dll + libcurl.lib + libcrypto.1.0.0.dylib +``` + +------ + +## SDK 模块介绍 + +SDK 采用模块化设计,每一模块的功能相对独立和完善,用户可以根据自己的需求选择使用下面的模块: + +![img](https://docs-im.easemob.com/_media/im/windows/intro/sdk%E6%A8%A1%E5%9D%97.png) + +### 模块化设计 + +- EMClient + +SDK 的入口,主要完成登录、退出、注册、配置管理等功能,管理连接监听模块 EMConnectionListener 。也是获取其他模块的入口。 + +- EMChatManager + +管理消息的收发,完成会话管理等功能,管理会话监听模块 EMChatManagerListener 。 + +- EMContactManager + +负责好友的添加删除,黑名单的管理等功能,管理好友变更监听模块 EMContactListener。 + +- EMGroupManager + +负责群组的管理,创建、删除群组,管理群组成员等功能,管理群组监听模块 EMGroupManagerListener。 + +- EMChatroomManager + +负责聊天室的查询、加入、退出功能管理,管理聊天室监听模块 EMChatroomManagerListener。 + +------ + +## SDK 对象说明 + +SDK 中使用到的对象包括: + +- 系统配置信息 EMChatConfigs + +- 群组信息 EMGroup + +- 群组配置信息 EMMucSetting + +- 群文件信息 EMMucSharedFile + +- 聊天室信息 EMChatroom + +- 会话信息 EMConversation + +- 消息 EMMessage + +- 文本消息体 EMFileMessageBody + +- 图片消息体 EMImageMessageBody + +- 文件消息体 EMTextMessageBody + +- 命令消息体 EMCmdMessageBody + +具体接口[详见 SDK API Doc](https://downloads.easemob.com/doc/desktop/apidoc/index.html) + +### 依赖模块安装 + +electron 开发中依赖的模块及版本写在 package.json 中,安装依赖模块时,在 sdkdemoapp_windows 目录下使用命令: + +``` +npm install +``` + +如果安装过程中出现 error,可能是网络原因,可以选择使用 yarn 镜像下载安装: + +``` +npm install -g yarn +yarn install +``` + +------ + +### 软件调试 + +首先需要编译软件,运行命令: + +``` +npm run build:app +``` + +调试过程需要使用热启动,运行命令: + +``` +npm run hot-server +``` + +然后另启动一个命令行工具,运行命令: + +``` +npm run start:hot +``` + +可启动软件。调试过程中修改代码后,hot-server 会自动编译新代码,在界面上使用 F5 按键可以立即刷新界面,应用新代码。在界面上点击鼠标右键,弹出右键菜单,点击检查元素,可以打开开发者工具,查看 console 控制台输出,在 Source 中加断点调试。 \ No newline at end of file diff --git a/docs/document/v1/electron/quickstart.md b/docs/document/v1/electron/quickstart.md new file mode 100644 index 000000000..92402d244 --- /dev/null +++ b/docs/document/v1/electron/quickstart.md @@ -0,0 +1,228 @@ +# 快速开始 + +## 加载SDK + +直接加载 index.js 模块,代码如下: + +``` +var easemob = require('../../node/index'); +``` + +------ + +## 用户登录 + +登录前,需要先创建配置对象和 client 对象,用户可以使用 **用户名+密码** 和 **用户名+token** 两种方式登录。 + +### 创建配置对象 + +``` +/** + * 首先构造 sdk 配置信息 + * param1 为资源存储路径,输入参数 + * param2 为工作路径,输入参数,日志存储在这里 + * param3 为 appkey ,输入参数,easemob-demo#chatdemoui 为 DemoAppKey ,需填写自己的 Appkey + * param4 为设备 ID ,默认 0 + * return 配置模块对象 + */ +var emchatconfigs = new easemob.EMChatConfig(".", ".", "easemob-demo#chatdemoui", 0); +``` + +### 创建 client 对象 + +``` +var emclient = new easemob.EMClient(emchatconfigs); +``` + +#### 用户名+密码登录方式代码如下: + +``` +/** + * 密码登录 api ,异步操作 + * param username 为用户名,输入, String + * param password 为密码,输入, String + * return 返回 Promise 对象,response 参数为 #Result + */ +login(username, password) +``` + +调用用方法如下: + +``` +emclient.login("jwfan", "jwfan").then((res) =>{ +if(res.code == 0) + console.log("login success"); +},(error) => {}); +``` + +#### 用户名+token 登录方式代码如下: + +``` +/** + * token 登录 api ,异步操作 + * param username 用户名,输入, String + * param token 用户 token ,输入, String + * return 返回 Promise 对象,response 参数为 #Result + */ +loginWithToken(username, token) +``` + +调用方法如下: + +``` +emclient.loginWithToken("jwfan", "Mytoken").then((res) =>{ +if(res.code == 0) + console.log("login success"); +},(error) => {}); +``` + +登录接口返回值 ret 为 EMError 对象,登录成功则 ret 的 errorCode 为 0,否则可以用 description 获取错误信息 登录后获取用户信息方法如下: + +``` +// 获取用户信息,包括用户名,密码,token +var loginInfo = emclient.getLoginInfo(); +console.log("loginInfo.loginUser = " + loginInfo.loginUser); +console.log("loginInfo.loginPassword = " + loginInfo.loginPassword); +console.log("loginInfo.loginToken = " + loginInfo.loginToken); +``` + +------ + +## 用户退出 + +用户退出代码如下: + +``` +// 返回退出结果 EMError 对象 +emclient.logout().then((res) => { +if(res.code == 0) + console.log("logout success"); +},(error) => {}); +``` + +------ + +## 用户注册 + +接口API如下: + +``` +/** + * 账户注册api,异步操作 + * param username 用户名,输入,String + * param password 密码,输入,String + * return Promise对象,该对象的response参数为Result + */ +createAccount(username, password); + + +调用方法如下: + +emclient.createAccount("newAccount","password").then((res) => { + if(res.errorCode == 0) + console.log("createAccount success"); + else + console.log("createAccount fail:" + res.description); + },(error) => {}) +``` + +------ + +## 连接监听管理 + +通过注册回调函数,可以监听 SDK 的连接与断开状态,在用户登录成功后调用,代码如下 + +``` +// 实例化监听模块 +var listener = new easemob.EMConnectionListener(); +// 添加到client +emclient.addConnectionListener(listener); + +// 连接成功,什么都不需要做 +listener.onConnect(() => { +console.log("EMConnectionListener onConnect"); +}); + +// 连接断开,可能是断网或异地登录被踢,可通过error.errorCode判断,若为206,即为被踢,需要退出登录 +listener.onDisconnect((res) => { +console.log(res.errorCode); +console.log(res.description); +console.log("EMConnectionListener onDisconnect"); +if(res.errorCode == 206) + emclient.logout(); + console.log("你的账户已在其他地方登录"); +}); + +// 移除监听 +emclient.removeConnectionListener(listener); +``` + +------ + +## 系统配置 + +系统配置信息模块为 EMChatConfig ,可以使用 emclient 的 getChatConfigs() 接口获取 + +``` +let config = emclient.getChatConfigs(); +``` + +配置信息包括日志路径,资源路径、下载路径、是否自动同意好友申请、是否自动同意组邀请、退出群组时是否删除消息等,[详见](https://github.com/easemob/sdkdemoapp_windows/blob/electron/jsdoc/out/EmChatConfigs.html) + +------ + +## 私有化部署 + +sdk 提供私有化部署中的服务器设置接口,私有化部署设置使用 api 中的 **EMChatPrivateConfigs**,可以由系统配置模块的 **privateConfigs** 接口获取,代码如下: + +``` +let privateconfigs = config.privateConfigs(); +``` + +**EMChatPrivateConfigs** 使用属性配置服务器部署信息,设置及获取的方法如下: + +``` +privateconfigs.enableDns=false; +privateconfigs.chatServer="192.168.1.100"; +privateconfigs.chatPort=5000; +privateconfigs.restServer="http://192.168.1.101:5001"; +privateconfigs.resolverServer="http://192.168.1.101:5002"; +console.log(privateconfigs.enableDns); +console.log(privateconfigs.chatServer); +console.log(privateconfigs.chatPort); +console.log(privateconfigs.restServer); +console.log(privateconfigs.resolverServer); +``` + +------ + +## 日志输出 + +SDK 提供输出到日志文件的 js 接口,需要先创建 EMLog 对象,可以输出 String 和数字,代码如下: + +``` +// 实例化日志对象,日志按等级可分为error,warn,Debug 3级 +var log = new easemob.EMLog(); + +// 设置日志等级,0为debug,1为warn,2为error +log.setLogLevel(0); + +// 可以控制日志是否输出到控制台,默认不输出 +log.setIsDisplayOnConsole(true); + +//输出日志 +log.Log("Log Test"); +log.Log(5); +log.Debug("Debug Test"); +log.Debug(5); +log.Warn("Warn Test"); +log.Warn(5); +log.Error("Error Test"); +log.Error(5); +``` + +**注:**由于 EMChatConfig 对象创建时会指定日志输出路径,日志对象的创建一般放到 EMChatConfig 创建之后。 + +Windows 桌面端日志生成在 c:/用户/{user}/AppData/Roaming/{ProcessName}/easemob-desktop/easemobLog 路径下的`easemob.log`,{user}为操作系统用户名,{ProcessName}为进程名称,热启动时为**electron**,安装后启动时为**IM-SDK桌面端Demo**。 + +Mac 桌面端日志生成在 /Users/{user}/Library/Application Support/{ProcessName}/easemob-desktop/easemobLog 路径下的`easemolog.log`,{user}为操作系统用户名,{ProcessName}为进程名称,热启动时为**electron**,安装后启动时为**IM-SDK桌面端Demo**。 \ No newline at end of file diff --git a/docs/document/v1/electron/releasenote.md b/docs/document/v1/electron/releasenote.md new file mode 100644 index 000000000..cb44c8b6e --- /dev/null +++ b/docs/document/v1/electron/releasenote.md @@ -0,0 +1,59 @@ +# 桌面端SDK 更新日志 + +## 版本 V3.8.4 2021-12-09 + +新增 + +- 增加支持自定义消息的收发 + +## 版本 V3.8.0 2021-03-13 + +修复 + +- 去掉音视频功能 +- 修复部分Demo bug + +## 版本 V3.6.0 2019-07-16 + +新增 + +- 1v1音视频会话功能 + +修复 + +- 修复了上传附件token过期时,重新获取的token在重试过程中未应用的bug +- 修复了音视频消息体中remotePath路径为空的问题 +- 修复Demo UI层的bug + +## 版本 V3.5.5 2019-05-09 + +新增 + +- sdk 新增私有化部署的接口 + +修复 + +- 修复 Demo 在 mac 系统某些版本(如10.12)上,存在兼容性问题,无法启动的问题 +- 修改 sdk 收到消息后 ack 确认的发送为消息存储到数据库之后,防止突然崩溃导致的消息丢失 +- 修复 Demo UI 层的部分 bug + +优化 + +- 离线消息的下载存储由单条存储改为多条批量存储,提升效率 + +## 版本:V3.5.4 2019-03-26 + +实现功能: + +- 账户的登录、登出、注册。 + +- 聊天:单聊、群聊消息收发。 + +- 消息类型: + +1. 可发送:文本、emoji表情、图片、文件。 +2. 可接收:文本、emoji表情、图片、文件、位置、语音消息。 + +- 好友管理:添加好友、删除好友。 + +- 群管理:创建群、退出群、解散群、修改群标题、邀请加入群、搜索公开群、申请加入公开群。 \ No newline at end of file diff --git a/docs/document/v1/electron/room_manage.md b/docs/document/v1/electron/room_manage.md new file mode 100644 index 000000000..dc437efbd --- /dev/null +++ b/docs/document/v1/electron/room_manage.md @@ -0,0 +1,106 @@ +# 聊天室管理 + +环信桌面端 SDK 支持聊天室功能的集成,集成后可以进行如下操作: + +- 查询聊天室信息 + +- 加入聊天室 + +- 退出聊天室 + +- 监听回调 + +通过这些操作,可以组合帮助您完成多种场景下的 IM 需求。 + +**注意:**聊天室只能有服务端创建,客户端只可以查询、加入和退出聊天室 + +------ + +## 查询聊天室信息 + +``` +// 获取聊天室控制对象 +var chatroomManager = emclient.getChatroomManager(); +// 获取所有聊天室 +var chatroomlist = chatroomManager.fetchAllChatrooms(error); +// 获取聊天室属性 +chatroomlist.map((chatroom) => { + console.log("chatroom id:"+chatroom.chatroomId()); + console.log("chatroom chatroomSubject:"+chatroom.chatroomSubject()); + console.log("chatroom chatroomDescription:"+chatroom.chatroomDescription()); + console.log("chatroom owner:"+chatroom.owner()); + console.log("chatroom chatroomMemberCount:"+chatroom.chatroomMemberCount()); + console.log("chatroom chatroomMemberMaxCount:"+chatroom.chatroomMemberMaxCount()); + console.log("chatroom chatroomAnnouncement:"+chatroom.chatroomAnnouncement()); + var adminlist = chatroom.chatroomAdmins(); + var memberlist = chatroom.chatroomMembers(); + var banslist = chatroom.chatroomBans(); +}); +``` + +------ + +## 加入聊天室 + +接口 API 说明如下: + +``` +/** + * 加入聊天室 + * param chatroomid 聊天室 ID + * param error 操作结果 + * return Promise 对象,该对象的 response 参数 EMChatroom 对象 + */ +joinChatroom(chatroomid,error); +``` + +调用方法如下: + +``` +chatroomManager.joinChatroom(chatroomId, error).then((res)=>{},(error) => {}); +``` + +------ + +## 退出聊天室 + +接口 API 说明如下: + +``` +/** + * 离开聊天室 + * param chatroomid 聊天室 ID + * param error 操作结果 + * return Promise 对象,该对象的 response 参数为空 + */ +leaveChatroom(chatroomid,error); +``` + +调用方法如下: + +``` +chatroomManager.leaveChatroom(chatroomId, error).then((res)=>{},(error) => {}); +``` + +------ + +## 回调监听 + +``` +// 添加消息回调 +var emchatroomlistener = new easemob.EMChatroomManagerListener(); +console.log(emchatroomlistener); + +emchatroomlistener.onMemberJoinedChatroom((chatroom,member) => { + console.log("onMemberJoinedChatroom" + chatroom.chatroomSubject()); + console.log("onMemberJoinedChatroom" + member); +}); +emchatroomlistener.onMemberLeftChatroom((chatroom,member) => { + console.log("onMemberLeftChatroom" + chatroom.chatroomSubject()); + console.log("onMemberLeftChatroom" + member); +}); +//注册监听 +chatroomManager.addListener(emchatroomlistener); +// 移除监听 +chatroomManager.removeListener(emchatroomlistener); +``` \ No newline at end of file diff --git a/docs/document/v1/electron/user_relationship.md b/docs/document/v1/electron/user_relationship.md new file mode 100644 index 000000000..3d1afc810 --- /dev/null +++ b/docs/document/v1/electron/user_relationship.md @@ -0,0 +1,338 @@ +# 好友管理 + +环信桌面端 SDK 支持好友功能的集成,集成后可以进行如下操作: + +- 好友处理 + +- 黑名单处理 + +- 监听联系人变更 + +通过这些操作,可以组合帮助您完成多种场景下的 IM 需求。 + +好友管理模块为 EMContactManager ,由 EMClient 模块加载时主动创建,可以使用 EMClient 模块的 getContactManager 方法获取,代码如下: + +``` +var contactManager = emclient.getContactManager(); +``` + +------ + +## 好友处理 + +好友处理包含以下处理操作: + +- 获取好友列表 + +- 添加好友 + +- 删除好友 + +- 同意好友申请 + +- 拒绝好友申请 + +所有处理操作的示例下面会一一说明。 + +------ + +### 获取好友列表 + +好友列表可以从**本地**和**服务器**获取,各接口说明如下: + +#### 从本地中获取 + +接口 API 如下: + +``` +/** + * 获取当前缓存中的好友列表,若缓存中没有则从数据库中获取 + * return 返回 ContactListResult + */ +allContacts() +``` + +调用方法如下: + +``` +let res = contactManager.allContacts(); +console.log() +``` + +#### 从服务器获取 + +接口API如下: + +``` +/** + * 从服务端拉取好友列表,异步操作 + * return 返回 Promise 对象,response 参数为 ContactListResult + */ +getContactsFromServer(); +``` + +调用方法如下: + +``` +contactManager.getContactsFromServer().then(ContactListResult => { + },(error) => {}); +``` + +------ + +### 添加好友 + +接口API如下: + +``` +/** + * 添加好友 api,异步操作 + * param String,username 为对方用户名,输入参数 + * param String,message 为欢迎信息,输入参数,对方收到好友申请时可以看到 + * return Promise 对象,response 参数为 Result + */ +inviteContact(username, message); +``` + +调用方法如下: + +``` +contactManager.inviteContact("jwfan1", "welcome").then((res) => { + },(error) => {}) +``` + +------ + +### 删除好友 + +接口API如下: + +``` +/** + * 从好友列表移除好友 api,异步操作 + * param username 移除目标好友的用户名,输入参数 + * param keepConversation 移除好友后,是否保留会话,输入参数,布尔型,true 为保留,false 为不保留 + * return Promise 对象,response 参数 Result + */ +deleteContact(username,keepConversation); +``` + +调用方法如下: + +``` +contactManager.deleteContact("jwfan1", true).then((res) => { + },(error) => {}) +``` + +------ + +### 同意好友申请 + +接口 API 如下: + +``` +/** + * 用户收到好友申请后的操作,同意好友申请,异步操作 + * param username 发起好友申请的用户名,输入参数 + * return Promise 对象,response 参数为 Result + */ +acceptInvitation(username); +``` + +调用方法如下: + +``` +contactManager.acceptInvitation(username).then((res) => { + },(error) => {}) +``` + +------ + +### 拒绝好友申请 + +接口 API 如下: + +``` +/** + * 用户收到好友申请后的操作,拒绝好友申请,异步操作 + * param username 发起好友申请的用户名,输入参数 + * return Promise 对象,response 参数为 Result + */ +declineInvitation(username) +``` + +调用方法如下: + +``` +contactManager.declineInvitation(username).then((res) => { + },(error) => {}) +``` + +------ + +## 黑名单 + +黑名单包含以下处理操作: + +- 获取黑名单 + +- 设置黑名单 + +- 移入黑名单 + +- 从黑名单移除 + +所有处理操作的示例下面会一一说明。 + +------ + +### 获取黑名单 + +黑名单列表可以从**本地**和**服务器**获取,各接口说明如下: + +#### 从本地中获取 + +接口 API 如下: + +``` +/** + * 从本地获取用户的黑名单列表,黑名单的用户无法发送消息 + * return ContactListResult 黑名单列表,data 为 String 数组 + */ +blacklist(); +``` + +调用方法如下: + +``` +let res = contactManager.blacklist() +``` + +#### 从服务器获取 + +接口 API 如下: + +``` +/** + * 从服务器获取用户的黑名单列表,黑名单的用户无法发送消息 + * return Promise 对象,response 参数为 ContactListResult + */ +getBlackListFromServer(); +``` + +调用方法如下: + +``` +contactManager.getBlackListFromServer().then((res) => {},(error) => {}) +``` + +------ + +### 设置黑名单 + +接口 API 如下: + +``` +/** + * 设置用户的黑名单列表,异步操作 + * param blacklist 输入参数,黑名单列表,StringArray,["ID1","ID2"] + * return Promise 对象,response 参数为 Result + */ +saveBlackList(blacklist); +``` + +调用方法如下: + +``` +contactManager.saveBlackList(['jwfan2', 'jwfan3']).then((res)=>{},(error) => {}); +``` + +### 移入黑名单 + +接口 API 如下: + +``` +/** + * 添加用户到黑名单列表,异步操作 + * param username 输入参数,要添加的黑名单用户名,String + * return Promise 对象,response 参数为 Result + */ +addToBlackList(username); +``` + +调用方法如下: + +``` +contactManager.addToBlackList('jwfan2').then((res)=>{},(error) => {}); +``` + +------ + +### 从黑名单移除 + +接口 API 如下: + +``` +/** + * 从黑名单列表移除用户,异步操作 + * param username 输入参数,要从黑名单移除的用户名,String + * return Promise 对象,response 参数为 Result + */ +removeFromBlackList(username); +``` + +调用方法如下: + +``` +contactManager.removeFromBlackList('jwfan2').then((res)=>{},(error) => {}); +``` + +------ + +## 监听联系人变更 + +通过注册回调函数,监听联系人的变动,代码如下: + +``` +// 实例化监听对象 +var listener = new easemob.EMContactListener(); + +// 有好友添加的回调 +listener.onContactAdded((username) => { +console.log("onContactAdded username: " + username); +}); + +// 有好友删除的回调 +listener.onContactDeleted((username) => { +console.log("onContactDeleted username: " + username); +}); + +// 收到好友申请的回调,用户可以在这里同意或拒绝好友申请 +listener.onContactInvited((username, reason) => { +console.log("onContactInvited username: " + username + " reason: " + reason); +if (username == "jwfan1") { + let res = contactManager.acceptInvitation(username); +} else { + let res = contactManager.declineInvitation(username); +} +}); + +// 群组邀请成员同意 +listener.onContactAgreed((username) => { +console.log("onContactAgreed username: " + username); +}); + +// 群组邀请成员拒绝 +listener.onContactRefused((username) => { +console.log("onContactRefused username: " + username); +}); + +// 注册回调函数 +contactManager.registerContactListener(listener); + + +===== 结束联系人监听 ===== + +// 移除回调监听 +contactManager.removeContactListener(listener); +``` \ No newline at end of file