Compare commits

...
46 Commits
Author SHA1 Message Date
heavyrain2012 1f9824b283 version to 0.70 2021-09-04 11:23:40 +08:00
heavyrain2012 c7e20632a8 解决单个敏感词无法过滤的问题 2021-09-02 11:55:09 +08:00
heavyrain2012 81a2ab8239 更新命名 2021-09-01 14:48:11 +08:00
heavyrain2012 f62e3f3cef 添加设置用户关系中的附加信息 2021-09-01 14:39:59 +08:00
heavyrain2012 5ce8165514 fix word spell 2021-09-01 13:46:57 +08:00
heavyrain2012 106756ded4 修改敏感词替换错误问题 2021-09-01 13:44:49 +08:00
imndx 3f93be0ece update readme 2021-08-15 10:48:05 +08:00
heavyrain2012 a53f3eb587 version 0.68 -> 0.69 2021-08-13 17:00:02 +08:00
heavyrain2012 d43afb282e 健康检查 2021-08-13 16:37:16 +08:00
heavyrain2012 2f195440cf 更新健康检查内容 2021-08-13 15:06:09 +08:00
heavyrain2012 d241acf980 添加健康检查功能 2021-08-13 12:36:33 +08:00
heavyrain2012 debd4f1aea 解决配置文件中特殊字符问题 2021-08-05 15:44:20 +08:00
heavyrain2012 5a2ded4b6e 回滚错删的配置 2021-07-28 16:16:11 +08:00
heavyrain2012 ca1bdc9ee5 配置文件添加注释 2021-07-28 15:53:28 +08:00
heavyrain2012 b187151683 完善会议API 2021-07-25 12:08:47 +08:00
heavyrain2012 c3859a9fae 当web/pc在线时,手机默认不发出通知 2021-07-23 11:40:04 +08:00
heavyrain2012 c233304a8f version 0.67->0.68 2021-07-23 11:21:14 +08:00
heavyrain2012 affc527326 解决文件不存在时出现的异常 2021-07-23 08:28:11 +08:00
heavyrain2012 07fb4ce511 添加注释 2021-07-22 20:18:16 +08:00
heavyrain2012 ce9f2cbafe 添加开关,确定手机是否默认静音当pc或web在线时 2021-07-22 19:38:14 +08:00
heavyrain2012 2ed81ea629 当好友请求原因为空时,在好友请求接受后,不发送此消息 2021-07-22 16:31:15 +08:00
heavyrain2012 2454067fc3 general admin两个用户设置的接口改为public 2021-07-13 10:10:43 +08:00
heavyrain2012 21a0de04ca 不能尝试兼容加密/未加密的消息,因为有可能错误解出消息,导致不可控结果。 2021-07-12 16:36:38 +08:00
heavyrain2012 f8153d68e8 解决获取原创消息揭秘问题 2021-07-12 15:54:31 +08:00
heavyrain2012 a909e79c50 添加配置是否明文存储消息到数据库 2021-07-12 11:20:26 +08:00
heavyrain2012 c58790ebce 去掉控制台的日志输出 2021-07-06 22:43:22 +08:00
heavyrain2012 0f5b0692af version to 0.67 2021-07-02 11:41:51 +08:00
heavyrain2012 2013e2b6ce SDK复用链接问题 2021-07-01 15:53:04 +08:00
heavyrain2012 35c040c476 解决server api创建群组有部分参数无效问题 2021-07-01 15:10:13 +08:00
heavyrain2012 31472bc5aa 当聊天室不存在时,加入聊天室自动创建聊天室 2021-06-22 11:05:41 +08:00
heavyrain2012 7e812a095f 添加群组成员修改附加信息的功能 2021-06-19 11:34:49 +08:00
heavyrain2012 ec03b4632a server api send friend request force参数错误 2021-06-19 11:34:20 +08:00
heavyrain2012 c1d2c77837 修正新引入的错误 2021-06-19 09:15:51 +08:00
heavyrain2012 5f50455169 添加数据库升级提醒 2021-06-16 14:15:24 +08:00
heavyrain2012 499cfe7602 添加Server SDK 配置对象 2021-06-15 16:28:35 +08:00
heavyrain2012 3b98461946 version 0.65 -> 0.66 2021-06-15 10:58:41 +08:00
imhao183 b10ee75da5 SDK支持多个机器人账户 2021-06-09 16:38:15 +08:00
heavyrain.lee a9792b10ac Update README.md 2021-06-08 13:13:14 +08:00
imhao183 51bfb788ac version 0.64 -> 0.65 2021-06-04 18:01:53 +08:00
dependabot[bot] 82088db682 Bump httpclient from 4.4.1 to 4.5.13 in /broker
Bumps httpclient from 4.4.1 to 4.5.13.

---
updated-dependencies:
- dependency-name: org.apache.httpcomponents:httpclient
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2021-06-04 17:58:45 +08:00
dependabot[bot] 463e3e766a Bump httpclient from 4.5.3 to 4.5.13 in /sdk
Bumps httpclient from 4.5.3 to 4.5.13.

---
updated-dependencies:
- dependency-name: org.apache.httpcomponents:httpclient
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2021-06-04 17:58:34 +08:00
imhao183 4b00b873c3 同步会议参数 2021-06-04 17:52:37 +08:00
imhao183 0c06e28116 解决server api强制添加好友请求时被限制的问题 2021-06-04 17:42:17 +08:00
imndx 7ea6ea08fd update readme 2021-06-01 15:50:07 +08:00
imhao183 b61d292fb5 同步会议API 2021-06-01 08:45:00 +08:00
imhao183 0aba453a24 添加分段同步好友/好友请求/用户设置的功能 2021-05-24 14:44:40 +08:00
71 changed files with 2853 additions and 392 deletions
+19 -15
View File
@@ -1,22 +1,27 @@
## 野火IM解决方案
野火IM是一套跨平台、核心功能开源的即时通讯解决方案,主要包含以下内容。
野火IM是专业级即时通讯和实时音视频整体解决方案,由北京野火无限网络科技有限公司维护和支持。
主要特性有:私有部署安全可靠,性能强大,功能齐全,全平台支持,开源率高,部署运维简单,二次开发友好,方便与第三方系统对接或者嵌入现有系统中。详细情况请参考[在线文档](https://docs.wildfirechat.cn)。
主要包括一下项目:
| [GitHub仓库地址(主站)](https://github.com/wildfirechat) | [码云仓库地址(镜像)](https://gitee.com/wfchat) | 说明 | 备注 |
| ------------------------------------------------------------ | ----------------------------------------------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------- |
| [android-chat](https://github.com/wildfirechat/android-chat) | [android-chat](https://gitee.com/wfchat/android-chat) | 野火IM Android SDK源码和App源码 | 可以很方便地进行二次开发,或集成到现有应用当中 |
| [ios-chat](https://github.com/wildfirechat/ios-chat) | [ios-chat](https://gitee.com/wfchat/ios-chat) | 野火IM iOS SDK源码和App源码 | 可以很方便地进行二次开发,或集成到现有应用当中 |
| [pc-chat](https://github.com/wildfirechat/pc-chat) | [pc-chat](https://gitee.com/wfchat/pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC平台应用 | |
| [web-chat](https://github.com/wildfirechat/web-chat) | [web-chat](https://gitee.com/wfchat/web-chat) | Web平台的Demo, [体验地址](http://web.wildfirechat.cn) | |
| [wx-chat](https://github.com/wildfirechat/wx-chat) | [wx-chat](https://gitee.com/wfchat/wx-chat) | 微信小程序平台的Demo | |
| [server](https://github.com/wildfirechat/server) | [server](https://gitee.com/wfchat/server) | IM server | |
| [app server](https://github.com/wildfirechat/app_server) | [app server](https://gitee.com/wfchat/app_server) | 应用服务端 | |
| [robot_server](https://github.com/wildfirechat/robot_server) | [robot_server](https://gitee.com/wfchat/robot_server) | 机器人服务端 | |
| [push_server](https://github.com/wildfirechat/push_server) | [push_server](https://gitee.com/wfchat/push_server) | 推送服务器 | |
| [docs](https://github.com/wildfirechat/docs) | [docs](https://gitee.com/wfchat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明,[在线查看](https://docs.wildfirechat.cn/) | | |
| 仓库 | 说明 | 备注 |
| ------------------------------------------------------------ | ------------------------------------------------------- | ---- |
| [android-chat](https://github.com/wildfirechat/android-chat) | 野火IM Android SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 |
| [ios-chat](https://github.com/wildfirechat/ios-chat) | 野火IM iOS SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 |
| [pc-chat](https://github.com/wildfirechat/pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC平台应用 | |
| [web-chat](https://github.com/wildfirechat/web-chat) | Web平台的Demo, [体验地址](http://web.wildfirechat.net) | |
| [wx-chat](https://github.com/wildfirechat/wx-chat) | 微信小程序平台的Demo | |
| [server](https://github.com/wildfirechat/server) | IM server | |
| [app server](https://github.com/wildfirechat/app_server) | 应用服务端 | |
| [robot_server](https://github.com/wildfirechat/robot_server) | 机器人服务端 | |
| [push_server](https://github.com/wildfirechat/push_server) | 推送服务器 | |
| [docs](https://github.com/wildfirechat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明 | | | |
# server
本工程为野火IM 社区版IM服务软件。野火IM作为一个通用的即时通讯解决方案,可以集成到各种应用中。请阅读[docs](http://docs.wildfirechat.net)或下载服务器[发布版本](https://github.com/wildfirechat/server/releases)
本工程为野火IM 社区版IM服务软件。野火IM作为一个通用的即时通讯解决方案,既可以直接使用,也可以集成到各种应用中。
开发一套IM系统真的很艰辛,请路过的朋友们给点个star,支持我们坚持下去🙏🙏🙏🙏🙏
@@ -85,4 +90,3 @@
## License
1. Under the Creative Commons Attribution-NoDerivs 3.0 Unported license. See the [LICENSE](https://github.com/wildfirechat/server/blob/wildfirechat/LICENSE) file for details.
2. Under the Anti 996 License. See the [Anti 996 LICENSE](https://github.com/wildfirechat/server/blob/wildfirechat/LICENSE_996) file for details.
+4
View File
@@ -13,6 +13,10 @@
</join>
</network>
<properties>
<property name="hazelcast.logging.type">slf4j</property>
</properties>
<!-- map eviction -->
<!-- http://docs.hazelcast.org/docs/latest-development/manual/html/Distributed_Data_Structures/Map/Map_Eviction.html -->
<map name="messages_map">
+37 -15
View File
@@ -11,13 +11,13 @@
#*********************************************************************
#服务器的接入IP。给客户端提供是${server.ip}和${http_port}。
#客户端会从${http_port}端口获取到长链接端口。这个地址一定要改成客户端可以访问到的IP地址
# (如果您部署云服务器上或者具有独立公网出口的服务器上,请改为对应的公网IP;如果您部署在在内网环境下,在内网使用,这个地方改成内网地址)
#(如果您部署云服务器上或者具有独立公网出口的服务器上,请改为对应的公网IP;如果您部署在在内网环境下,在内网使用,这个地方改成内网地址)
server.ip 192.168.3.124
##原生客户端长链接端口
port 1883
##客户端短链接端口
##客户端短链接端口,客户端固定使用80端口,不要修改此端口。
http_port 80
#管理端口
@@ -32,15 +32,15 @@ host 0.0.0.0
##本地绑定端口
local_port 80
##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2
##是否使用内置DB。0使用mysql;1使用h2db。
embed.db 1
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
## 如果不开启自动清理,需要手动清理t_messages_x和t_user_messages_x表内的历史数据,保存数据不能超过3年。
## 使用mongodb时次开关无效(因为mongodb设置了消息过期时间,会自动清理)。
## 使用mongodb时次开关无效(因为mongodb设置了消息过期时间,会自动清理,仅专业版支持mongodb)。
db.auto_clean_history_messages true
##服务器管理接口密钥
##服务器管理接口密钥。如果修改此端口需要同步修改使用管理API的地方,比如应用服务。
http.admin.secret_key 123456
##服务器API接口参数是否检查时间。当设置为false时,所有的请求会检查时间的有效性;当设置为true时,可以在http.admin.secret_key保持不变的情况下,使用固定的服务API签名
@@ -74,14 +74,21 @@ message.blacklist.strategy 0
##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段
message.disable_remote_search false
##允许客户端撤回用户自己发送的消息时限,单位是秒。群组管理员或群主撤回群成员消息、server api不受此限制,可以撤回任意时限内的消息
##是否数据库中加密消息内容。注意这个开关在服务运行起来后不能改变了,避免读取数据库时无法恢复历史消息。
##如果要避免数据库中明文存储消息内容,请打开这个开关和message.disable_remote_search开关
message.encrypt_message_content false
##允许客户端撤回用户自己发送的消息时限,单位是秒。
##Server API不受此限制,可以撤回任意时限内的消息
##群组管理员或群主撤回群成员消息不受此限制,可以撤回任意时限内的消息。但管理员或群主撤回自己的消息还是需要准守此时间限制。
##修改此参数需要同步修改客户端UI,客户端UI代码有判断撤回是否显示的逻辑。
message.recall_time_limit 120
##禁止群主/群管理员撤回群内消息,关闭时群主/群管理员可以撤回任意时间段内群内成员的消息,群主/群管理员撤回自己发送的消息还是会受到message.recall_time_limit时间限制。
##禁止群主/群管理员撤回群内消息,关闭时群主/群管理员可以撤回任意时间段内群内成员的消息。
message.disable_group_manager_recall false
## 禁止客户端发送消息类型,消息类型以逗号分开,下面3个值为示例,可以删除。
## 一般用于重要类型消息,比如交易、充值等,禁止客户端发送,仅限于服务器发送,提高安全性。
##禁止客户端发送消息类型,消息类型以逗号分开,下面3个值为示例,可以删除。
##一般用于重要类型消息,比如交易、充值等,禁止客户端发送,仅限于服务器发送,提高安全性。
#message.forbidden_client_send_types 3999,4000,4001
## 当禁止发送消息时,允许例外发送的消息。这种一般用户需要被动回应的消息。比如群中被禁言的用户,他无法主动发起音视频,但可以接听未被禁言用户的音视频
@@ -114,7 +121,7 @@ friend.request_expiration_duration 604800000
##添加好友后会发送欢迎消息,比如"你们已经是好友了,可以聊天了"。这个开关控制是用旧的方式还是用新的方式。
##旧的方式会发送notification消息(contenttype是80),内容会根据好友接收者的语言选择对应的语言,如果双方语言不一致会导致另外一方看到的不是本地语言。
##新的方式会发送添加好友消息(contenttype是93)和欢迎消息(contenttype是92),需要客户端实现这两种消息。
##如果客户端已经实现这两种消息可以打开这个开关
##如果客户端已经实现这两种消息可以打开这个开关(客户端2020.6.30添加了此消息类型)。
friend.new_welcome_message true
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
@@ -123,6 +130,9 @@ chatroom.participant_idle_time 900000
## 用户向聊天室发送消息,自动加入聊天室
chatroom.rejoin_when_active true
## 当一个聊天室不存在时,如果有用户加入就自动创建
chatroom.create_when_not_exist true
## 是否允许客户端发送操作群的自定义群通知消息
group.allow_client_custom_operation_notification true
@@ -135,6 +145,10 @@ group.visible_quit_or_kickoff_notification 0
## 注意,修改本配置不会对已经同步的信息产生影响。
#user.hide_properties 3,4,5
# 好友/好友请求/用户设置 这三类数据同步的最大条目数。之前是客户第一次登录时,会把所有的对应数据一次下载到客户端,但如果有特别多的信息,会导致无法同步到客户端,
# 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。
#sync.data_part_size 1000
#*********************************************************************
# hazelcase configuration
#*********************************************************************
@@ -144,7 +158,7 @@ hazelcast.configuration config/hazelcast.xml
# Media server configuration
#*********************************************************************
##是否使用七牛云存储。1使用七牛;0使用内存文件服务器。默认的七牛账户信息不可用,请在七牛官网申请账户并配置
## https://docs.wildfirechat.cn/server/media_server.html
##配置使用七牛请参考:https://docs.wildfirechat.cn/server/media_server.html
media.server.use_qiniu 0
##媒体类型分类
@@ -189,11 +203,17 @@ local.media.storage.root media
# 尽管内置文件存储可以使用,但是我们还是建议使用专业级别的对象存储服务,社区版可以使用七牛,专业版另外支持阿里云和也是私有对象存储。详情请参考 https://docs.wildfirechat.cn/server/oss.html
# local.media.storage.remote_server_url https://example.com/media
# 是否支持多端登陆,为true时支持任意平台任意多个客户端同时登录;为false时每个平台只支持一个端登录,但不同平台可以同时登录。
# 是否支持任意多端登陆,为true时支持任意平台任意多个客户端同时登录;为false时每个平台只支持一个端登录,但不同平台可以同时登录。
# Android/iOS为移动平台,windows/mac/linux为pc平台,web为web平台,小程序为小程序平台。
# 建议使用false
server.multi_endpoint false
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
server.multi_platform_notification false
server.multi_platform_notification true
# 当pc或者web在线时,手机是否默认静音,默认为true。注意仅影响默认值,用户可以手动切换是否静音。
# 如果这里改为false,客户端那边需要同步修改pc在线默认通知状态,方法是client的setDefaultSilentWhenPcOnline函数。
server.mobile_default_silent_when_pc_online true
#*********************************************************************
# Push server configuration
@@ -210,6 +230,8 @@ push.ios.server.address http://localhost:8085/ios/push
#*********************************************************************
# 监控配置
#*********************************************************************
##异常事件产生回调
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#monitor.exception_event_address http://localhost:8888/im_exception_event/
#*********************************************************************
@@ -269,7 +291,7 @@ sensitive.filter.type 0
#sensitive.remote_server_url http://192.168.3.202:8888/message/censor
## 需要进行敏感词审核的消息类型,当有多个时以英文逗号分割
#sensitive.remote_sensitive_message_type 1,2,3
## 如果远程审核服务返回403,返回给发送端发送失败还是成功?实际上这个值影响发送响应是否等待审核结果,当为false时,消息发送给审核服务就立即返回
## 成功给客户端。当为true时,消息发送给审核服务,等待审核结果,如果结果为继续发送就返回给客户端为成功,结果为禁止发送就返回失败给客户端。
## 如果远程审核服务返回403,返回给发送端发送失败还是成功?实际上这个值影响发送响应是否等待审核结果,当为false时,消息发送给审核服务就立即返回成功给客户端。
## 当为true时,消息发送给审核服务,等待审核结果,如果结果为继续发送就返回给客户端为成功,结果为禁止发送就返回失败给客户端。
## 客户端操作的超时一般为10s左右,且考虑到复杂的网络情况,建议处理时间不要超过3s。建议这个值为false。
#sensitive.remote_fail_when_matched false
+2 -2
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.64</version>
<version>0.70</version>
</parent>
<artifactId>moquette-broker</artifactId>
@@ -84,7 +84,7 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
<version>4.5.13</version>
</dependency>
<dependency>
@@ -46,21 +46,28 @@ public class FileAction extends Action {
return true;
}
final File file = getFileByPath(request.getPath());
Logger.debug("Client [{}] get file [{}]", request.getIp(), file.getPath());
File file = null;
try {
file = getFileByPath(request.getPath());
} catch (Exception e) {
response.sendError(HttpResponseStatus.NOT_FOUND, "404 File not found!");
return true;
}
// 隐藏文件,跳过
if (file.isHidden() || !file.exists()) {
// 隐藏文件或不存在,跳过
if (file == null || file.isHidden() || !file.exists()) {
response.sendError(HttpResponseStatus.NOT_FOUND, "404 File not found!");
return true;
}
// 非文件,跳过
if (false == file.isFile()) {
if (!file.isFile()) {
response.sendError(HttpResponseStatus.FORBIDDEN, "403 Forbidden!");
return true;
}
Logger.debug("Client [{}] get file [{}]", request.getIp(), file.getPath());
// Cache Validation
String ifModifiedSince = request.getHeader(HttpHeaderNames.IF_MODIFIED_SINCE.toString());
if (StrUtil.isNotBlank(ifModifiedSince)) {
@@ -8,6 +8,7 @@
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.Action;
@@ -46,7 +47,11 @@ abstract public class AdminAction extends Action {
if (!mLimitCounter.isGranted("admin")) {
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
}
if(APIPath.Health.equals(request.getUri())) {
return ErrorCode.ERROR_CODE_SUCCESS;
}
String nonce = request.getHeader("nonce");
if (StringUtil.isNullOrEmpty(nonce)) {
nonce = request.getHeader("Nonce");
@@ -0,0 +1,39 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputUpdateFriendExtra;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
@Route(APIPath.Friend_Set_Extra)
@HttpMethod("POST")
public class FriendExtraPutAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputUpdateFriendExtra input = getRequestBody(request.getNettyRequest(), InputUpdateFriendExtra.class);
ErrorCode errorCode = messagesStore.setFriendExtraRequest(input.getOperator(), input.getTargetId(), input.getExtra(), new long[1]);
setResponseContent(RestResult.resultOf(errorCode), response);
}
return true;
}
}
@@ -0,0 +1,73 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.pojos.OutputUserBlockStatusList;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.io.File;
import java.lang.management.OperatingSystemMXBean;
import static java.lang.management.ManagementFactory.getOperatingSystemMXBean;
@Route(APIPath.Health)
public class HealthAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("node", "1");
JSONObject cpuObject = new JSONObject();
jsonObject.put("cpu", cpuObject);
JSONObject memoryObject = new JSONObject();
jsonObject.put("memory", memoryObject);
JSONObject fileObject = new JSONObject();
jsonObject.put("disk", fileObject);
if (getOperatingSystemMXBean() instanceof OperatingSystemMXBean) {
double load = getOperatingSystemMXBean().getSystemLoadAverage();
cpuObject.put("load", load);
}
cpuObject.put("cores", Runtime.getRuntime().availableProcessors());
memoryObject.put("free", Runtime.getRuntime().freeMemory());
memoryObject.put("max", Runtime.getRuntime().maxMemory());
memoryObject.put("avail", Runtime.getRuntime().totalMemory());
File root = new File("/");
fileObject.put("space", root.getTotalSpace());
fileObject.put("free", root.getFreeSpace());
fileObject.put("usable", root.getUsableSpace());
JSONArray out = new JSONArray();
out.add(jsonObject);
RestResult result = RestResult.ok(out);
setResponseContent(result, response);
}
return true;
}
}
@@ -0,0 +1,58 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputSetGroupMemberExtra;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import win.liyufan.im.IMTopic;
import java.util.concurrent.Executor;
@Route(APIPath.Group_Set_Member_Extra)
@HttpMethod("POST")
public class ModifyGroupMemberExtraAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputSetGroupMemberExtra inputSetGroupMemberExtra = getRequestBody(request.getNettyRequest(), InputSetGroupMemberExtra.class);
if (inputSetGroupMemberExtra.isValide()) {
sendApiMessage(response, inputSetGroupMemberExtra.getOperator(), IMTopic.ModifyGroupMemberExtraTopic, inputSetGroupMemberExtra.toProtoGroupRequest().toByteArray(), result -> {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
return new Result(errorCode);
});
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,61 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package com.xiaoleilu.loServer.action.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputSetGroupMemberExtra;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import win.liyufan.im.IMTopic;
@Route(APIPath.Robot_Group_Set_Member_Extra)
@HttpMethod("POST")
public class ModifyGroupMemberExtraAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputSetGroupMemberExtra inputSetGroupMemberExtra = getRequestBody(request.getNettyRequest(), InputSetGroupMemberExtra.class);
inputSetGroupMemberExtra.setOperator(robot.getUid());
if (inputSetGroupMemberExtra.isValide()) {
sendApiRequest(response, IMTopic.ModifyGroupMemberExtraTopic, inputSetGroupMemberExtra.toProtoGroupRequest().toByteArray(), result -> {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
});
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -49,7 +49,6 @@ public final class BrokerConstants {
public static final String DISABLED_PORT_BIND = "disabled";
public static final String HOST = "0.0.0.0";
public static final String NEED_CLIENT_AUTH = "need_client_auth";
public static final String HAZELCAST_CONFIGURATION = "hazelcast.configuration";
public static final String HAZELCAST_CLIENT_IP = "hazelcast.client.ip";
public static final String HAZELCAST_CLIENT_PORT = "hazelcast.client.port";
public static final String NETTY_SO_BACKLOG_PROPERTY_NAME = "netty.so_backlog";
@@ -132,6 +131,7 @@ public final class BrokerConstants {
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification";
public static final String SERVER_MOBILE_DEFAULT_SILENT_WHEN_PC_ONLINE = "server.mobile_default_silent_when_pc_online";
public static final String MESSAGE_ROAMING = "message.roaming";
public static final String MESSAGE_Remote_History_Message = "message.remote_history_message";
@@ -152,11 +152,14 @@ public final class BrokerConstants {
public static final String CHATROOM_Participant_Idle_Time = "chatroom.participant_idle_time";
public static final String CHATROOM_Rejoin_When_Active = "chatroom.rejoin_when_active";
public static final String CHATROOM_Create_When_Not_Exist = "chatroom.create_when_not_exist";
public static final String GROUP_Allow_Client_Custom_Operation_Notification = "group.allow_client_custom_operation_notification";
public static final String GROUP_Visible_Quit_Kickoff_Notification = "group.visible_quit_or_kickoff_notification";
public static final String USER_HIDE_PROPERTIES = "user.hide_properties";
public static final String SYNC_Data_Part_Size = "sync.data_part_size";
public static final String MESSAGES_FORBIDDEN_CLIENT_SEND_TYPES = "message.forbidden_client_send_types";
public static final String MESSAGES_BLACKLIST_EXCEPTION_TYPES = "message.blacklist_exception_types";
@@ -164,6 +167,8 @@ public final class BrokerConstants {
public static final String MESSAGES_GLOBAL_MUTE_EXCEPTION_TYPES = "message.global_mute_exception_types";
public static final String MESSAGES_DISABLE_REMOTE_SEARCH = "message.disable_remote_search";
public static final String MESSAGES_ENCRYPT_MESSAGE_CONTENT = "message.encrypt_message_content";
public static final String MESSAGES_RECALL_TIME_LIMIT = "message.recall_time_limit";
public static final String MESSAGES_DISABLE_GROUP_MANAGER_RECALL = "message.disable_group_manager_recall";
@@ -37,7 +37,9 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
long timestamp = System.currentTimeMillis();
builder.setMessageId(messageId);
builder.setServerTimestamp(timestamp);
saveAndPublish(request.getTargetUid(), null, builder.build());
if(!StringUtil.isNullOrEmpty(builder.getContent().getSearchableContent())) {
saveAndPublish(request.getTargetUid(), null, builder.build());
}
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
String language = "zh_CN";
@@ -25,7 +25,7 @@ public class ModifyGroupAliasHandler extends GroupHandler<WFCMessage.ModifyGroup
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), null, isAdmin);
ErrorCode errorCode = m_messagesStore.modifyGroupMemberAlias(fromUser, request.getGroupId(), request.getAlias(), null, isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
@@ -25,8 +25,8 @@ public class ModifyGroupMemberAliasHandler extends GroupHandler<WFCMessage.Modif
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), request.getMemberId(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS && request.hasNotifyContent()) {
ErrorCode errorCode = m_messagesStore.modifyGroupMemberAlias(fromUser, request.getGroupId(), request.getAlias(), request.getMemberId(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
@@ -0,0 +1,39 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package io.moquette.imhandler;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.GroupNotificationBinaryContent;
import cn.wildfirechat.proto.WFCMessage;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import win.liyufan.im.IMTopic;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
@Handler(IMTopic.ModifyGroupMemberExtraTopic)
public class ModifyGroupMemberExtraHandler extends GroupHandler<WFCMessage.ModifyGroupMemberExtra> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupMemberExtra request, Qos1PublishHandler.IMCallback callback) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.modifyGroupMemberExtra(fromUser, request.getGroupId(), request.getExtra(), request.getMemberId(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getExtra(), request.getMemberId()).getModifyGroupMemberExtraNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
}
}
return errorCode;
}
}
@@ -8,11 +8,11 @@
package io.moquette.persistence;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.pojos.SystemSettingPojo;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import cn.wildfirechat.server.ThreadPoolExecutorWrapper;
import com.google.protobuf.InvalidProtocolBufferException;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.MultiMap;
import com.hazelcast.util.StringUtil;
@@ -26,7 +26,9 @@ import win.liyufan.im.MessageBundle;
import win.liyufan.im.MessageShardingUtil;
import win.liyufan.im.Utility;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.sql.*;
import java.util.*;
@@ -42,10 +44,15 @@ public class DatabaseStore {
private static final Logger LOG = LoggerFactory.getLogger(DatabaseStore.class);
private final ThreadPoolExecutorWrapper mScheduler;
private boolean disableRemoteMessageSearch = false;
private boolean encryptMessage = false;
public void setDisableRemoteMessageSearch(boolean disableRemoteMessageSearch) {
this.disableRemoteMessageSearch = disableRemoteMessageSearch;
}
public void setEncryptMessage(boolean encryptMessage) {
this.encryptMessage = encryptMessage;
}
public DatabaseStore(ThreadPoolExecutorWrapper scheduler) {
this.mScheduler = scheduler;
}
@@ -537,7 +544,7 @@ public class DatabaseStore {
statement.setString(index++, message.getConversation().getTarget());
statement.setInt(index++, message.getConversation().getLine());
Blob blob = connection.createBlob();
blob.setBytes(1, message.getContent().toByteArray());
blob.setBytes(1, encryptMessageContent(message.getContent().toByteArray(), false));
statement.setBlob(index++, blob);
if (!disableRemoteMessageSearch) {
statement.setString(index++, searchableContent);
@@ -571,6 +578,15 @@ public class DatabaseStore {
});
}
byte[] encryptMessageContent(byte[] in, boolean force) {
if(in != null && (encryptMessage || force)) {
for (int i = 0; i < in.length; i++) {
in[i] ^= 0xBD;
}
}
return in;
}
void persistSensitiveMessage(final WFCMessage.Message message) {
if(message.getContent().getPersistFlag() == Transparent) {
return;
@@ -599,7 +615,7 @@ public class DatabaseStore {
statement.setString(index++, message.getConversation().getTarget());
statement.setInt(index++, message.getConversation().getLine());
Blob blob = connection.createBlob();
blob.setBytes(1, message.getContent().toByteArray());
blob.setBytes(1, encryptMessageContent(message.getContent().toByteArray(), false));
statement.setBlob(index++, blob);
statement.setString(index++, searchableContent);
statement.setTimestamp(index++, new Timestamp(message.getServerTimestamp()));
@@ -668,7 +684,7 @@ public class DatabaseStore {
builder.setConversation(cb.build());
Blob blob = resultSet.getBlob(index++);
WFCMessage.MessageContent messageContent = WFCMessage.MessageContent.parseFrom(blob.getBinaryStream());
WFCMessage.MessageContent messageContent = WFCMessage.MessageContent.parseFrom(encryptMessageContent(toByteArray(blob.getBinaryStream()), false));
builder.setContent(messageContent);
builder.setServerTimestamp(resultSet.getTimestamp(index++).getTime());
WFCMessage.Message message = builder.build();
@@ -702,6 +718,16 @@ public class DatabaseStore {
return out;
}
public byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
MessageBundle getMessage(long messageId) {
String sql = "select `_from`, `_type`, `_target`, `_line`, `_data`, `_dt` from " + MessageShardingUtil.getMessageTable(messageId) +" where _mid = ? order by `_dt` DESC limit 1";
Connection connection = null;
@@ -724,7 +750,7 @@ public class DatabaseStore {
builder.setConversation(cb.build());
Blob blob = resultSet.getBlob(index++);
WFCMessage.MessageContent messageContent = WFCMessage.MessageContent.parseFrom(blob.getBinaryStream());
WFCMessage.MessageContent messageContent = WFCMessage.MessageContent.parseFrom(encryptMessageContent(toByteArray(blob.getBinaryStream()), false));
builder.setContent(messageContent);
builder.setServerTimestamp(resultSet.getTimestamp(index++).getTime());
WFCMessage.Message message = builder.build();
@@ -829,7 +855,8 @@ public class DatabaseStore {
builder.setConversation(cb.build());
Blob blob = resultSet.getBlob(index++);
WFCMessage.MessageContent messageContent = WFCMessage.MessageContent.parseFrom(blob.getBinaryStream());
WFCMessage.MessageContent messageContent = WFCMessage.MessageContent.parseFrom(encryptMessageContent(toByteArray(blob.getBinaryStream()), false));
builder.setContent(messageContent);
builder.setServerTimestamp(resultSet.getTimestamp(index++).getTime());
@@ -133,10 +133,12 @@ public class MemoryMessagesStore implements IMessagesStore {
private boolean mFriendNewWelcomeMessage = true;
private boolean mMultiPlatformNotification = false;
private boolean mMobileDefaultSilentWhenPCOnline = true;
private boolean mDisableStrangerChat = false;
private long mChatroomParticipantIdleTime = 900000;
private boolean mChatroomRejoinWhenActive = true;
private boolean mChatroomCreateWhenNotExist = true;
private List<Integer> mForbiddenClientSendTypes = new ArrayList<>();
private List<Integer> mBlackListExceptionTypes = new ArrayList<>();
@@ -154,6 +156,7 @@ public class MemoryMessagesStore implements IMessagesStore {
private String mChatroomMemberUpdateCallback;
private boolean mGroupAllowClientCustomOperationNotification;
private int mGroupVisibleQuitKickoffNotification;
private int mSyncDataPartSize = 0;
private Set<Integer> mUserHideProperties = new HashSet<>();
@@ -181,6 +184,12 @@ public class MemoryMessagesStore implements IMessagesStore {
printMissConfigLog(SERVER_MULTI_PLATFROM_NOTIFICATION, mMultiPlatformNotification + "");
}
try {
mMobileDefaultSilentWhenPCOnline = Boolean.parseBoolean(m_Server.getConfig().getProperty(SERVER_MOBILE_DEFAULT_SILENT_WHEN_PC_ONLINE, "true"));
} catch (Exception e) {
e.printStackTrace();
}
try {
mDisableSearch = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_Search));
} catch (Exception e) {
@@ -244,6 +253,14 @@ public class MemoryMessagesStore implements IMessagesStore {
printMissConfigLog(CHATROOM_Rejoin_When_Active, mChatroomRejoinWhenActive + "");
}
try {
mChatroomCreateWhenNotExist = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.CHATROOM_Create_When_Not_Exist));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(CHATROOM_Create_When_Not_Exist, mChatroomCreateWhenNotExist + "");
}
try {
mChatroomParticipantIdleTime = Long.parseLong(m_Server.getConfig().getProperty(CHATROOM_Participant_Idle_Time, "900000"));
} catch (Exception e) {
@@ -258,6 +275,12 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) {
}
try {
boolean encryptMessage = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.MESSAGES_ENCRYPT_MESSAGE_CONTENT, "false"));
databaseStore.setEncryptMessage(encryptMessage);
} catch (Exception e) {
}
try {
mRecallTimeLimit = Long.parseLong(m_Server.getConfig().getProperty(BrokerConstants.MESSAGES_RECALL_TIME_LIMIT));
} catch (Exception e) {
@@ -381,6 +404,12 @@ public class MemoryMessagesStore implements IMessagesStore {
}
try {
mSyncDataPartSize = Integer.parseInt(server.getConfig().getProperty(SYNC_Data_Part_Size, "0"));
} catch (Exception e) {
}
try {
String userHideStr = server.getConfig().getProperty(USER_HIDE_PROPERTIES);
@@ -1491,7 +1520,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public ErrorCode modifyGroupAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin) {
public ErrorCode modifyGroupMemberAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
@@ -1575,6 +1604,91 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override
public ErrorCode modifyGroupMemberExtra(String operator, String groupId, String extra, String memberId, boolean isAdmin) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
WFCMessage.GroupInfo groupInfo = mIMap.get(groupId);
if (groupInfo == null) {
groupInfo = databaseStore.getPersistGroupInfo(groupId);
if (groupInfo != null) {
mIMap.set(groupId, groupInfo);
} else {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
}
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
if (members == null || members.size() == 0) {
members = loadGroupMemberFromDB(hzInstance, groupId);
}
if (StringUtil.isNullOrEmpty(memberId)) {
memberId = operator;
} else {
if (!isAdmin && !operator.equals(groupInfo.getOwner())) {
WFCMessage.GroupMember operatorMember = null;
WFCMessage.GroupMember targetMember = null;
for (WFCMessage.GroupMember member : members) {
if (member.getMemberId().equals(operator)) {
operatorMember = member;
if (targetMember != null) {
break;
}
}
if ((member.getMemberId().equals(memberId))) {
targetMember = member;
if (operatorMember != null) {
break;
}
}
}
if (operatorMember == null) {
LOG.error("Modify group member extra error, the operator {} is not in group", operator);
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
if (targetMember == null) {
LOG.error("Modify group member extra error, the member {} is not in group", memberId);
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
if (operatorMember.getType() == GroupMemberType_Manager && targetMember.getType() != GroupMemberType_Manager) {
LOG.error("Modify group member extra error, the operator {} type is {} and the member {} type is {}", operator, operatorMember.getType(), memberId, targetMember.getType());
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
}
}
long updateDt = System.currentTimeMillis();
boolean inGroup = false;
for (WFCMessage.GroupMember member : members) {
if (member.getMemberId().equals(memberId)) {
groupMembers.remove(groupId, member);
member = member.toBuilder().setExtra(extra).setUpdateDt(updateDt).build();
databaseStore.persistGroupMember(groupId, Arrays.asList(member), false);
databaseStore.updateGroupMemberDt(groupId, updateDt);
groupMembers.put(groupId, member);
mIMap.set(groupId, groupInfo.toBuilder().setUpdateDt(updateDt).setMemberUpdateDt(updateDt).build());
inGroup = true;
break;
}
}
if (!inGroup) {
LOG.error("Modify group member extra error, the member {} is not in group", memberId);
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
callbackGroupMemberEvent(operator, groupId, Arrays.asList(memberId), ProtoConstants.GroupMemberUpdateEventType.Group_Member_Event_Alias, extra);
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override
public List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -2573,6 +2687,11 @@ public class MemoryMessagesStore implements IMessagesStore {
}
}
if(mSyncDataPartSize > 0 && out.size() > mSyncDataPartSize) {
out.sort(Comparator.comparingLong(FriendData::getTimestamp));
out = out.subList(0, mSyncDataPartSize);
}
return out;
}
@@ -2618,12 +2737,16 @@ public class MemoryMessagesStore implements IMessagesStore {
}
}
if(mSyncDataPartSize > 0 && out.size() > mSyncDataPartSize) {
out.sort(Comparator.comparingLong(WFCMessage.FriendRequest::getUpdateDt));
out = out.subList(0, mSyncDataPartSize);
}
return out;
}
@Override
public ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin) {
if (mDisableFriendRequest) {
if (!isAdmin && mDisableFriendRequest) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
@@ -2956,11 +3079,53 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override
public ErrorCode setFriendExtraRequest(String fromUser, String targetUserId, String extra, long[] heads){
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
FriendData friendData = null;
Collection<FriendData> friends = friendsMap.get(fromUser);
if (friends == null || friends.size() == 0) {
friends = loadFriend(friendsMap, fromUser);
}
for (FriendData fd:friends) {
if (fd.getFriendUid().equals(targetUserId)) {
friendData = fd;
break;
}
}
if (friendData == null) {
friendData = new FriendData();
friendData.setUserId(fromUser);
friendData.setFriendUid(targetUserId);
}
friendData.setExtra(extra);
friendData.setTimestamp(System.currentTimeMillis());
databaseStore.persistOrUpdateFriendData(friendData);
heads[0] = friendData.getTimestamp();
friendsMap.remove(fromUser);
callbackRelationEvent(fromUser, targetUserId, 3, extra);
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override
public ErrorCode handleJoinChatroom(String userId, String clientId, String chatroomId) {
IMap<String, WFCMessage.ChatroomInfo> chatroomInfoMap = m_Server.getHazelcastInstance().getMap(CHATROOMS);
if (chatroomInfoMap == null || chatroomInfoMap.get(chatroomId) == null) {
return ErrorCode.ERROR_CODE_NOT_EXIST;
if(mChatroomCreateWhenNotExist) {
WFCMessage.ChatroomInfo.Builder builder = WFCMessage.ChatroomInfo.newBuilder().setTitle(chatroomId);
createChatroom(chatroomId, builder.build());
} else {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
}
m_Server.getStore().sessionsStore().getSession(clientId).refreshLastChatroomActiveTime();
@@ -3111,6 +3276,12 @@ public class MemoryMessagesStore implements IMessagesStore {
}
}
if(mSyncDataPartSize > 0 && ec == ErrorCode.ERROR_CODE_SUCCESS && builder.getEntryCount() > mSyncDataPartSize) {
List<WFCMessage.UserSettingEntry> list = new ArrayList<>(builder.getEntryList());
list.sort(Comparator.comparingLong(WFCMessage.UserSettingEntry::getUpdateDt));
list = list.subList(0, mSyncDataPartSize);
builder.clearEntry().addAllEntry(list);
}
return ec;
}
@@ -3273,9 +3444,9 @@ public class MemoryMessagesStore implements IMessagesStore {
public boolean getSilentWhenPcOnline(String userId) {
WFCMessage.UserSettingEntry entry = getUserSetting(userId, UserSettingScope.kUserSettingMuteWhenPCOnline, null);
if (entry != null && "1".equals(entry.getValue())) {
return true;
return !mMobileDefaultSilentWhenPCOnline;
} else {
return false;
return mMobileDefaultSilentWhenPCOnline;
}
}
private Date getTodayDate() {
@@ -362,7 +362,7 @@ public class Server {
LOG.info("Configuring embedded Hazelcast instance");
String serverIp = getServerIp(config);
String hzConfigPath = config.getProperty(BrokerConstants.HAZELCAST_CONFIGURATION);
String hzConfigPath = "config/hazelcast.xml";
String hzClientIp = config.getProperty(BrokerConstants.HAZELCAST_CLIENT_IP, "localhost");
String hzClientPort = config.getProperty(BrokerConstants.HAZELCAST_CLIENT_PORT, "5703");
@@ -84,34 +84,37 @@ class ConfigurationParser {
String line;
try {
while ((line = br.readLine()) != null) {
line = line.trim();
int commentMarker = line.indexOf('#');
if (commentMarker != -1) {
if (commentMarker == 0) {
// skip its a comment
continue;
} else {
// it's a malformed comment
throw new ParseException(line, commentMarker);
String[] ss = line.split(" ");
if(ss.length != 2) {
throw new ParseException(line, commentMarker);
}
}
} else {
if (line.isEmpty() || line.matches("^\\s*$")) {
// skip it's a black line
continue;
}
// split till the first space
int delimiterIdx = line.indexOf(' ');
String key;
String value = "";
if (delimiterIdx > 0) {
key = line.substring(0, delimiterIdx).trim();
value = line.substring(delimiterIdx).trim();
} else {
key = line.trim();
}
m_properties.put(key, value);
}
// split till the first space
int delimiterIdx = line.indexOf(' ');
String key;
String value = "";
if (delimiterIdx > 0) {
key = line.substring(0, delimiterIdx).trim();
value = line.substring(delimiterIdx).trim();
} else {
key = line.trim();
}
m_properties.put(key, value);
}
} catch (IOException ex) {
throw new ParseException("Failed to read", 1);
@@ -113,7 +113,8 @@ public interface IMessagesStore {
void clearUserGroups(String userId);
ErrorCode dismissGroup(String operator, String groupId, boolean isAdmin);
ErrorCode modifyGroupInfo(String operator, String groupId, int modifyType, String value, boolean isAdmin);
ErrorCode modifyGroupAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin);
ErrorCode modifyGroupMemberAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin);
ErrorCode modifyGroupMemberExtra(String operator, String groupId, String extra, String memberId, boolean isAdmin);
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests);
WFCMessage.GroupInfo getGroupInfo(String groupId);
Set<String> getUserGroupIds(String userId);
@@ -181,6 +182,7 @@ public interface IMessagesStore {
ErrorCode SyncFriendRequestUnread(String userId, long unreadDt, long[] head);
ErrorCode isAllowUserMessage(String fromUser, String userId);
ErrorCode setFriendAliasRequest(String fromUser, String targetUserId, String alias, long[] head);
ErrorCode setFriendExtraRequest(String fromUser, String targetUserId, String extra, long[] head);
ErrorCode handleJoinChatroom(String userId, String clientId, String chatroomId);
ErrorCode handleQuitChatroom(String userId, String clientId, String chatroomId);
@@ -12,6 +12,7 @@ package win.liyufan.im;
import java.beans.PropertyVetoException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.math.BigInteger;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
@@ -104,7 +105,11 @@ public class DBUtil {
}
}
Flyway flyway = Flyway.configure().dataSource(comboPooledDataSource).locations(migrateLocation).baselineOnMigrate(true).load();
if(!IsEmbedDB && (flyway.info().current() == null || flyway.info().current().getVersion().getMajor().intValue() < 43)) {
System.out.println("数据库执行初始化或升级需要较长时间,可能长达数分钟或更长,请耐心等待,不要中断。。。");
}
flyway.migrate();
if(autoCleanMsgs) {
@@ -32,6 +32,7 @@ public interface IMTopic {
String ModifyGroupInfoTopic = "GMI";
String ModifyGroupAliasTopic = "GMA";
String ModifyGroupMemberAliasTopic = "GMMA";
String ModifyGroupMemberExtraTopic = "GMME";
String GetGroupInfoTopic = "GPGI";
String GetGroupMemberTopic = "GPGM";
String TransferGroupTopic = "GTG";
@@ -31,11 +31,12 @@ public class SensitiveFilter {
return sensitiveWords;
}
String originalText = text;
text = text.toLowerCase();
for(int i=0;i<text.length();i++){
int sensitiveWordLength = getSensitiveWordLength(text, i, matchType);
if(sensitiveWordLength>0){
String sensitiveWord = text.substring(i, i + sensitiveWordLength);
String sensitiveWord = originalText.substring(i, i + sensitiveWordLength);
sensitiveWords.add(sensitiveWord);
if(matchType==MatchType.MIN_MATCH){
break;
@@ -93,7 +94,7 @@ public class SensitiveFilter {
Iterator<String> iterator = sensitiveWords.iterator();
while (iterator.hasNext()){
currentWord=iterator.next();
if(currentWord==null||currentWord.trim().length()<2){ //敏感词长度必须大于等于2
if(currentWord==null||currentWord.trim().length()<1){ //敏感词长度必须大于等于1
continue;
}
currentMap=sensitiveWordsMap;
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.64</version>
<version>0.70</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -39,6 +39,7 @@ public interface APIPath {
String Blacklist_Get_List = "/admin/blacklist/list";
String Friend_Get_Alias = "/admin/friend/get_alias";
String Friend_Set_Alias = "/admin/friend/set_alias";
String Friend_Set_Extra = "/admin/friend/set_extra";
String Friend_Send_Request = "/admin/friend/send_request";
String Friend_Get_Requests = "/admin/friend/get_requests";
String Relation_Get = "/admin/relation/get";
@@ -65,11 +66,19 @@ public interface APIPath {
String Group_Allow_Member = "/admin/group/manager/allow";
String Get_User_Groups = "/admin/group/of_user";
String Group_Set_Member_Alias = "/admin/group/member/set_alias";
String Group_Set_Member_Extra = "/admin/group/member/set_extra";
String Create_Channel = "/admin/channel/create";
String Get_System_Setting = "/admin/system/get_setting";
String Put_System_Setting = "/admin/system/put_setting";
String Health = "/admin/health";
String Conference_List = "/admin/conference/list";
String Conference_List_Participant = "/admin/conference/list_participant";
String Conference_Create = "/admin/conference/create";
String Conference_Destroy = "/admin/conference/destroy";
String Channel_User_Info = "/channel/user_info";
String Channel_Update_Profile = "/channel/update_profile";
String Channel_Get_Profile = "/channel/get_profile";
@@ -96,6 +105,7 @@ public interface APIPath {
String Robot_Group_Member_Kickoff = "/robot/group/member/del";
String Robot_Group_Modify_Info = "/robot/group/modify";
String Robot_Group_Set_Member_Alias = "/robot/group/member/set_alias";
String Robot_Group_Set_Member_Extra = "/robot/group/member/set_extra";
String Robot_Group_Mute_Member = "/robot/group/manager/mute";
String Robot_Group_Member_Quit = "/robot/group/member/quit";
String Robot_Group_Transfer = "/robot/group/transfer";
@@ -38,11 +38,13 @@ public enum ErrorCode {
ERROR_CODE_NOT_IN_CHANNEL(21, "not in channel"),
ERROR_CODE_NOT_LICENSED(22, "not licensed"),
ERROR_CODE_ALREADY_FRIENDS(23, "already friends"),
ERROR_CODE_RECALL_TIME_EXPIRED(24, "time expired"),
ERROR_CODE_CONFERENCE_ROOM_NOT_EXIST(60, "conference room not exist"),
ERROR_CODE_USER_NOT_PREPARED(238, "user not prepared"),
ERROR_CODE_API_NOT_SIGNED(239, "api not signed or sign parameter not completion"),
ERROR_CODE_GROUP_EXCEED_MAX_MEMBER_COUNT(240, "group exceed max member count"),
ERROR_CODE_GROUP_MUTED(241, "group is muted"),
@@ -50,7 +52,7 @@ public enum ErrorCode {
ERROR_CODE_SIGN_EXPIRED(243, "sign expired"),
ERROR_CODE_AUTH_FAILURE(244, "auth failure"),
ERROR_CODE_CLIENT_COUNT_OUT_OF_LIMIT(245, "client count out of limit"),
ERROR_CODE_IN_BLACK_LIST(246, "user in balck list"),
ERROR_CODE_IN_BLACK_LIST(246, "user in black list"),
ERROR_CODE_FORBIDDEN_SEND_MSG(247, "forbidden send msg globally"),
ERROR_CODE_NOT_RIGHT(248, "no right to operate"),
ERROR_CODE_TIMEOUT(249, "timeout"),
@@ -11,6 +11,7 @@ public class IMExceptionEvent {
int ROBOT_API_Exception = 7;
int SHORT_LINK_Exception = 8;
int EVENT_CALLBACK_Exception = 9;
int CONFERENCE_Exception = 10;
int HEART_BEAT = 100;
}
@@ -0,0 +1,13 @@
package cn.wildfirechat.pojos;
public class ConferenceCreateEvent {
public String userId;
public String roomId;
public String serverId;
public String description;
public String pin;
public int max_publishers;
public int bitrate;
public boolean advance;
public boolean recording;
}
@@ -0,0 +1,6 @@
package cn.wildfirechat.pojos;
public class ConferenceDestroyEvent {
public String userId;
public String roomId;
}
@@ -0,0 +1,6 @@
package cn.wildfirechat.pojos;
public class ConferenceJoinEvent {
public String userId;
public String roomId;
}
@@ -0,0 +1,6 @@
package cn.wildfirechat.pojos;
public class ConferenceLeaveEvent {
public String userId;
public String roomId;
}
@@ -0,0 +1,7 @@
package cn.wildfirechat.pojos;
public class ConferencePublishEvent {
public String userId;
public boolean video;
public String roomId;
}
@@ -0,0 +1,6 @@
package cn.wildfirechat.pojos;
public class ConferenceUnpublishEvent {
public String userId;
public String roomId;
}
@@ -133,6 +133,10 @@ public class GroupNotificationBinaryContent {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_MODIFY_GROUP_ALIAS);
}
public WFCMessage.MessageContent getModifyGroupMemberExtraNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_MODIFY_GROUP_MEMBER_EXTRA);
}
public WFCMessage.MessageContent getChangeGroupMuteNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_CHANGE_MUTE);
}
@@ -164,5 +168,4 @@ public class GroupNotificationBinaryContent {
public WFCMessage.MessageContent getChangeGroupExtraNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_MODIFY_GROUP_EXTRA);
}
}
@@ -0,0 +1,29 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
import java.util.List;
public class HealthCheckResult extends ArrayList<HealthCheckResult.Node>
{
public static class Node {
public String node;
public CPU cpu;
public Memory memory;
public Disk disk;
}
public static class Memory {
public long avail;
public long max;
public long free;
}
public static class Disk {
public long usable;
public long free;
public long space;
}
public static class CPU {
public int cores;
public double load;
}
}
@@ -56,9 +56,15 @@ public class InputCreateGroup extends InputGroupBase {
if (group_info.private_chat > 0 && group_info.private_chat < 128) {
groupInfoBuilder.setPrivateChat(group_info.private_chat);
}
if (group_info.searchable > 0) {
if (group_info.searchable > 0 && group_info.searchable < 128) {
groupInfoBuilder.setSearchable(group_info.searchable);
}
if(group_info.history_message > 0&& group_info.history_message < 128) {
groupInfoBuilder.setHistoryMessage(group_info.history_message);
}
if(group_info.max_member_count > 0) {
groupInfoBuilder.setMaxMemberCount(group_info.max_member_count);
}
groupBuilder.setGroupInfo(groupInfoBuilder);
for (PojoGroupMember pojoGroupMember : group.getMembers()) {
@@ -27,6 +27,8 @@ public class InputDismissGroup extends InputGroupBase {
}
public boolean isValide() {
if (StringUtil.isNullOrEmpty(group_id) || StringUtil.isNullOrEmpty(operator))
return false;
return true;
}
@@ -35,6 +35,8 @@ public class InputKickoffGroupMember extends InputGroupBase {
}
public boolean isValide() {
if (StringUtil.isNullOrEmpty(group_id) || StringUtil.isNullOrEmpty(operator) || members == null || members.isEmpty())
return false;
return true;
}
@@ -22,7 +22,9 @@ public class InputModifyGroupInfo extends InputGroupBase {
private String value;
public boolean isValide() {
return !StringUtil.isNullOrEmpty(group_id);
if (StringUtil.isNullOrEmpty(group_id) || StringUtil.isNullOrEmpty(operator))
return false;
return true;
}
public String getGroup_id() {
return group_id;
@@ -10,6 +10,7 @@ package cn.wildfirechat.pojos;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.List;
@@ -25,6 +26,8 @@ public class InputQuitGroup extends InputGroupBase {
}
public boolean isValide() {
if (StringUtil.isNullOrEmpty(group_id) || StringUtil.isNullOrEmpty(operator))
return false;
return true;
}
@@ -0,0 +1,65 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
public class InputSetGroupMemberExtra extends InputGroupBase {
private String group_id;
private String memberId;
private String extra;
public String getGroup_id() {
return group_id;
}
public void setGroup_id(String group_id) {
this.group_id = group_id;
}
public boolean isValide() {
return true;
}
public WFCMessage.ModifyGroupMemberExtra toProtoGroupRequest() {
WFCMessage.ModifyGroupMemberExtra.Builder modifyAliasBuilder = WFCMessage.ModifyGroupMemberExtra.newBuilder();
modifyAliasBuilder.setGroupId(group_id);
modifyAliasBuilder.setMemberId(memberId);
modifyAliasBuilder.setExtra(StringUtil.isNullOrEmpty(extra)?"": extra);
if (to_lines != null) {
for (Integer line : to_lines) {
modifyAliasBuilder.addToLine(line);
}
}
if (notify_message != null) {
modifyAliasBuilder.setNotifyContent(notify_message.toProtoMessageContent());
}
return modifyAliasBuilder.build();
}
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
}
@@ -18,6 +18,8 @@ public class InputTransferGroup extends InputGroupBase {
public boolean isValide() {
if (StringUtil.isNullOrEmpty(group_id) || StringUtil.isNullOrEmpty(operator) || StringUtil.isNullOrEmpty(new_owner))
return false;
return true;
}
@@ -0,0 +1,40 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class InputUpdateFriendExtra {
private String operator;
private String targetId;
private String extra;
public String getTargetId() {
return targetId;
}
public void setTargetId(String targetId) {
this.targetId = targetId;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
}
@@ -0,0 +1,21 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class InputVerifyApplicationUser {
private String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
@@ -0,0 +1,21 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class OutputVerifyApplicationUser {
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
@@ -0,0 +1,11 @@
package cn.wildfirechat.pojos;
public class PojoConferenceCreate {
public String roomId;
public String description;
public String pin;
public int max_publishers;
public int bitrate;
public boolean advance;
public boolean recording;
}
@@ -0,0 +1,12 @@
package cn.wildfirechat.pojos;
public class PojoConferenceInfo {
public String roomId;
public String serverId;
public String description;
public int max_publishers;
public int num_publishers;
public int bitrate;
public boolean advance;
public boolean recording;
}
@@ -0,0 +1,21 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
import java.util.List;
public class PojoConferenceInfoList {
public PojoConferenceInfoList(List<PojoConferenceInfo> conferenceInfoList) {
this.conferenceInfoList = conferenceInfoList;
}
public PojoConferenceInfoList() {
conferenceInfoList = new ArrayList<>();
}
public List<PojoConferenceInfo> conferenceInfoList;
public void addConferenceInfo(PojoConferenceInfo conferenceInfo) {
this.conferenceInfoList.add(conferenceInfo);
}
}
@@ -0,0 +1,6 @@
package cn.wildfirechat.pojos;
public class PojoConferenceParticipant {
public String userId;
public boolean publishing;
}
@@ -0,0 +1,21 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
import java.util.List;
public class PojoConferenceParticipantList {
public PojoConferenceParticipantList(List<PojoConferenceParticipant> participantList) {
this.participantList = participantList;
}
public PojoConferenceParticipantList() {
participantList = new ArrayList<>();
}
public List<PojoConferenceParticipant> participantList;
public void addConferenceInfo(PojoConferenceParticipant participant) {
this.participantList.add(participant);
}
}
@@ -0,0 +1,14 @@
package cn.wildfirechat.pojos;
public class PojoConferenceRoomId {
public String roomId;
public boolean advance;
public PojoConferenceRoomId() {
}
public PojoConferenceRoomId(String roomId, boolean advance) {
this.roomId = roomId;
this.advance = advance;
}
}
@@ -185,6 +185,7 @@ public class ProtoConstants {
int Group_Member_Event_Kickoff = 2;
int Group_Member_Event_Type_Update = 3;
int Group_Member_Event_Alias = 4;
int Group_Member_Event_Extra = 5;
}
public interface ChannelUpdateEventType {
@@ -220,7 +221,6 @@ public class ProtoConstants {
int Update_User_Name = 0x200;
}
public static final int MESSAGE_CONTENT_TYPE_CREATE_GROUP = 104;
public static final int MESSAGE_CONTENT_TYPE_ADD_GROUP_MEMBER = 105;
public static final int MESSAGE_CONTENT_TYPE_KICKOF_GROUP_MEMBER = 106;
@@ -241,7 +241,8 @@ public class ProtoConstants {
public static final int MESSAGE_CONTENT_TYPE_ALLOW_MEMBER = 119;
public static final int MESSAGE_CONTENT_TYPE_KICKOF_GROUP_MEMBER_VISIBLE = 120;
public static final int MESSAGE_CONTENT_TYPE_QUIT_GROUP_VISIBLE = 121;
public static final int MESSAGE_CONTENT_TYPE_MODIFY_GROUP_EXTRA = 122;
public static final int MESSAGE_CONTENT_TYPE_MODIFY_GROUP_MEMBER_EXTRA = 123;
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,7 +6,7 @@
<!--<relativePath>../pom.xml</relativePath>-->
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.64</version>
<version>0.70</version>
</parent>
<artifactId>distribution</artifactId>
@@ -9,6 +9,10 @@
</join>
</network>
<properties>
<property name="hazelcast.logging.type">slf4j</property>
</properties>
<!-- map eviction -->
<!-- http://docs.hazelcast.org/docs/latest-development/manual/html/Distributed_Data_Structures/Map/Map_Eviction.html -->
<map name="messages_map">
@@ -7,13 +7,13 @@
#*********************************************************************
#服务器的接入IP。给客户端提供是${server.ip}和${http_port}。
#客户端会从${http_port}端口获取到长链接端口。这个地址一定要改成客户端可以访问到的IP地址
# (如果您部署云服务器上或者具有独立公网出口的服务器上,请改为对应的公网IP;如果您部署在在内网环境下,在内网使用,这个地方改成内网地址)
#(如果您部署云服务器上或者具有独立公网出口的服务器上,请改为对应的公网IP;如果您部署在在内网环境下,在内网使用,这个地方改成内网地址)
server.ip 0.0.0.0
##原生客户端长链接端口。如果使用4层的反向代理或者类似组件,需要设置长链接保持时间为10分钟。
port 1883
##客户端短链接端口
##客户端短链接端口,客户端固定使用80端口,不要修改此端口。
http_port 80
#管理端口
@@ -28,15 +28,15 @@ host 0.0.0.0
##本地绑定端口
local_port 80
##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2
##是否使用内置DB。0使用mysql;1使用h2db。
embed.db 1
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
## 如果不开启自动清理,需要手动清理t_messages_x和t_user_messages_x表内的历史数据,保存数据不能超过3年。
## 使用mongodb时次开关无效(因为mongodb设置了消息过期时间,会自动清理)。
## 使用mongodb时次开关无效(因为mongodb设置了消息过期时间,会自动清理,仅专业版支持mongodb)。
db.auto_clean_history_messages true
##服务器管理接口密钥
##服务器管理接口密钥。如果修改此端口需要同步修改使用管理API的地方,比如应用服务。
http.admin.secret_key 123456
##服务器API接口参数是否检查时间。当设置为false时,所有的请求会检查时间的有效性;当设置为true时,可以在http.admin.secret_key保持不变的情况下,使用固定的服务API签名
@@ -69,14 +69,21 @@ message.blacklist.strategy 0
##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段
message.disable_remote_search false
##允许客户端撤回用户自己发送的消息时限,单位是秒。群组管理员或群主撤回群成员消息、server api不受此限制,可以撤回任意时限内的消息
##是否数据库中加密消息内容。注意这个开关在服务运行起来后不能改变了,避免读取数据库时无法恢复历史消息。
##如果要避免数据库中明文存储消息内容,请打开这个开关和message.disable_remote_search开关
message.encrypt_message_content false
##允许客户端撤回用户自己发送的消息时限,单位是秒。
##Server API不受此限制,可以撤回任意时限内的消息
##群组管理员或群主撤回群成员消息不受此限制,可以撤回任意时限内的消息。但管理员或群主撤回自己的消息还是需要准守此时间限制。
##修改此参数需要同步修改客户端UI,客户端UI代码有判断撤回是否显示的逻辑。
message.recall_time_limit 120
##禁止群主/群管理员撤回群内消息,关闭时群主/群管理员可以撤回任意时间段内群内成员的消息,群主/群管理员撤回自己发送的消息还是会受到message.recall_time_limit时间限制。
##禁止群主/群管理员撤回群内消息,关闭时群主/群管理员可以撤回任意时间段内群内成员的消息。
message.disable_group_manager_recall false
## 禁止客户端发送消息类型,消息类型以逗号分开,下面3个值为示例,可以删除。
## 一般用于重要类型消息,比如交易、充值等,禁止客户端发送,仅限于服务器发送,提高安全性。
##禁止客户端发送消息类型,消息类型以逗号分开,下面3个值为示例,可以删除。
##一般用于重要类型消息,比如交易、充值等,禁止客户端发送,仅限于服务器发送,提高安全性。
#message.forbidden_client_send_types 3999,4000,4001
## 当禁止发送消息时,允许例外发送的消息。这种一般用户需要被动回应的消息。比如群中被禁言的用户,他无法主动发起音视频,但可以接听未被禁言用户的音视频
@@ -108,7 +115,7 @@ friend.request_expiration_duration 604800000
##添加好友后会发送欢迎消息,比如"你们已经是好友了,可以聊天了"。这个开关控制是用旧的方式还是用新的方式。
##旧的方式会发送notification消息(contenttype是80),内容会根据好友接收者的语言选择对应的语言,如果双方语言不一致会导致另外一方看到的不是本地语言。
##新的方式会发送添加好友消息(contenttype是93)和欢迎消息(contenttype是92),需要客户端实现这两种消息。
##如果客户端已经实现这两种消息可以打开这个开关
##如果客户端已经实现这两种消息可以打开这个开关(客户端2020.6.30添加了此消息类型)。
friend.new_welcome_message true
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
@@ -117,6 +124,9 @@ chatroom.participant_idle_time 900000
## 用户向聊天室发送消息,自动加入聊天室
chatroom.rejoin_when_active true
## 当一个聊天室不存在时,如果有用户加入就自动创建
chatroom.create_when_not_exist true
## 是否允许客户端发送操作群的自定义群通知消息
group.allow_client_custom_operation_notification true
@@ -130,6 +140,10 @@ group.visible_quit_or_kickoff_notification 0
## 注意,修改本配置不会对已经同步的信息产生影响。
#user.hide_properties 3,4
# 好友/好友请求/用户设置 这三类数据同步的最大条目数。之前是客户第一次登录时,会把所有的对应数据一次下载到客户端,但如果有特别多的信息,会导致无法同步到客户端,
# 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。
#sync.data_part_size 1000
#*********************************************************************
# hazelcase configuration
#*********************************************************************
@@ -139,7 +153,7 @@ hazelcast.configuration config/hazelcast.xml
# Media server configuration
#*********************************************************************
##是否使用七牛云存储。1使用七牛;0使用内存文件服务器。默认的七牛账户信息不可用,请在七牛官网申请账户并配置
## https://docs.wildfirechat.cn/server/media_server.html
##配置使用七牛请参考:https://docs.wildfirechat.cn/server/media_server.html
media.server.use_qiniu 0
##媒体类型分类
@@ -186,11 +200,17 @@ local.media.storage.root ./media
# 尽管内置文件存储可以使用,但是我们还是建议使用专业级别的对象存储服务,社区版可以使用七牛,专业版另外支持阿里云和也是私有对象存储。详情请参考 https://docs.wildfirechat.cn/server/oss.html
# local.media.storage.remote_server_url https://example.com/media
# 是否支持多端登陆,为true时支持任意平台任意多个客户端同时登录;为false时每个平台只支持一个端登录,但不同平台可以同时登录。
# 是否支持任意多端登陆,为true时支持任意平台任意多个客户端同时登录;为false时每个平台只支持一个端登录,但不同平台可以同时登录。
# Android/iOS为移动平台,windows/mac/linux为pc平台,web为web平台,小程序为小程序平台。
# 建议使用false
server.multi_endpoint false
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
server.multi_platform_notification false
server.multi_platform_notification true
# 当pc或者web在线时,手机是否默认静音,默认为true。注意仅影响默认值,用户可以手动切换是否静音。
# 如果这里改为false,客户端那边需要同步修改pc在线默认通知状态,方法是client的setDefaultSilentWhenPcOnline函数。
server.mobile_default_silent_when_pc_online true
#*********************************************************************
# Push server configuration
@@ -207,6 +227,8 @@ push.ios.server.address http://localhost:8085/ios/push
#*********************************************************************
# 监控配置
#*********************************************************************
##异常事件产生回调
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#monitor.exception_event_address http://localhost:8888/im_exception_event/
#*********************************************************************
@@ -276,7 +298,7 @@ sensitive.filter.type 0
#sensitive.remote_server_url http://192.168.3.202:8888/message/censor
## 需要进行敏感词审核的消息类型,当有多个时以英文逗号分割
#sensitive.remote_sensitive_message_type 1,2,3
## 如果远程审核服务返回403,返回给发送端发送失败还是成功?实际上这个值影响发送响应是否等待审核结果,当为false时,消息发送给审核服务就立即返回
## 成功给客户端。当为true时,消息发送给审核服务,等待审核结果,如果结果为继续发送就返回给客户端为成功,结果为禁止发送就返回失败给客户端。
## 如果远程审核服务返回403,返回给发送端发送失败还是成功?实际上这个值影响发送响应是否等待审核结果,当为false时,消息发送给审核服务就立即返回成功给客户端。
## 当为true时,消息发送给审核服务,等待审核结果,如果结果为继续发送就返回给客户端为成功,结果为禁止发送就返回失败给客户端。
## 客户端操作的超时一般为10s左右,且考虑到复杂的网络情况,建议处理时间不要超过3s。建议这个值为false。
#sensitive.remote_fail_when_matched false
+10 -8
View File
@@ -72,18 +72,20 @@ JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=500"
### GC logging options -- uncomment to enable
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails"
#JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails"
#JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDateStamps"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintHeapAtGC"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintTenuringDistribution"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCApplicationStoppedTime"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintPromotionFailure"
#JAVA_OPTS="$JAVA_OPTS -XX:+PrintHeapAtGC"
#JAVA_OPTS="$JAVA_OPTS -XX:+PrintTenuringDistribution"
#JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCApplicationStoppedTime"
#JAVA_OPTS="$JAVA_OPTS -XX:+PrintPromotionFailure"
#JAVA_OPTS="$JAVA_OPTS -XX:PrintFLSStatistics=1"
JAVA_OPTS="$JAVA_OPTS -XX:+UseGCLogFileRotation"
JAVA_OPTS="$JAVA_OPTS -XX:NumberOfGCLogFiles=10"
JAVA_OPTS="$JAVA_OPTS -XX:GCLogFileSize=10M"
#JAVA_OPTS="$JAVA_OPTS -XX:+UseGCLogFileRotation"
#JAVA_OPTS="$JAVA_OPTS -XX:NumberOfGCLogFiles=10"
#JAVA_OPTS="$JAVA_OPTS -XX:GCLogFileSize=10M"
echo ""
echo "请设置JVM参数Xmx和Xms!!!"
echo ""
#JAVA_OPTS="$JAVA_OPTS -Xmx2G"
#JAVA_OPTS="$JAVA_OPTS -Xms2G"
+1 -1
View File
@@ -12,7 +12,7 @@
<artifactId>wildfirechat-parent</artifactId>
<packaging>pom</packaging>
<version>0.64</version>
<version>0.70</version>
<name>Wildfire Chat</name>
<description>Wildfire Chat Server</description>
<inceptionYear>2019</inceptionYear>
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.64</version>
<version>0.70</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -67,7 +67,7 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
<version>4.5.13</version>
</dependency>
<dependency>
@@ -0,0 +1,9 @@
package cn.wildfirechat.sdk;
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
public class AdminConfig {
public static void initAdmin(String url, String secret) {
AdminHttpUtils.init(url, secret);
}
}
@@ -9,7 +9,7 @@ import java.util.List;
//仅专业版支持,社区版不支持
public class ChannelServiceApi {
private ChannelHttpUtils httpUtils;
private final ChannelHttpUtils httpUtils;
public ChannelServiceApi(String imurl, String channelId, String secret) {
httpUtils = new ChannelHttpUtils(imurl, channelId, secret);
@@ -1,15 +0,0 @@
package cn.wildfirechat.sdk;
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
import cn.wildfirechat.sdk.utilities.ChannelHttpUtils;
import cn.wildfirechat.sdk.utilities.RobotHttpUtils;
public class ChatConfig {
public static void initAdmin(String url, String secret) {
AdminHttpUtils.init(url, secret);
}
public static void initRobot(String url, String robotId, String secret) {
RobotHttpUtils.init(url, robotId, secret);
}
}
@@ -0,0 +1,38 @@
package cn.wildfirechat.sdk;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.pojos.*;
import cn.wildfirechat.sdk.model.IMResult;
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
public class ConferenceAdmin {
public static IMResult<PojoConferenceInfoList> listConferences() throws Exception {
String path = APIPath.Conference_List;
return AdminHttpUtils.httpJsonPost(path, null, PojoConferenceInfoList.class);
}
public static IMResult<PojoConferenceParticipantList> listParticipants(String roomId, boolean advance) throws Exception {
String path = APIPath.Conference_List_Participant;
PojoConferenceRoomId data = new PojoConferenceRoomId(roomId, advance);
return AdminHttpUtils.httpJsonPost(path, data, PojoConferenceParticipantList.class);
}
public static IMResult<Void> createRoom(String roomId, String description, String pin, int maxPublisher, boolean advance, int bitrate, boolean recording) throws Exception {
String path = APIPath.Conference_Create;
PojoConferenceCreate create = new PojoConferenceCreate();
create.roomId = roomId;
create.description = description;
create.pin = pin;
create.max_publishers = maxPublisher;
create.advance = advance;
create.bitrate = bitrate;
create.recording = recording;
return AdminHttpUtils.httpJsonPost(path, create, Void.class);
}
public static IMResult<Void> destroy(String roomId, boolean advance) throws Exception {
String path = APIPath.Conference_Destroy;
PojoConferenceRoomId conferenceRoomId = new PojoConferenceRoomId(roomId, advance);
return AdminHttpUtils.httpJsonPost(path, conferenceRoomId, Void.class);
}
}
@@ -45,7 +45,7 @@ public class GeneralAdmin {
}
private static IMResult<UserSettingPojo> getUserSetting(String userId, int scope, String key) throws Exception {
public static IMResult<UserSettingPojo> getUserSetting(String userId, int scope, String key) throws Exception {
String path = APIPath.User_Get_Setting;
UserSettingPojo pojo = new UserSettingPojo();
pojo.setUserId(userId);
@@ -54,7 +54,7 @@ public class GeneralAdmin {
return AdminHttpUtils.httpJsonPost(path, pojo, UserSettingPojo.class);
}
private static IMResult<Void> setUserSetting(String userId, int scope, String key, String value) throws Exception {
public static IMResult<Void> setUserSetting(String userId, int scope, String key, String value) throws Exception {
String path = APIPath.User_Put_Setting;
UserSettingPojo pojo = new UserSettingPojo();
pojo.setUserId(userId);
@@ -63,4 +63,8 @@ public class GeneralAdmin {
pojo.setValue(value);
return AdminHttpUtils.httpJsonPost(path, pojo, Void.class);
}
public static IMResult<HealthCheckResult> healthCheck() throws Exception {
return AdminHttpUtils.httpGet(APIPath.Health, HealthCheckResult.class);
}
}
@@ -5,7 +5,6 @@ import cn.wildfirechat.pojos.*;
import cn.wildfirechat.sdk.model.IMResult;
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
import java.util.ArrayList;
import java.util.List;
public class GroupAdmin {
@@ -152,6 +151,18 @@ public class GroupAdmin {
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
}
public static IMResult<Void> setGroupMemberExtra(String operator, String groupId, String memberId, String extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Group_Set_Member_Extra;
InputSetGroupMemberExtra input = new InputSetGroupMemberExtra();
input.setGroup_id(groupId);
input.setOperator(operator);
input.setMemberId(memberId);
input.setExtra(extra);
input.setTo_lines(to_lines);
input.setNotify_message(notify_message);
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
}
public static IMResult<OutputGroupIds> getUserGroups(String user) throws Exception {
String path = APIPath.Get_User_Groups;
InputUserId inputUserId = new InputUserId();
+139 -31
View File
@@ -32,7 +32,7 @@ public class Main {
static void testAdmin() throws Exception {
//初始化服务API
AdminHttpUtils.init("http://localhost:18080", "123456");
AdminConfig.initAdmin("http://localhost:18080", "123456");
testUser();
testUserRelation();
@@ -43,9 +43,9 @@ public class Main {
testSensitiveApi();
if (commercialServer) {
testDevice();
testConference();
}
System.out.println("Congratulation, all admin test case passed!!!!!!!");
}
@@ -133,7 +133,6 @@ public class Main {
System.out.println("get user info by userId failure");
System.exit(-1);
}
InputOutputUserInfo updateUserInfo = new InputOutputUserInfo();
updateUserInfo.setUserId(System.currentTimeMillis()+"");
updateUserInfo.setDisplayName("updatedUserName");
@@ -382,6 +381,15 @@ public class Main {
System.exit(-1);
}
String friendExtra = "hello friend extra";
IMResult<Void> setExtraResult = RelationAdmin.updateFriendExtra("ff1", "ff2", friendExtra);
if (setExtraResult != null && setExtraResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("set friend extra success");
} else {
System.out.println("set friend extra failure");
System.exit(-1);
}
IMResult<RelationPojo> getRelation = RelationAdmin.getRelation("ff1", "ff2");
if (getRelation != null && getRelation.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get friend relation success");
@@ -389,6 +397,11 @@ public class Main {
System.out.println("get friend relation failure");
System.exit(-1);
}
if(!friendExtra.equals(getRelation.getResult().extra)) {
System.out.println("set friend extra failure");
System.exit(-1);
}
}
//***********************************************
//**** 群组相关功能
@@ -456,6 +469,13 @@ public class Main {
System.exit(-1);
}
voidIMResult = GroupAdmin.modifyGroupInfo(groupInfo.getOwner(), groupInfo.getTarget_id(), ProtoConstants.ModifyGroupInfoType.Modify_Group_Extra,"HelloWorld2", null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("modify group extra success");
} else {
System.out.println("modify group extra failure");
System.exit(-1);
}
resultGetGroupInfo = GroupAdmin.getGroupInfo(groupInfo.getTarget_id());
if (resultGetGroupInfo != null && resultGetGroupInfo.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
@@ -506,6 +526,14 @@ public class Main {
System.exit(-1);
}
voidIMResult = GroupAdmin.setGroupMemberExtra(groupInfo.getOwner(), groupInfo.getTarget_id(), groupInfo.getOwner(), "hello member extra2", null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("set group member extra success");
} else {
System.out.println("set group member extra failure");
System.exit(-1);
}
if(commercialServer) {
voidIMResult = GroupAdmin.setGroupManager("user1", groupInfo.getTarget_id(), Arrays.asList("user4", "user5"), true, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
@@ -693,6 +721,14 @@ public class Main {
System.out.println("create channel failure");
System.exit(-1);
}
IMResult<HealthCheckResult> health = GeneralAdmin.healthCheck();
if(health != null && health.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println(health.result);
} else {
System.out.println("health check failure");
System.exit(-1);
}
}
static void testChatroom() throws Exception {
@@ -853,13 +889,14 @@ public class Main {
static void testRobot() throws Exception {
//初始化机器人API,注意端口是80,不是18080
String robotId = "robot1";
RobotHttpUtils.init("http://localhost", robotId, "123456");
RobotService robotService = new RobotService("http://localhost", robotId, "123456");
//***********************************************
//**** 机器人API
//***********************************************
IMResult<InputOutputUserInfo> userInfoIMResult = RobotService.getProfile(robotId);
IMResult<InputOutputUserInfo> userInfoIMResult = robotService.getProfile(robotId);
if(userInfoIMResult != null && userInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get profile success");
} else {
@@ -868,14 +905,14 @@ public class Main {
}
String displayName = "testrobot"+System.currentTimeMillis();
IMResult<Void> voidIMResult1 = RobotService.updateProfile(Modify_DisplayName, displayName);
IMResult<Void> voidIMResult1 = robotService.updateProfile(Modify_DisplayName, displayName);
if(voidIMResult1 != null && voidIMResult1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("modify profile success");
} else {
System.out.println("modify profile failure");
System.exit(-1);
}
userInfoIMResult = RobotService.getProfile(robotId);
userInfoIMResult = robotService.getProfile(robotId);
if(userInfoIMResult != null && userInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && displayName.equals(userInfoIMResult.getResult().getDisplayName())) {
System.out.println("get profile success");
} else {
@@ -884,7 +921,7 @@ public class Main {
}
String robotCallback = "http://hellow123";
voidIMResult1 = RobotService.setCallback(robotCallback);
voidIMResult1 = robotService.setCallback(robotCallback);
if(voidIMResult1 != null && voidIMResult1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("set callback success");
} else {
@@ -892,7 +929,7 @@ public class Main {
System.exit(-1);
}
IMResult<RobotCallbackPojo> callbackPojoIMResult = RobotService.getCallback();
IMResult<RobotCallbackPojo> callbackPojoIMResult = robotService.getCallback();
if(callbackPojoIMResult != null && callbackPojoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && robotCallback.equals(callbackPojoIMResult.getResult().getUrl())) {
System.out.println("get callback success");
} else {
@@ -900,7 +937,7 @@ public class Main {
System.exit(-1);
}
voidIMResult1 = RobotService.deleteCallback();
voidIMResult1 = robotService.deleteCallback();
if(voidIMResult1 != null && voidIMResult1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("delete callback success");
} else {
@@ -908,7 +945,7 @@ public class Main {
System.exit(-1);
}
callbackPojoIMResult = RobotService.getCallback();
callbackPojoIMResult = robotService.getCallback();
if(callbackPojoIMResult != null && callbackPojoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && StringUtil.isNullOrEmpty(callbackPojoIMResult.getResult().getUrl())) {
System.out.println("get callback success");
} else {
@@ -923,7 +960,7 @@ public class Main {
payload.setType(1);
payload.setSearchableContent("hello world");
IMResult<SendMessageResult> resultRobotSendMessage = RobotService.sendMessage("robot1", conversation, payload);
IMResult<SendMessageResult> resultRobotSendMessage = robotService.sendMessage("robot1", conversation, payload);
if (resultRobotSendMessage != null && resultRobotSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("robot send message success");
} else {
@@ -931,7 +968,7 @@ public class Main {
System.exit(-1);
}
IMResult<InputOutputUserInfo> resultRobotGetUserInfo = RobotService.getUserInfo("userId1");
IMResult<InputOutputUserInfo> resultRobotGetUserInfo = robotService.getUserInfo("userId1");
if (resultRobotGetUserInfo != null && resultRobotGetUserInfo.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("robot get user info success");
} else {
@@ -960,7 +997,7 @@ public class Main {
member3.setMember_id("user3");
members.add(member3);
IMResult<OutputCreateGroupResult> resultCreateGroup = RobotService.createGroup(groupInfo, members, null, null);
IMResult<OutputCreateGroupResult> resultCreateGroup = robotService.createGroup(groupInfo, members, null, null);
if (resultCreateGroup != null && resultCreateGroup.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("create group success");
} else {
@@ -968,7 +1005,7 @@ public class Main {
System.exit(-1);
}
IMResult<PojoGroupInfo> resultGetGroupInfo = RobotService.getGroupInfo(groupInfo.getTarget_id());
IMResult<PojoGroupInfo> resultGetGroupInfo = robotService.getGroupInfo(groupInfo.getTarget_id());
if (resultGetGroupInfo != null && resultGetGroupInfo.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
if (groupInfo.getExtra().equals(resultGetGroupInfo.getResult().getExtra())
&& groupInfo.getName().equals(resultGetGroupInfo.getResult().getName())
@@ -983,7 +1020,7 @@ public class Main {
System.exit(-1);
}
IMResult<Void> voidIMResult = RobotService.modifyGroupInfo(groupInfo.getTarget_id(), ProtoConstants.ModifyGroupInfoType.Modify_Group_Name,"HelloWorld", null, null);
IMResult<Void> voidIMResult = robotService.modifyGroupInfo(groupInfo.getTarget_id(), ProtoConstants.ModifyGroupInfoType.Modify_Group_Name,"HelloWorld", null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("modify group success");
} else {
@@ -992,7 +1029,7 @@ public class Main {
}
IMResult<OutputGroupMemberList> resultGetMembers = RobotService.getGroupMembers(groupInfo.getTarget_id());
IMResult<OutputGroupMemberList> resultGetMembers = robotService.getGroupMembers(groupInfo.getTarget_id());
if (resultGetMembers != null && resultGetMembers.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get group member success");
} else {
@@ -1004,7 +1041,7 @@ public class Main {
m.setMember_id("user1");
m.setAlias("hello user1");
voidIMResult = RobotService.addGroupMembers(groupInfo.getTarget_id(), Arrays.asList(m), null, null);
voidIMResult = robotService.addGroupMembers(groupInfo.getTarget_id(), Arrays.asList(m), null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("add group member success");
} else {
@@ -1012,7 +1049,7 @@ public class Main {
System.exit(-1);
}
voidIMResult = RobotService.kickoffGroupMembers(groupInfo.getTarget_id(), Arrays.asList("user3"), null, null);
voidIMResult = robotService.kickoffGroupMembers(groupInfo.getTarget_id(), Arrays.asList("user3"), null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("kickoff group member success");
} else {
@@ -1020,7 +1057,7 @@ public class Main {
System.exit(-1);
}
voidIMResult = RobotService.setGroupMemberAlias(groupInfo.getTarget_id(), "user3", "test user3", null, null);
voidIMResult = robotService.setGroupMemberAlias(groupInfo.getTarget_id(), "user3", "test user3", null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("set group member alias success");
} else {
@@ -1029,7 +1066,7 @@ public class Main {
}
if(commercialServer) {
voidIMResult = RobotService.setGroupManager(groupInfo.getTarget_id(), Arrays.asList("user4", "user5"), true, null, null);
voidIMResult = robotService.setGroupManager(groupInfo.getTarget_id(), Arrays.asList("user4", "user5"), true, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("set group manager success");
} else {
@@ -1037,7 +1074,7 @@ public class Main {
System.exit(-1);
}
voidIMResult = RobotService.setGroupManager(groupInfo.getTarget_id(), Arrays.asList("user4", "user5"), false, null, null);
voidIMResult = robotService.setGroupManager(groupInfo.getTarget_id(), Arrays.asList("user4", "user5"), false, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("cancel group manager success");
} else {
@@ -1051,7 +1088,7 @@ public class Main {
//仅专业版支持
if (commercialServer) {
//开启群成员禁言
voidIMResult = RobotService.muteGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), true, null, null);
voidIMResult = robotService.muteGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), true, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("mute group member success");
} else {
@@ -1059,7 +1096,7 @@ public class Main {
System.exit(-1);
}
//关闭群成员禁言
voidIMResult = RobotService.muteGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), false, null, null);
voidIMResult = robotService.muteGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), false, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("unmute group member success");
} else {
@@ -1068,7 +1105,7 @@ public class Main {
}
//开启群成员白名单,当群全局禁言时,白名单用户可以发言
voidIMResult = RobotService.allowGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), true, null, null);
voidIMResult = robotService.allowGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), true, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("allow group member success");
} else {
@@ -1077,7 +1114,7 @@ public class Main {
}
//关闭群成员白名单
voidIMResult = RobotService.allowGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), false, null, null);
voidIMResult = robotService.allowGroupMember(groupInfo.getTarget_id(), Arrays.asList("user5"), false, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("unallow group member success");
} else {
@@ -1085,7 +1122,7 @@ public class Main {
System.exit(-1);
}
}
voidIMResult = RobotService.transferGroup(groupInfo.getTarget_id(), "user2", null, null);
voidIMResult = robotService.transferGroup(groupInfo.getTarget_id(), "user2", null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("transfer success");
} else {
@@ -1093,7 +1130,7 @@ public class Main {
System.exit(-1);
}
resultGetGroupInfo = RobotService.getGroupInfo(groupInfo.getTarget_id());
resultGetGroupInfo = robotService.getGroupInfo(groupInfo.getTarget_id());
if (resultGetGroupInfo != null && resultGetGroupInfo.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
if ("user2".equals(resultGetGroupInfo.getResult().getOwner())) {
groupInfo.setOwner("user2");
@@ -1106,7 +1143,7 @@ public class Main {
System.exit(-1);
}
voidIMResult = RobotService.quitGroup(groupInfo.getTarget_id(), null, null);
voidIMResult = robotService.quitGroup(groupInfo.getTarget_id(), null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("quit group success");
} else {
@@ -1119,7 +1156,7 @@ public class Main {
//***测试频道API功能,仅专业版支持***
static void testChannel() throws Exception {
//初始化服务API
AdminHttpUtils.init("http://localhost:18080", "123456");
AdminConfig.initAdmin("http://localhost:18080", "123456");
//先创建3个用户
InputOutputUserInfo userInfo = new InputOutputUserInfo();
@@ -1184,6 +1221,8 @@ public class Main {
ChannelServiceApi channelServiceApi = new ChannelServiceApi("http://localhost", resultCreateChannel.getResult().getTargetId(), secret);
if (commercialServer) {
//3. 测试channel api功能
IMResult<Void> resultVoid = channelServiceApi.subscribe("userId2");
if (resultVoid != null && resultVoid.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
@@ -1200,6 +1239,7 @@ public class Main {
System.out.println("subscribe failure");
System.exit(-1);
}
IMResult<OutputStringList> resultStringList = channelServiceApi.getSubscriberList();
if (resultStringList != null && resultStringList.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && resultStringList.getResult().getList().contains("userId2") && resultStringList.getResult().getList().contains("userId3")) {
System.out.println("get subscriber done");
@@ -1231,7 +1271,7 @@ public class Main {
System.out.println("get user info failure");
System.exit(-1);
}
}
MessagePayload payload = new MessagePayload();
@@ -1284,6 +1324,8 @@ public class Main {
System.exit(-1);
}
Thread.sleep(100);
IMResult<InputOutputSensitiveWords> swResult = SensitiveAdmin.getSensitives();
if (swResult != null && swResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && swResult.getResult().getWords().containsAll(words)) {
System.out.println("Sensitive word added");
@@ -1300,6 +1342,7 @@ public class Main {
System.exit(-1);
}
Thread.sleep(100);
swResult = SensitiveAdmin.getSensitives();
if (swResult != null && swResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && !swResult.getResult().getWords().containsAll(words)) {
System.out.println("Sensitive word removed");
@@ -1352,4 +1395,69 @@ public class Main {
System.exit(-1);
}
}
/*
会议相关接口,仅音视频高级版服务支持
*/
public static void testConference() throws Exception {
IMResult<PojoConferenceInfoList> listResult = ConferenceAdmin.listConferences();
if(listResult == null || listResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get conference list failure");
System.exit(-1);
} else {
System.out.println("conference list " + listResult.getResult().conferenceInfoList);
}
for (PojoConferenceInfo conferenceInfo:listResult.getResult().conferenceInfoList) {
IMResult<Void> destroyResult = ConferenceAdmin.destroy(conferenceInfo.roomId, conferenceInfo.advance);
if(destroyResult == null || destroyResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("destroy room failure");
System.exit(-1);
} else {
System.out.println("destroy room success");
}
}
listResult = ConferenceAdmin.listConferences();
if(listResult == null || listResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get conference list failure");
System.exit(-1);
} else {
System.out.println("conference list " + listResult.getResult().conferenceInfoList);
}
IMResult<Void> createResult = ConferenceAdmin.createRoom("helloroomid", "hello room description", "123456", 9, false, 0, false);
if(createResult == null || createResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("create conference failure");
System.exit(-1);
} else {
System.out.println("create conference");
}
createResult = ConferenceAdmin.createRoom("helloroomid2", "hello room description advanced", "123456", 20, true, 0, false);
if(createResult == null || createResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("create conference failure");
System.exit(-1);
} else {
System.out.println("create conference");
}
listResult = ConferenceAdmin.listConferences();
if(listResult == null || listResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get conference list failure");
System.exit(-1);
} else {
System.out.println("conference list " + listResult.getResult().conferenceInfoList);
}
for (PojoConferenceInfo conferenceInfo:listResult.getResult().conferenceInfoList) {
IMResult<PojoConferenceParticipantList> listParticipantsResult = ConferenceAdmin.listParticipants(conferenceInfo.roomId, conferenceInfo.advance);
if(listParticipantsResult == null || listParticipantsResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("list participants failure");
System.exit(-1);
} else {
System.out.println("list participants success");
}
}
}
}
@@ -56,6 +56,14 @@ public class RelationAdmin {
return AdminHttpUtils.httpJsonPost(path, input, OutputGetAlias.class);
}
public static IMResult<Void> updateFriendExtra(String operator, String targetId, String extra) throws Exception {
String path = APIPath.Friend_Set_Extra;
InputUpdateFriendExtra input = new InputUpdateFriendExtra();
input.setOperator(operator);
input.setTargetId(targetId);
input.setExtra(extra);
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
}
public static IMResult<Void> sendFriendRequest(String userId, String targetId, String reason, boolean force) throws Exception {
String path = APIPath.Friend_Send_Request;
InputAddFriendRequest input = new InputAddFriendRequest();
@@ -9,64 +9,70 @@ import cn.wildfirechat.sdk.utilities.RobotHttpUtils;
import java.util.List;
public class RobotService {
public static IMResult<SendMessageResult> sendMessage(String sender, Conversation conversation, MessagePayload payload) throws Exception {
private final RobotHttpUtils robotHttpUtils;
public RobotService(String url, String robotId, String robotSecret) {
robotHttpUtils = new RobotHttpUtils(url, robotId, robotSecret);
}
public IMResult<SendMessageResult> sendMessage(String sender, Conversation conversation, MessagePayload payload) throws Exception {
String path = APIPath.Robot_Message_Send;
SendMessageData messageData = new SendMessageData();
messageData.setSender(sender);
messageData.setConv(conversation);
messageData.setPayload(payload);
return RobotHttpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
return robotHttpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
}
public static IMResult<InputOutputUserInfo> getUserInfo(String userId) throws Exception {
public IMResult<InputOutputUserInfo> getUserInfo(String userId) throws Exception {
String path = APIPath.Robot_User_Info;
InputGetUserInfo getUserInfo = new InputGetUserInfo(userId, null, null);
return RobotHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
return robotHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
}
public static IMResult<InputOutputUserInfo> getUserInfoByMobile(String phone) throws Exception {
public IMResult<InputOutputUserInfo> getUserInfoByMobile(String phone) throws Exception {
String path = APIPath.Robot_User_Info;
InputGetUserInfo getUserInfo = new InputGetUserInfo(null, null, phone);
return RobotHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
return robotHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
}
public static IMResult<InputOutputUserInfo> getUserInfoByName(String userName) throws Exception {
public IMResult<InputOutputUserInfo> getUserInfoByName(String userName) throws Exception {
String path = APIPath.Robot_User_Info;
InputGetUserInfo getUserInfo = new InputGetUserInfo(null, userName, null);
return RobotHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
return robotHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
}
public static IMResult<Void> setCallback(String url) throws Exception {
public IMResult<Void> setCallback(String url) throws Exception {
String path = APIPath.Robot_Set_Callback;
RobotCallbackPojo pojo = new RobotCallbackPojo();
pojo.setUrl(url);
return RobotHttpUtils.httpJsonPost(path, pojo, Void.class);
return robotHttpUtils.httpJsonPost(path, pojo, Void.class);
}
public static IMResult<RobotCallbackPojo> getCallback() throws Exception {
public IMResult<RobotCallbackPojo> getCallback() throws Exception {
String path = APIPath.Robot_Get_Callback;
return RobotHttpUtils.httpJsonPost(path, null, RobotCallbackPojo.class);
return robotHttpUtils.httpJsonPost(path, null, RobotCallbackPojo.class);
}
public static IMResult<Void> deleteCallback() throws Exception {
public IMResult<Void> deleteCallback() throws Exception {
String path = APIPath.Robot_Delete_Callback;
return RobotHttpUtils.httpJsonPost(path, null, Void.class);
return robotHttpUtils.httpJsonPost(path, null, Void.class);
}
public static IMResult<InputOutputUserInfo> getProfile(String robotId) throws Exception {
public IMResult<InputOutputUserInfo> getProfile(String robotId) throws Exception {
return getUserInfo(robotId);
}
/*
type可选范围为MyInfoType,注意不能修改电话号码,如果要修改电话号码请使用adminapi进行修改
*/
public static IMResult<Void> updateProfile(int/*MyInfoType*/ type, String value) throws Exception {
public IMResult<Void> updateProfile(int/*MyInfoType*/ type, String value) throws Exception {
String path = APIPath.Robot_Update_Profile;
IntStringPairPojo pojo = new IntStringPairPojo(type, value);
return RobotHttpUtils.httpJsonPost(path, pojo, Void.class);
return robotHttpUtils.httpJsonPost(path, pojo, Void.class);
}
public static IMResult<OutputCreateGroupResult> createGroup(PojoGroupInfo group_info, List<PojoGroupMember> members, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<OutputCreateGroupResult> createGroup(PojoGroupInfo group_info, List<PojoGroupMember> members, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Create_Group;
PojoGroup pojoGroup = new PojoGroup();
pojoGroup.setGroup_info(group_info);
@@ -76,37 +82,37 @@ public class RobotService {
createGroup.setTo_lines(to_lines);
createGroup.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, createGroup, OutputCreateGroupResult.class);
return robotHttpUtils.httpJsonPost(path, createGroup, OutputCreateGroupResult.class);
}
public static IMResult<PojoGroupInfo> getGroupInfo(String groupId) throws Exception {
public IMResult<PojoGroupInfo> getGroupInfo(String groupId) throws Exception {
String path = APIPath.Robot_Group_Get_Info;
InputGetGroup input = new InputGetGroup();
input.setGroupId(groupId);
return RobotHttpUtils.httpJsonPost(path, input, PojoGroupInfo.class);
return robotHttpUtils.httpJsonPost(path, input, PojoGroupInfo.class);
}
public static IMResult<Void> dismissGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> dismissGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Dismiss;
InputDismissGroup dismissGroup = new InputDismissGroup();
dismissGroup.setGroup_id(groupId);
dismissGroup.setTo_lines(to_lines);
dismissGroup.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, dismissGroup, Void.class);
return robotHttpUtils.httpJsonPost(path, dismissGroup, Void.class);
}
public static IMResult<Void> transferGroup(String groupId, String newOwner, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> transferGroup(String groupId, String newOwner, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Transfer;
InputTransferGroup transferGroup = new InputTransferGroup();
transferGroup.setGroup_id(groupId);
transferGroup.setNew_owner(newOwner);
transferGroup.setTo_lines(to_lines);
transferGroup.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, transferGroup, Void.class);
return robotHttpUtils.httpJsonPost(path, transferGroup, Void.class);
}
public static IMResult<Void> modifyGroupInfo(String groupId, /*ModifyGroupInfoType*/int type, String value, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> modifyGroupInfo(String groupId, /*ModifyGroupInfoType*/int type, String value, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Modify_Info;
InputModifyGroupInfo modifyGroupInfo = new InputModifyGroupInfo();
modifyGroupInfo.setGroup_id(groupId);
@@ -114,28 +120,28 @@ public class RobotService {
modifyGroupInfo.setType(type);
modifyGroupInfo.setValue(value);
modifyGroupInfo.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, modifyGroupInfo, Void.class);
return robotHttpUtils.httpJsonPost(path, modifyGroupInfo, Void.class);
}
public static IMResult<OutputGroupMemberList> getGroupMembers(String groupId) throws Exception {
public IMResult<OutputGroupMemberList> getGroupMembers(String groupId) throws Exception {
String path = APIPath.Robot_Group_Member_List;
InputGetGroup input = new InputGetGroup();
input.setGroupId(groupId);
return RobotHttpUtils.httpJsonPost(path, input, OutputGroupMemberList.class);
return robotHttpUtils.httpJsonPost(path, input, OutputGroupMemberList.class);
}
public static IMResult<Void> addGroupMembers(String groupId, List<PojoGroupMember> groupMembers, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> addGroupMembers(String groupId, List<PojoGroupMember> groupMembers, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Member_Add;
InputAddGroupMember addGroupMember = new InputAddGroupMember();
addGroupMember.setGroup_id(groupId);
addGroupMember.setMembers(groupMembers);
addGroupMember.setTo_lines(to_lines);
addGroupMember.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
}
public static IMResult<Void> setGroupManager(String groupId, List<String> groupMemberIds, boolean isManager, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> setGroupManager(String groupId, List<String> groupMemberIds, boolean isManager, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Set_Manager;
InputSetGroupManager addGroupMember = new InputSetGroupManager();
addGroupMember.setGroup_id(groupId);
@@ -143,10 +149,10 @@ public class RobotService {
addGroupMember.setIs_manager(isManager);
addGroupMember.setTo_lines(to_lines);
addGroupMember.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
}
public static IMResult<Void> muteGroupMember(String groupId, List<String> groupMemberIds, boolean isMute, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> muteGroupMember(String groupId, List<String> groupMemberIds, boolean isMute, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Mute_Member;
InputMuteGroupMember addGroupMember = new InputMuteGroupMember();
addGroupMember.setGroup_id(groupId);
@@ -154,10 +160,10 @@ public class RobotService {
addGroupMember.setIs_manager(isMute);
addGroupMember.setTo_lines(to_lines);
addGroupMember.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
}
public static IMResult<Void> allowGroupMember(String groupId, List<String> groupMemberIds, boolean isAllow, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> allowGroupMember(String groupId, List<String> groupMemberIds, boolean isAllow, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Allow_Member;
InputMuteGroupMember addGroupMember = new InputMuteGroupMember();
addGroupMember.setGroup_id(groupId);
@@ -165,29 +171,29 @@ public class RobotService {
addGroupMember.setIs_manager(isAllow);
addGroupMember.setTo_lines(to_lines);
addGroupMember.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
}
public static IMResult<Void> kickoffGroupMembers(String groupId, List<String> groupMemberIds, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> kickoffGroupMembers(String groupId, List<String> groupMemberIds, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Member_Kickoff;
InputKickoffGroupMember kickoffGroupMember = new InputKickoffGroupMember();
kickoffGroupMember.setGroup_id(groupId);
kickoffGroupMember.setMembers(groupMemberIds);
kickoffGroupMember.setTo_lines(to_lines);
kickoffGroupMember.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, kickoffGroupMember, Void.class);
return robotHttpUtils.httpJsonPost(path, kickoffGroupMember, Void.class);
}
public static IMResult<Void> quitGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> quitGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Member_Quit;
InputQuitGroup quitGroup = new InputQuitGroup();
quitGroup.setGroup_id(groupId);
quitGroup.setTo_lines(to_lines);
quitGroup.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, quitGroup, Void.class);
return robotHttpUtils.httpJsonPost(path, quitGroup, Void.class);
}
public static IMResult<Void> setGroupMemberAlias(String groupId, String memberId, String alias, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
public IMResult<Void> setGroupMemberAlias(String groupId, String memberId, String alias, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Set_Member_Alias;
InputSetGroupMemberAlias input = new InputSetGroupMemberAlias();
input.setGroup_id(groupId);
@@ -195,6 +201,17 @@ public class RobotService {
input.setAlias(alias);
input.setTo_lines(to_lines);
input.setNotify_message(notify_message);
return RobotHttpUtils.httpJsonPost(path, input, Void.class);
return robotHttpUtils.httpJsonPost(path, input, Void.class);
}
public IMResult<Void> setGroupMemberExtra(String groupId, String memberId, String extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Robot_Group_Set_Member_Extra;
InputSetGroupMemberExtra input = new InputSetGroupMemberExtra();
input.setGroup_id(groupId);
input.setMemberId(memberId);
input.setExtra(extra);
input.setTo_lines(to_lines);
input.setNotify_message(notify_message);
return robotHttpUtils.httpJsonPost(path, input, Void.class);
}
}
@@ -7,9 +7,12 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,13 +27,62 @@ public class AdminHttpUtils {
private static String adminUrl;
private static String adminSecret;
private static CloseableHttpClient httpClient;
public static void init(String url, String secret) {
adminUrl = url;
adminSecret = secret;
httpClient = HttpClients.createDefault();
}
public static <T> IMResult<T> httpJsonPost(String path, Object object, Class<T> clazz) throws Exception{
public static <T> IMResult<T> httpGet(String path, Class<T> clazz) throws Exception {
if (isNullOrEmpty(adminUrl) || isNullOrEmpty(adminSecret)) {
LOG.error("野火IM Server SDK必须先初始化才能使用,是不是忘记初始化了!!!!");
throw new Exception("SDK没有初始化");
}
if (isNullOrEmpty(path)) {
throw new Exception("路径缺失");
}
HttpGet get = null;
try {
get = new HttpGet(adminUrl + path);
HttpResponse response = httpClient.execute(get);
int statusCode = response.getStatusLine().getStatusCode();
String content = null;
if (response.getEntity().getContentLength() > 0) {
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
StringBuilder sb = new StringBuilder();
String line;
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line).append(NL);
}
in.close();
content = sb.toString();
LOG.info("http request response content: {}", content);
}
if(statusCode != HttpStatus.SC_OK){
LOG.info("Request error: " + statusCode + " error msg:" + content);
throw new Exception("Http request error with code:" + statusCode);
} else {
return fromJsonObject(content, clazz);
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if(get != null) {
get.releaseConnection();
}
}
}
public static <T> IMResult<T> httpJsonPost(String path, Object object, Class<T> clazz) throws Exception {
if (isNullOrEmpty(adminUrl) || isNullOrEmpty(adminSecret)) {
LOG.error("野火IM Server SDK必须先初始化才能使用,是不是忘记初始化了!!!!");
throw new Exception("SDK没有初始化");
@@ -42,15 +94,13 @@ public class AdminHttpUtils {
String url = adminUrl + path;
HttpPost post = null;
try {
HttpClient httpClient = HttpClientBuilder.create().build();
try {
int nonce = (int)(Math.random() * 100000 + 3);
long timestamp = System.currentTimeMillis();
String str = nonce + "|" + adminSecret + "|" + timestamp;
String sign = DigestUtils.sha1Hex(str);
post = new HttpPost(url);
post.setHeader("Content-type", "application/json; charset=utf-8");
post.setHeader("Connection", "Keep-Alive");
@@ -9,7 +9,9 @@ import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,11 +27,13 @@ public class ChannelHttpUtils {
private String imurl;
private String channelId;
private String channelSecret;
private final CloseableHttpClient httpClient;
public ChannelHttpUtils(String imurl, String channelId, String secret) {
this.imurl = imurl;
this.channelId = channelId;
this.channelSecret = secret;
this.httpClient = HttpClients.createDefault();
}
public <T> IMResult<T> httpJsonPost(String path, Object object, Class<T> clazz) throws Exception{
@@ -41,8 +45,6 @@ public class ChannelHttpUtils {
String url = imurl + path;
HttpPost post = null;
try {
HttpClient httpClient = HttpClientBuilder.create().build();
int nonce = (int)(Math.random() * 100000 + 3);
long timestamp = System.currentTimeMillis();
String str = nonce + "|" + channelSecret + "|" + timestamp;
@@ -10,7 +10,9 @@ import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -23,27 +25,28 @@ import java.nio.charset.Charset;
public class RobotHttpUtils {
private static final Logger LOG = LoggerFactory.getLogger(RobotHttpUtils.class);
private static String url;
private static String robotId;
private static String robotSecret;
private final String url;
private final String robotId;
private final String robotSecret;
private final CloseableHttpClient httpClient;
public static void init(String url, String robotId, String secret) {
RobotHttpUtils.url = url;
RobotHttpUtils.robotId = robotId;
RobotHttpUtils.robotSecret = secret;
public RobotHttpUtils(String url, String robotId, String robotSecret) {
this.url = url;
this.robotId = robotId;
this.robotSecret = robotSecret;
this.httpClient = HttpClients.createDefault();
}
public static <T> IMResult<T> httpJsonPost(String path, Object object, Class<T> clazz) throws Exception{
public <T> IMResult<T> httpJsonPost(String path, Object object, Class<T> clazz) throws Exception{
if (isNullOrEmpty(url) || isNullOrEmpty(path)) {
LOG.error("Not init IM SDK correctly. Do you forget init it?");
throw new Exception("SDK url or secret lack!");
}
String url = RobotHttpUtils.url + path;
String url = this.url + path;
HttpPost post = null;
try {
HttpClient httpClient = HttpClientBuilder.create().build();
int nonce = (int)(Math.random() * 100000 + 3);
long timestamp = System.currentTimeMillis();
String str = nonce + "|" + robotSecret + "|" + timestamp;