Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eac6648fc0 | ||
|
|
300f9aa0e6 | ||
|
|
dd40b72ec4 | ||
|
|
556e6ad2a0 | ||
|
|
473ae32f57 | ||
|
|
d57ae2ed58 | ||
|
|
1a6907efd3 | ||
|
|
1624c470d6 | ||
|
|
5ea6eefe67 | ||
|
|
8aebb2537a | ||
|
|
250b0ccebe | ||
|
|
91669c634f | ||
|
|
bf51cb9829 | ||
|
|
baadcac2c6 | ||
|
|
6c69a5ac96 | ||
|
|
eb19ed3301 | ||
|
|
5be7576bb8 | ||
|
|
86d552cd82 | ||
|
|
391f7345c0 | ||
|
|
92fa40f1fd | ||
|
|
3b3c05260c | ||
|
|
4e9cf86302 | ||
|
|
cbb89bbfb5 | ||
|
|
537221b0b4 | ||
|
|
9d23f9c996 | ||
|
|
6a25a83857 | ||
|
|
d0e533ad21 | ||
|
|
cd0e07f32d | ||
|
|
a6869c9072 | ||
|
|
03b3bb2093 | ||
|
|
304192e303 | ||
|
|
9490226757 | ||
|
|
c44062855b | ||
|
|
9d96fe927f | ||
|
|
ef21bd6db3 | ||
|
|
dc0b718083 | ||
|
|
c0703332d6 | ||
|
|
def048836f | ||
|
|
806cd440e3 | ||
|
|
a3f2623d7e | ||
|
|
4bc5fd6bb9 | ||
|
|
be2979c9a9 | ||
|
|
b7a30e1d14 | ||
|
|
beb591fdc5 | ||
|
|
d090244be9 | ||
|
|
22708caaaa | ||
|
|
2b24fb9f44 |
@@ -1,54 +1,66 @@
|
||||
## 野火IM解决方案
|
||||
# 野火IM解决方案
|
||||
野火IM是专业级的即时通讯和实时音视频整体解决方案,由北京野火无限网络科技有限公司维护和支持。
|
||||
|
||||
野火IM是专业级即时通讯和实时音视频整体解决方案,由北京野火无限网络科技有限公司维护和支持。
|
||||
|
||||
主要特性有:私有部署安全可靠,性能强大,功能齐全,全平台支持,开源率高,部署运维简单,二次开发友好,方便与第三方系统对接或者嵌入现有系统中。详细情况请参考[在线文档](https://docs.wildfirechat.cn)。
|
||||
## 功能特性
|
||||
* 极致地硬件利用率,IM服务最低128M内存即可运行,上不封顶。
|
||||
* 协议先进,采用MQTT+Protobuf组合,流量和性能极致优化。
|
||||
* 性能强大,专业版IM服务支持百万在线和集群部署。
|
||||
* 部署运维简单,依赖服务少,稍加配置一键启动。
|
||||
* 安全加密。网络连接AES加密。客户端数据库SqlCipher加密。安全无小事。
|
||||
* 全平台客户端,四端同时在线(移动端,pc端,web端和小程序端),数据和状态多端完美同步。
|
||||
* 支持国产化。支持国产化操作系统、国产化芯片和国产操作系统。支持国密加密。
|
||||
* 客户端使用微信[mars](https://github.com/tencent/mars)连接库,野火IM可能是最适应中国网络国情的即时通讯服务。
|
||||
* 支持加速点加速,即可用于全球应用,也可用于政企内外双网复杂的网络环境。
|
||||
* 支持阅读回执和在线状态功能,适用于办公环境。
|
||||
* 音视频多种解决方案,丰俭由人,可自由选择。
|
||||
* 高级音视频功能强大,支持9人以上的群组视频通话,支持1080P视频,支持会议模式,支持百人以上会议,支持服务器端录制。
|
||||
* 全私有部署,可不依赖任何第三方服务,完全内网部署。
|
||||
* 功能齐全,涵盖所有常见即时通讯功能。另外具有强大的可扩展能力。Demo成熟完善,基本可以做到开箱即用,也可把SDK嵌入其它应用。
|
||||
* 拥有应用开放平台,可以开发和创建自建应用,扩展您的工作台。
|
||||
* API丰富,方便与其它服务系统的对接。
|
||||
* 拥有机器人和频道功能。
|
||||
|
||||
## 野火开源项目
|
||||
主要包括一下项目:
|
||||
|
||||
| [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/) | | |
|
||||
| [GitHub仓库地址(主站)](https://github.com/wildfirechat) | [码云仓库地址(镜像)](https://gitee.com/wfchat) | 说明
|
||||
| ------------------------------------------------------------ | ----------------------------------------------------- | --------------------------------------------------------------------------
|
||||
| [im-server](https://github.com/wildfirechat/im-server) | [im-server](https://gitee.com/wfchat/im-server) | 野火社区版IM服务,野火IM的核心服务,处理所有IM相关业务。 |
|
||||
| [app_server](https://github.com/wildfirechat/app_server) | [app_server](https://gitee.com/wfchat/app_server) | Demo应用服务,模拟客户的应用服登陆处理逻辑及部分二次开发示例。 |
|
||||
| [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) | 推送服务器,可以对接所有的系统厂商推送服务或者第三方推送服务。 |
|
||||
| [wf-minio](https://github.com/wildfirechat/WF-minio) | [wf-minio](https://gitee.com/wfchat/WF-minio) | 私有对象存储服务,用来支持野火IM专业版的文件存储。 |
|
||||
| [wf-janus](https://github.com/wildfirechat/wf-janus ) | [wf-janus](https://gitee.com/wfchat/wf-janus ) | 高级音视频媒体服务。 |
|
||||
| [open-platform](https://github.com/wildfirechat/open-platform) | [open-platform](https://gitee.com/wfchat/open-platform) | 野火开放平台服务。 |
|
||||
| [daily-report](https://github.com/wildfirechat/daily-report) | [daily-report](https://github.com/wildfirechat/daily-report) | 野火开放平台日报 demo服务。 |
|
||||
| [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/vue-pc-chat) | [pc-chat](https://gitee.com/wfchat/vue-pc-chat) | 基于[Electron](https://electronjs.org/)的PC 端,支持Windows、Mac、Linux(包括国产化linux系统和CPU)。 |
|
||||
| [web-chat](https://github.com/wildfirechat/vue-chat) | [web-chat](https://gitee.com/wfchat/vue-chat) | 野火IM Web 端, [体验地址](https://web.wildfirechat.cn) |
|
||||
| [wx-chat](https://github.com/wildfirechat/wx-chat) | [wx-chat](https://gitee.com/wfchat/wx-chat) | 小程序平台的Demo(支持微信、百度、阿里、字节、QQ 等小程序平台) |
|
||||
| [uni-chat](https://github.com/wildfirechat/uni-chat) | [uni-chat](https://gitee.com/wfchat/uni-chat) | UniApp平台移动端应用(使用原生插件) |
|
||||
| [uni-wfc-client](https://github.com/wildfirechat/uni-wfc-client) | [uni-wfc-client](https://gitee.com/wfchat/uni-wfc-client) | UniApp平台原生插件 |
|
||||
| [flutter_imclient](https://github.com/wildfirechat/flutter_imclient) | [flutter_imclient](https://gitee.com/wfchat/flutter_imclient) | Flutter平台原生插件 |
|
||||
| [docs](https://github.com/wildfirechat/docs) | [docs](https://gitee.com/wfchat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明,[在线查看](https://docs.wildfirechat.cn/) |
|
||||
|
||||
## 野火开发文档
|
||||
[在线文档](https://docs.wildfirechat.cn/)
|
||||
|
||||
# server
|
||||
本工程为野火IM 社区版IM服务软件。野火IM作为一个通用的即时通讯解决方案,既可以直接使用,也可以集成到各种应用中。
|
||||
|
||||
|
||||
开发一套IM系统真的很艰辛,请路过的朋友们给点个star,支持我们坚持下去🙏🙏🙏🙏🙏
|
||||
|
||||
### 联系我们
|
||||
|
||||
> 商务合作请优先采用邮箱和我们联系。技术问题请到[野火IM论坛](http://bbs.wildfirechat.cn/)发帖交流
|
||||
|
||||
1. heavyrain.lee 邮箱: heavyrain.lee@wildfirechat.cn 微信:wildfirechat
|
||||
2. imndx 邮箱: imndx@wildfirechat.cn 微信:wfchat
|
||||
|
||||
### 问题交流
|
||||
|
||||
1. 如果大家发现bug,请在GitHub提issue
|
||||
2. 其他问题,请到[野火IM论坛](http://bbs.wildfirechat.cn/)进行交流学习
|
||||
3. 微信公众号
|
||||
|
||||
<img src="http://static.wildfirechat.cn/wx_wfc_qrcode.jpg" width = 50% height = 50% />
|
||||
|
||||
> 强烈建议关注我们的公众号。我们有新版本发布或者有重大更新会通过公众号通知大家,另外我们也会不定期的发布一些关于野火IM的技术介绍。
|
||||
|
||||
#### 体验Demo
|
||||
我们提供了体验demo,请使用微信扫码下载安装体验
|
||||
## 野火Demo
|
||||
请使用微信扫码下载安装体验野火IM移动客户端
|
||||
|
||||

|
||||
|
||||
#### 应用截图
|
||||
Web客户端点击[这里](https://web.wildfirechat.cn)
|
||||
|
||||
PC客户端点[这里](https://github.com/wildfirechat/vue-pc-chat/releases)下载安装。
|
||||
|
||||
小程序客户端请用微信扫码
|
||||
|
||||

|
||||
|
||||
|
||||
## 应用截图
|
||||

|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-message-view.png" width = 50% height = 50% />
|
||||
@@ -71,16 +83,49 @@
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-voip-view.png" width = 50% height = 50% />
|
||||
|
||||
|
||||
## 编译
|
||||
在安装JDK1.8以上及maven的前提下,在命令行中执行```mvn clean compile package```,生成的目标文件在```./distribution/target/distribution-xxxx-bundle-tar.tar.gz```
|
||||
在安装JDK1.8以上及maven的前提下,在命令行中执行```mvn clean package```,生成的目标文件在```./distribution/target/distribution-xxxx-bundle-tar.tar.gz```
|
||||
> 由于使用了一个git的maven插件,如果本地没有git信息就会编译出错,请使用```git clone```的方法下载代码,或者下载压缩包解压后在根目录创建```.git```的空目录。建议用```git clone```的方式下载代码。
|
||||
|
||||
## 配置
|
||||
解压```distribution-xxxx-bundle-tar.tar.gz```,修改解压出来的```config```目录下的```wildfirechat.conf```。修改如下部分:
|
||||
1. 修改```server.ip```为您的服务器的公网IP,或者域名。如果用域名需要做好域名解析。
|
||||
2. 可以阅读配置文件注释和文档,对其它配置项进行调整。
|
||||
|
||||
## 运行
|
||||
在程序目录运行如下命令:
|
||||
```
|
||||
./bin/wildfirechat.sh
|
||||
```
|
||||
|
||||
## 验证
|
||||
1. 在浏览器中输入地址 ```http://${ip}/api/version```可以看到返回一个json文件。
|
||||
2. 部署[应用服务](应用服务),配置和编译[Android客户端](https://github.com/wildfirechat/android-chat)和[iOS客户端](https://github.com/wildfirechat/ios-chat)进行验证。详情可参考[快速开始](https://docs.wildfirechat.cn/quick_start/)。
|
||||
|
||||
## 升级说明
|
||||
1. 从0.42 版本增加了群成员数限制,默认为2000。如果您从之前的版本升级到这个版本或以后,需要注意到群成员数的限制。升级之后超出限制的群不受影响,但不能继续加人,如果您想修改默认值,可以在升级版本之后,修改t_setting表,把默认的大小改为您期望的人数。另外修改t_group表,把已经存在的群组max_member_count改成您期望的,然后重启。
|
||||
2. 0.46和0.47版本升级到0.48及以后版本时,可能会提示flyway migrate 38错误,请执行 [修复脚本](https://github.com/wildfirechat/server/blob/wildfirechat/flyway_repaire_migrate_38.sql) 进行修复。0.46和0.47版本之外的版本不会出现此问题。
|
||||
3. 从0.54之前版本升级到0.54及以后版本时,会提示flyway migrate错误。因为0.54版本删除了sql脚本中默认敏感词的内容,flyway checksum失败。请执行```update flyway_schema_history set checksum = 0 where script = 'V17__add_default_sensitive_word.sql';```来修复。
|
||||
4. 从0.59之前的版本升级到之后的版本执行数据库升级时间比较长,请耐心等待提示运行成功,避免中途中断。
|
||||
|
||||
|
||||
## 联系我们
|
||||
|
||||
商务合作请使用如下邮箱和微信联系:
|
||||
|
||||
邮箱: support@wildfirechat.cn 微信1:wfchat 微信2:wildfirechat
|
||||
|
||||
## 问题交流
|
||||
|
||||
1. 如果大家发现bug,请在GitHub提issue;如果有需求也请给我们提issue。
|
||||
2. 其他问题,请到[野火IM论坛](http://bbs.wildfirechat.cn/)进行交流学习
|
||||
3. 关注我们的公众号。我们有新版本发布或者有重大更新会通过公众号通知大家,另外我们也会不定期的发布一些关于野火IM的技术介绍。
|
||||
|
||||
<img src="http://static.wildfirechat.cn/wx_wfc_qrcode.jpg" width = 50% height = 50% />
|
||||
|
||||
> 我们有研发工程师轮流值班处理issue和论坛,一般简单问题几个小时就会回复一遍,疑难Bug的修改和新需求的开发我们也会尽快解决。
|
||||
|
||||
## 特别感谢
|
||||
1. [moquette](https://github.com/moquette-io/moquette) 本项目是基于此项目二次开发而来,处理MQTT相关业务。
|
||||
2. [loServer](https://github.com/looly/loServer) 本项目使用loServer处理HTTP相关业务。
|
||||
|
||||
@@ -108,7 +108,6 @@ message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
|
||||
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
|
||||
message.no_forward_admin_message false
|
||||
|
||||
|
||||
##禁止搜索用户
|
||||
friend.disable_search false
|
||||
|
||||
@@ -118,13 +117,13 @@ friend.disable_nick_name_search false
|
||||
##禁止发送好友邀请,通过server api添加好友不受此限制(force参数需要为true)
|
||||
friend.disable_friend_request false
|
||||
|
||||
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为不限制
|
||||
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为无限长期限。
|
||||
friend.repeat_request_duration 604800000
|
||||
|
||||
##好友请求被拒绝后再次发送的间隔,单位是毫秒,默认是30天,0为不限制
|
||||
##好友请求被拒绝后再次发送的间隔,单位是毫秒,默认是30天,0为不限制。不能小于friend.repeat_request_duration。
|
||||
friend.reject_request_duration 2592000000
|
||||
|
||||
##好友请求过期时间,单位是毫秒,默认是7天,0为不限制
|
||||
##好友请求过期时间,单位是毫秒,默认是7天,0为无限长期限。
|
||||
friend.request_expiration_duration 604800000
|
||||
|
||||
##添加好友后会发送欢迎消息,比如"你们已经是好友了,可以聊天了"。这个开关控制是用旧的方式还是用新的方式。
|
||||
@@ -157,6 +156,9 @@ group.visible_quit_or_kickoff_notification 0
|
||||
## 注意,修改本配置不会对已经同步的信息产生影响。
|
||||
#user.hide_properties 3,4,5
|
||||
|
||||
## 销毁用户时,用户信息会被清空,deleted字段设置为1,这个开关控制是否保留用户昵称,默认为true。
|
||||
user.keep_display_name_when_destroy true
|
||||
|
||||
# 好友/好友请求/用户设置 这三类数据同步的最大条目数。之前是客户第一次登录时,会把所有的对应数据一次下载到客户端,但如果有特别多的信息,会导致无法同步到客户端,
|
||||
# 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。
|
||||
#sync.data_part_size 1000
|
||||
@@ -235,6 +237,9 @@ local.media.storage.root media
|
||||
# 建议使用false
|
||||
server.multi_endpoint false
|
||||
|
||||
## 是否支持PC多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PC端多端登录。
|
||||
server.multi_pc_endpoint false
|
||||
|
||||
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
|
||||
server.multi_platform_notification true
|
||||
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_secret_chat`;
|
||||
CREATE TABLE `t_secret_chat` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_from` varchar(64) DEFAULT '',
|
||||
`_from_cid` varchar(64) DEFAULT '',
|
||||
`_to` varchar(64) DEFAULT '',
|
||||
`_to_cid` varchar(64) DEFAULT '',
|
||||
`_state` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `secret_chat_uid_index` (`_uid` DESC)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_messages` add INDEX `messages_conv_index` ( `_type`, `_target`, `_line`);
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_channel_listener` add INDEX `channel_mid_index` ( `_mid`);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_secret_chat`;
|
||||
CREATE TABLE `t_secret_chat` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_from` varchar(64) DEFAULT '',
|
||||
`_from_cid` varchar(64) DEFAULT '',
|
||||
`_to` varchar(64) DEFAULT '',
|
||||
`_to_cid` varchar(64) DEFAULT '',
|
||||
`_state` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `secret_chat_uid_index` (`_uid` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_bin;
|
||||
@@ -0,0 +1,37 @@
|
||||
alter table `t_messages` add INDEX `messages_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_0` add INDEX `messages0_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_1` add INDEX `messages1_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_2` add INDEX `messages2_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_3` add INDEX `messages3_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_4` add INDEX `messages4_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_5` add INDEX `messages5_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_6` add INDEX `messages6_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_7` add INDEX `messages7_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_8` add INDEX `messages8_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_9` add INDEX `messages9_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_10` add INDEX `messages10_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_11` add INDEX `messages11_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_12` add INDEX `messages12_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_13` add INDEX `messages13_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_14` add INDEX `messages14_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_15` add INDEX `messages15_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_16` add INDEX `messages16_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_17` add INDEX `messages17_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_18` add INDEX `messages18_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_19` add INDEX `messages19_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_20` add INDEX `messages20_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_21` add INDEX `messages21_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_22` add INDEX `messages22_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_23` add INDEX `messages23_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_24` add INDEX `messages24_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_25` add INDEX `messages25_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_26` add INDEX `messages26_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_27` add INDEX `messages27_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_28` add INDEX `messages28_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_29` add INDEX `messages29_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_30` add INDEX `messages30_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_31` add INDEX `messages31_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_32` add INDEX `messages32_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_33` add INDEX `messages33_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_34` add INDEX `messages34_conv_index` (`_type`, `_target`, `_line`);
|
||||
alter table `t_messages_35` add INDEX `messages35_conv_index` (`_type`, `_target`, `_line`);
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_channel_listener` add INDEX `channel_mid_index` (`_mid`);
|
||||
+4
-4
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.84</version>
|
||||
<version>0.89</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
@@ -27,18 +27,18 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
<!--用于与slf4j保持桥接-->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
<!-- slf4j核心包-->
|
||||
<dependency>
|
||||
|
||||
@@ -34,6 +34,10 @@ abstract public class AdminAction extends Action {
|
||||
SECRET_KEY = secretKey;
|
||||
}
|
||||
|
||||
public static String getSecretKey() {
|
||||
return SECRET_KEY;
|
||||
}
|
||||
|
||||
public static void setNoCheckTime(String noCheckTime) {
|
||||
try {
|
||||
NO_CHECK_TIME = Boolean.parseBoolean(noCheckTime);
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputApplicationGetUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputApplicationUserInfo;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
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;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
@Route(APIPath.User_Application_Get_UserInfo)
|
||||
@HttpMethod("POST")
|
||||
public class ApplicationGetUserInfoAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputApplicationGetUserInfo inputUserToken = getRequestBody(request.getNettyRequest(), InputApplicationGetUserInfo.class);
|
||||
|
||||
RestResult result;
|
||||
if (inputUserToken == null || StringUtil.isNullOrEmpty(inputUserToken.getAuthCode())) {
|
||||
result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
} else {
|
||||
String userId = messagesStore.verifyApplicationAuthCode(inputUserToken.getAuthCode(), "admin", ProtoConstants.ApplicationType.ApplicationType_Admin);
|
||||
if(userId != null) {
|
||||
OutputApplicationUserInfo outputVerifyApplicationUser = new OutputApplicationUserInfo();
|
||||
outputVerifyApplicationUser.setUserId(userId);
|
||||
WFCMessage.User user = messagesStore.getUserInfo(userId);
|
||||
if(user != null) {
|
||||
outputVerifyApplicationUser.setDisplayName(user.getDisplayName());
|
||||
outputVerifyApplicationUser.setPortraitUrl(user.getPortrait());
|
||||
}
|
||||
result = RestResult.ok(outputVerifyApplicationUser);
|
||||
} else {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_TOKEN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.InputMessageUid;
|
||||
import cn.wildfirechat.pojos.OutputMessageData;
|
||||
import cn.wildfirechat.pojos.RecallMessageData;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
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.util.internal.StringUtil;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
@Route(APIPath.Msg_GetOne)
|
||||
@HttpMethod("POST")
|
||||
public class GetMessageAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputMessageUid inputMessageUid = getRequestBody(request.getNettyRequest(), InputMessageUid.class);
|
||||
if (inputMessageUid != null && inputMessageUid.messageUid > 0) {
|
||||
RestResult result;
|
||||
WFCMessage.Message msg = messagesStore.getMessage(inputMessageUid.messageUid);
|
||||
if(msg == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
result = RestResult.ok(OutputMessageData.fromProtoMessage(msg));
|
||||
}
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.InputGetUserInfo;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.InputRobotId;
|
||||
import cn.wildfirechat.pojos.OutputRobot;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
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;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.User_Get_Robot_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetRobotAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputRobotId inputUserId = getRequestBody(request.getNettyRequest(), InputRobotId.class);
|
||||
if (inputUserId != null
|
||||
&& (!StringUtil.isNullOrEmpty(inputUserId.getRobotId()))) {
|
||||
|
||||
WFCMessage.User user = messagesStore.getUserInfo(inputUserId.getRobotId());
|
||||
WFCMessage.Robot robot = messagesStore.getRobot(inputUserId.getRobotId());
|
||||
|
||||
RestResult result;
|
||||
if (user == null || robot == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
OutputRobot outputRobot = new OutputRobot();
|
||||
outputRobot.fromUser(user);
|
||||
outputRobot.fromRobot(robot, true);
|
||||
result = RestResult.ok(outputRobot);
|
||||
}
|
||||
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.channel;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputApplicationGetUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputApplicationUserInfo;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
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.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.Channel_Application_Get_UserInfo)
|
||||
@HttpMethod("POST")
|
||||
public class ApplicationGetUserInfoAction extends ChannelAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputApplicationGetUserInfo inputUserToken = getRequestBody(request.getNettyRequest(), InputApplicationGetUserInfo.class);
|
||||
RestResult result;
|
||||
if (inputUserToken == null || StringUtil.isNullOrEmpty(inputUserToken.getAuthCode())) {
|
||||
result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
} else {
|
||||
String userId = messagesStore.verifyApplicationAuthCode(inputUserToken.getAuthCode(), channelInfo.getTargetId(), ProtoConstants.ApplicationType.ApplicationType_Channel);
|
||||
if(userId != null) {
|
||||
OutputApplicationUserInfo outputVerifyApplicationUser = new OutputApplicationUserInfo();
|
||||
outputVerifyApplicationUser.setUserId(userId);
|
||||
WFCMessage.User user = messagesStore.getUserInfo(userId);
|
||||
if(user != null) {
|
||||
outputVerifyApplicationUser.setDisplayName(user.getDisplayName());
|
||||
outputVerifyApplicationUser.setPortraitUrl(user.getPortrait());
|
||||
}
|
||||
result = RestResult.ok(outputVerifyApplicationUser);
|
||||
} else {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_APPLICATION_TOKEN_ERROR_OR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.InputApplicationGetUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputApplicationUserInfo;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
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.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.Robot_Application_Get_UserInfo)
|
||||
@HttpMethod("POST")
|
||||
public class ApplicationGetUserInfoAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputApplicationGetUserInfo inputUserToken = getRequestBody(request.getNettyRequest(), InputApplicationGetUserInfo.class);
|
||||
RestResult result;
|
||||
if (inputUserToken == null || StringUtil.isNullOrEmpty(inputUserToken.getAuthCode())) {
|
||||
result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
} else {
|
||||
String userId = messagesStore.verifyApplicationAuthCode(inputUserToken.getAuthCode(), robot.getUid(), ProtoConstants.ApplicationType.ApplicationType_Robot);
|
||||
if(userId != null) {
|
||||
OutputApplicationUserInfo outputVerifyApplicationUser = new OutputApplicationUserInfo();
|
||||
outputVerifyApplicationUser.setUserId(userId);
|
||||
WFCMessage.User user = messagesStore.getUserInfo(userId);
|
||||
if(user != null) {
|
||||
outputVerifyApplicationUser.setDisplayName(user.getDisplayName());
|
||||
outputVerifyApplicationUser.setPortraitUrl(user.getPortrait());
|
||||
}
|
||||
result = RestResult.ok(outputVerifyApplicationUser);
|
||||
} else {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_APPLICATION_TOKEN_ERROR_OR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.InputGetUserInfo;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputRobot;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
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;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.Robot_Get_Profile)
|
||||
@HttpMethod("POST")
|
||||
public class GetProfileAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
WFCMessage.User user = messagesStore.getUserInfo(robot.getUid());
|
||||
RestResult result;
|
||||
if (user == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
OutputRobot outputRobot = new OutputRobot();
|
||||
outputRobot.fromUser(user);
|
||||
outputRobot.fromRobot(robot, false);
|
||||
result = RestResult.ok(outputRobot);
|
||||
}
|
||||
setResponseContent(result, response);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,7 @@ public final class BrokerConstants {
|
||||
|
||||
|
||||
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
|
||||
public static final String SERVER_MULTI_PC_ENDPOINT = "server.multi_pc_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 SERVER_CLIENT_SUPPORT_KICKOFF_EVENT = "server.client_support_kickoff_event";
|
||||
@@ -160,6 +161,8 @@ public final class BrokerConstants {
|
||||
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 USER_KEEP_DISPLAY_NAME_WHEN_DESTROY = "user.keep_display_name_when_destroy";
|
||||
|
||||
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";
|
||||
|
||||
@@ -27,8 +27,6 @@ public class ChannelListenMember extends IMHandler<WFCMessage.ListenChannel> {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingListenedChannels).setKey(request.getChannelId()).setValue(request.getListen() > 0 ? "1" : "0").build();
|
||||
mServer.onApiMessage(fromUser, null, modifyUserSettingReq.toByteArray(), 0, fromUser, PutUserSettingTopic, requestSourceType);
|
||||
|
||||
publisher.notifyChannelListenStatusChanged(m_messagesStore.getChannelInfo(request.getChannelId()), fromUser, request.getListen() > 0);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.proto.ProtoConstants;
|
||||
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.ApplicationConfigRequestTopic)
|
||||
public class ConfigApplicationHandler extends IMHandler<WFCMessage.ApplicationConfigRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.ApplicationConfigRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
ErrorCode errorCode = m_messagesStore.configApplication(request.getAppId(), request.getAppType(), request.getTimestamp(), request.getNonce(), request.getSignature());
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,11 +19,11 @@ import static win.liyufan.im.IMTopic.PutUserSettingTopic;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingMyChannels;
|
||||
|
||||
@Handler(value = IMTopic.DestroyChannelInfoTopic)
|
||||
public class DistroyChannelHandler extends GroupHandler<WFCMessage.IDBuf> {
|
||||
public class DestroyChannelHandler extends GroupHandler<WFCMessage.IDBuf> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.IDBuf request, Qos1PublishHandler.IMCallback callback) {
|
||||
boolean isAdmin = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Admin;
|
||||
ErrorCode errorCode = m_messagesStore.distoryChannel(fromUser, request.getId(), isAdmin);
|
||||
ErrorCode errorCode = m_messagesStore.destroyChannel(fromUser, request.getId(), isAdmin);
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingMyChannels).setKey(request.getId()).setValue("0").build();
|
||||
mServer.onApiMessage(fromUser, null, modifyUserSettingReq.toByteArray(), 0, fromUser, PutUserSettingTopic, requestSourceType);
|
||||
@@ -11,9 +11,7 @@ package io.moquette.imhandler;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.moquette.spi.impl.security.TokenAuthenticator;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
@@ -30,7 +28,7 @@ public class DestroyUserHandler extends IMHandler<WFCMessage.IDBuf> {
|
||||
m_messagesStore.clearUserFriend(fromUser);
|
||||
m_messagesStore.clearUserGroups(fromUser);
|
||||
m_messagesStore.clearUserChannels(fromUser);
|
||||
m_messagesStore.destoryUser(fromUser);
|
||||
m_messagesStore.destroyUser(fromUser);
|
||||
|
||||
m_messagesStore.destroyRobot(fromUser);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.proto.ProtoConstants;
|
||||
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.GetApplicationTokenRequestTopic)
|
||||
public class GetApplicationTokenHandler extends IMHandler<WFCMessage.AuthCodeRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.AuthCodeRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
String authCode = m_messagesStore.getApplicationAuthCode(fromUser, request.getTargetId(), request.getType(), request.getHost());
|
||||
if(authCode != null) {
|
||||
byte[] data = WFCMessage.IDBuf.newBuilder().setId(authCode).build().toByteArray();
|
||||
ackPayload.ensureWritable(data.length).writeBytes(data);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class RecallMessageHandler extends IMHandler<WFCMessage.INT64Buf> {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
publish(fromUser, clientID, message, requestSourceType);
|
||||
publish(message.getFromUser(), clientID, message, requestSourceType);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
@@ -994,7 +994,7 @@ public class DatabaseStore {
|
||||
}
|
||||
sb.append(")");
|
||||
|
||||
sb.append(" and _scope = 6 and _key = ?");
|
||||
sb.append(" and _scope in (5,6,26) and _key = ?");
|
||||
|
||||
statement = connection.prepareStatement(sb.toString());
|
||||
int index = 1;
|
||||
@@ -1142,23 +1142,21 @@ public class DatabaseStore {
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
|
||||
StringBuilder sb = new StringBuilder("delete from t_user_setting where _scope in (1,3,5,7) and _uid in (");
|
||||
StringBuilder sb = new StringBuilder("delete from t_user_setting where _scope in (1,3,5,6,7,19) and _uid in (");
|
||||
for (int i = 0; i < users.size(); i++) {
|
||||
sb.append("?");
|
||||
if (i != users.size() - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
sb.append(") and _key like '1-_-");
|
||||
sb.append(groupId);
|
||||
sb.append("'");
|
||||
|
||||
sb.append(") and _key like ?");
|
||||
|
||||
statement = connection.prepareStatement(sb.toString());
|
||||
int index = 1;
|
||||
for (String userId:users) {
|
||||
statement.setString(index++, userId);
|
||||
}
|
||||
statement.setString(index++, "1-_-" + groupId);
|
||||
|
||||
int count = statement.executeUpdate();
|
||||
LOG.info("Update rows {}", count);
|
||||
@@ -3334,6 +3332,57 @@ public class DatabaseStore {
|
||||
});
|
||||
}
|
||||
|
||||
List<String> getUserChannels(String userId) {
|
||||
List<String> out = new ArrayList<>();
|
||||
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _cid from t_channel_listener where _mid = ?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setString(index++, userId);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
String value = rs.getString(1);
|
||||
if (!StringUtil.isNullOrEmpty(value)) {
|
||||
out.add(value);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void clearChannelListener(final String channelId) {
|
||||
LOG.info("Database remove channel {}", channelId);
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "delete from t_channel_listener where _cid=?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
statement.setString(1, channelId);
|
||||
int count = statement.executeUpdate();
|
||||
LOG.info("Update rows {}", count);
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getSensitiveWord() {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.google.gson.Gson;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.hazelcast.core.*;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.action.admin.AdminAction;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import io.moquette.BrokerConstants;
|
||||
@@ -31,14 +32,18 @@ import io.moquette.server.Constants;
|
||||
import io.moquette.server.Server;
|
||||
import io.moquette.spi.IMatchingCondition;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.moquette.spi.impl.security.AES;
|
||||
import io.moquette.spi.security.Tokenor;
|
||||
import io.moquette.spi.impl.subscriptions.Topic;
|
||||
import io.netty.handler.codec.mqtt.MqttVersion;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import win.liyufan.im.*;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -160,6 +165,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private boolean mGroupAllowRobotCustomOperationNotification;
|
||||
private int mGroupVisibleQuitKickoffNotification;
|
||||
private int mSyncDataPartSize = 0;
|
||||
private boolean keepDisplayNameWhenDestroyUser = true;
|
||||
|
||||
private Set<Integer> mUserHideProperties = new HashSet<>();
|
||||
|
||||
@@ -418,6 +424,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
mSyncDataPartSize = Integer.parseInt(server.getConfig().getProperty(SYNC_Data_Part_Size, "0"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
keepDisplayNameWhenDestroyUser = Boolean.parseBoolean(server.getConfig().getProperty(USER_KEEP_DISPLAY_NAME_WHEN_DESTROY, "true"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -435,8 +446,6 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void printMissConfigLog(String config, String defaultValue) {
|
||||
@@ -558,8 +567,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
if (channelInfo != null) {
|
||||
if (channelInfo.getOwner().equals(fromUser)) {
|
||||
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_Channel
|
||||
&& !StringUtil.isNullOrEmpty(channelInfo.getCallback())
|
||||
&& channelInfo.getAutomatic() == 1) {
|
||||
&& channelInfo.getAutomatic() != 0) {
|
||||
LOG.info("Channel api message not send to the owner when automatic");
|
||||
} else {
|
||||
notifyReceivers.add(fromUser);
|
||||
@@ -589,8 +597,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
} else {
|
||||
notifyReceivers.add(fromUser);
|
||||
if (StringUtil.isNullOrEmpty(channelInfo.getCallback()) || channelInfo.getAutomatic() == 0) {
|
||||
if (channelInfo.getAutomatic() == 0) {
|
||||
notifyReceivers.add(channelInfo.getOwner());
|
||||
} else {
|
||||
LOG.info("Channel api message not send to the owner when automatic");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2077,6 +2087,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
if (!canRecall) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
if(message.getContent().getType() == 80) {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("s", message.getFromUser());
|
||||
@@ -2483,25 +2497,41 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destoryUser(String userId) {
|
||||
public void destroyUser(String userId) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
|
||||
WFCMessage.User us = mUserMap.get(userId);
|
||||
if (us != null) {
|
||||
us = WFCMessage.User.newBuilder()
|
||||
.setUid(userId)
|
||||
.setUpdateDt(System.currentTimeMillis())
|
||||
.setName(userId)
|
||||
.setDeleted(1)
|
||||
.clearDisplayName()
|
||||
.clearAddress()
|
||||
.clearCompany()
|
||||
.clearEmail()
|
||||
.clearExtra()
|
||||
.clearMobile()
|
||||
.clearPortrait()
|
||||
.clearSocial()
|
||||
.build();
|
||||
if (keepDisplayNameWhenDestroyUser) {
|
||||
us = WFCMessage.User.newBuilder()
|
||||
.setUid(userId)
|
||||
.setUpdateDt(System.currentTimeMillis())
|
||||
.setName(userId)
|
||||
.setDeleted(1)
|
||||
.clearAddress()
|
||||
.clearCompany()
|
||||
.clearEmail()
|
||||
.clearExtra()
|
||||
.clearMobile()
|
||||
.clearPortrait()
|
||||
.clearSocial()
|
||||
.build();
|
||||
} else {
|
||||
us = WFCMessage.User.newBuilder()
|
||||
.setUid(userId)
|
||||
.setUpdateDt(System.currentTimeMillis())
|
||||
.setName(userId)
|
||||
.setDeleted(1)
|
||||
.clearDisplayName()
|
||||
.clearAddress()
|
||||
.clearCompany()
|
||||
.clearEmail()
|
||||
.clearExtra()
|
||||
.clearMobile()
|
||||
.clearPortrait()
|
||||
.clearSocial()
|
||||
.build();
|
||||
}
|
||||
|
||||
try {
|
||||
databaseStore.updateUser(us);
|
||||
@@ -3275,6 +3305,156 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String ensureSecretLength(String secret) {
|
||||
while ( secret.length() < 16) {
|
||||
secret += "w";
|
||||
secret += secret;
|
||||
}
|
||||
return secret;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getApplicationAuthCode(String fromUser, String applicationId, int type, String host) {
|
||||
String secret = null;
|
||||
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
||||
WFCMessage.Robot robotData = getRobot(applicationId);
|
||||
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||
try {
|
||||
URL url = new URL(robotData.getCallback());
|
||||
if(url.getHost().equals(host)) {
|
||||
secret = robotData.getSecret();
|
||||
} else {
|
||||
LOG.warn("get application auth code error, request host is not the same host with callback host");
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
String errorReason;
|
||||
if(robotData == null) {
|
||||
errorReason = "Robot not exist.";
|
||||
} else if(StringUtil.isNullOrEmpty(robotData.getCallback())) {
|
||||
errorReason = "Robot no callback address";
|
||||
} else {
|
||||
errorReason = "Robot no secret";
|
||||
}
|
||||
LOG.warn("get application auth code error, reason {}", errorReason);
|
||||
}
|
||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
|
||||
if(channelData != null && !StringUtil.isNullOrEmpty(channelData.getCallback()) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
||||
try {
|
||||
URL url = new URL(channelData.getCallback());
|
||||
if(url.getHost().equals(host)) {
|
||||
secret = channelData.getSecret();
|
||||
} else {
|
||||
LOG.warn("get application auth code error, request host is not the same host with callback host");
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
String errorReason;
|
||||
if(channelData == null) {
|
||||
errorReason = "Channel not exist.";
|
||||
} else if(StringUtil.isNullOrEmpty(channelData.getCallback())) {
|
||||
errorReason = "Channel no callback address";
|
||||
} else {
|
||||
errorReason = "Channel no secret";
|
||||
}
|
||||
LOG.warn("get application auth code error, reason {}", errorReason);
|
||||
}
|
||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Admin) {
|
||||
secret = AdminAction.getSecretKey();
|
||||
applicationId = "wfadmin";
|
||||
}
|
||||
|
||||
if(!StringUtil.isNullOrEmpty(secret)) {
|
||||
secret = ensureSecretLength(secret);
|
||||
byte[] token = AES.AESEncrypt(fromUser + "?|?" + System.currentTimeMillis() + "?|?" + applicationId + "?|?" + type, secret);
|
||||
return new String(Base64.getEncoder().encode(token));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String verifyApplicationAuthCode(String authCode, String applicationId, int type) {
|
||||
String secret = null;
|
||||
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
||||
WFCMessage.Robot robotData = getRobot(applicationId);
|
||||
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||
secret = robotData.getSecret();
|
||||
}
|
||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
|
||||
if(channelData != null && !StringUtil.isNullOrEmpty(channelData.getCallback()) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
||||
secret = channelData.getSecret();
|
||||
}
|
||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Admin) {
|
||||
secret = AdminAction.getSecretKey();
|
||||
applicationId = "wfadmin";
|
||||
}
|
||||
|
||||
secret = ensureSecretLength(secret);
|
||||
|
||||
byte[] data = Base64.getDecoder().decode(authCode);
|
||||
data = AES.AESDecrypt(data, secret, true);
|
||||
|
||||
if (data == null || data.length == 0) {
|
||||
return null;
|
||||
} else {
|
||||
String str = new String(data);
|
||||
String[] strArr = str.split("\\?\\|\\?");
|
||||
if (strArr.length == 4) {
|
||||
if (applicationId.equals(strArr[2])) {
|
||||
long timestamp= Long.parseLong(strArr[1]);
|
||||
if(System.currentTimeMillis() - timestamp > 60*1000) {
|
||||
return null;
|
||||
}
|
||||
return strArr[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode configApplication(String appId, int appType, long timestamp, String nonce, String signature) {
|
||||
String secret;
|
||||
if(System.currentTimeMillis()/1000 - timestamp > 300) {
|
||||
return ErrorCode.ERROR_CODE_SIGN_EXPIRED;
|
||||
}
|
||||
|
||||
if(appType == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
||||
WFCMessage.Robot robotData = getRobot(appId);
|
||||
if(robotData != null) {
|
||||
secret = robotData.getSecret();
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
} else if(appType == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelData = getChannelInfo(appId);
|
||||
if(channelData != null) {
|
||||
secret = channelData.getSecret();
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
} else {
|
||||
LOG.error("Config application type only support 0 or 1");
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
String str = nonce + "|" + appId + "|" + timestamp + "|" + secret;
|
||||
String sign = DigestUtils.sha1Hex(str);
|
||||
if(sign.equals(signature)) {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
return ErrorCode.ERROR_CODE_AUTH_FAILURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewFriendWelcomeMessage() {
|
||||
return mFriendNewWelcomeMessage;
|
||||
@@ -3625,7 +3805,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
@Override
|
||||
public void clearUserChannels(String userId) {
|
||||
|
||||
databaseStore.getUserChannels(userId).forEach(s -> listenChannel(userId, s, false));
|
||||
}
|
||||
|
||||
|
||||
@@ -3705,7 +3885,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode distoryChannel(String operator, String channelId, boolean isAdmin) {
|
||||
public ErrorCode destroyChannel(String operator, String channelId, boolean isAdmin) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.ChannelInfo> mIMap = hzInstance.getMap(CHANNELS);
|
||||
|
||||
@@ -3725,6 +3905,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
newInfoBuilder.setStatus(oldInfo.getStatus() | Channel_State_Mask_Deleted);
|
||||
newInfoBuilder.setUpdateDt(System.currentTimeMillis());
|
||||
mIMap.put(channelId, newInfoBuilder.build());
|
||||
databaseStore.clearChannelListener(channelId);
|
||||
hzInstance.getMultiMap(CHANNEL_LISTENERS).remove(channelId);
|
||||
|
||||
callbackChannelInfoUpdateEvent(operator, channelId, Channel_Event_Destroy);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
@@ -3742,18 +3924,18 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
IMap<String, WFCMessage.ChannelInfo> mIMap = hzInstance.getMap(CHANNELS);
|
||||
WFCMessage.ChannelInfo channelInfo = mIMap.get(channelId);
|
||||
if(channelInfo != null && (channelInfo.getStatus() & ProtoConstants.ChannelState.Channel_State_Mask_Private) > 0) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
getChannelListener(channelId);
|
||||
|
||||
if (listen) {
|
||||
listeners.put(channelId, operator);
|
||||
} else {
|
||||
listeners.remove(channelId, operator);
|
||||
try {
|
||||
mWriteLock.lock();
|
||||
databaseStore.updateChannelListener(channelId, operator, listen);
|
||||
listeners.remove(channelId);
|
||||
} finally {
|
||||
mWriteLock.unlock();
|
||||
}
|
||||
databaseStore.updateChannelListener(channelId, operator, listen);
|
||||
|
||||
|
||||
IMHandler.getPublisher().notifyChannelListenStatusChanged(channelInfo, operator, listen);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3762,9 +3944,14 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
MultiMap<String, String> listeners = hzInstance.getMultiMap(CHANNEL_LISTENERS);
|
||||
Collection<String> result = listeners.get(channelId);
|
||||
if (result.isEmpty()) {
|
||||
result = databaseStore.getChannelListener(channelId);
|
||||
for (String userId : result) {
|
||||
listeners.put(channelId, userId);
|
||||
try {
|
||||
mWriteLock.lock();
|
||||
result = databaseStore.getChannelListener(channelId);
|
||||
for (String userId : result) {
|
||||
listeners.put(channelId, userId);
|
||||
}
|
||||
} finally {
|
||||
mWriteLock.unlock();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -3793,12 +3980,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
Collection<String> channelMembers = getChannelListener(channelId);
|
||||
if (channelMembers == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Collection<String> chatroomMembers = getChannelListener(channelId);
|
||||
if (chatroomMembers == null || !chatroomMembers.contains(user)) {
|
||||
if (channelMembers == null || !channelMembers.contains(user)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3824,12 +4006,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
@Override
|
||||
public Collection<String> getChannelSubscriber(String channelId) {
|
||||
MultiMap<String, String> channelMembers = m_Server.getHazelcastInstance().getMultiMap(CHANNEL_LISTENERS);
|
||||
if (channelMembers == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return channelMembers.get(channelId);
|
||||
return getChannelListener(channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,6 +39,7 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MemorySessionStore.class);
|
||||
|
||||
private boolean supportMultiEndpoint = false;
|
||||
private boolean supportMultiPCEndpoint = false;
|
||||
private boolean clientSupportKickoff = false;
|
||||
|
||||
public static class Session implements Comparable<Session>{
|
||||
@@ -287,6 +288,11 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
supportMultiPCEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PC_ENDPOINT, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
clientSupportKickoff = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_CLIENT_SUPPORT_KICKOFF_EVENT, "false"));
|
||||
} catch (Exception e) {
|
||||
@@ -385,7 +391,12 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
}
|
||||
databaseStore.clearMultiUser(username, clientID);
|
||||
|
||||
if (!supportMultiEndpoint && platform > 0) {
|
||||
if (!supportMultiEndpoint
|
||||
&& platform > 0
|
||||
&& !(platform == ProtoConstants.Platform.Platform_Windows && supportMultiPCEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_LINUX && supportMultiPCEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_OSX && supportMultiPCEndpoint)
|
||||
) {
|
||||
databaseStore.clearMultiEndpoint(username, clientID, platform);
|
||||
if (userSessions.get(username) != null) {
|
||||
Iterator<String> it = userSessions.get(username).iterator();
|
||||
@@ -751,10 +762,12 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
public void disableSession(String userId, String clientId) {
|
||||
Session session = sessions.get(clientId);
|
||||
if (session != null && session.getDeleted() == 0 && (userId == null || session.getUsername().equals(userId))) {
|
||||
databaseStore.updateSessionDeleted(session.getUsername(), clientId, 1);
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(session.username);
|
||||
sessionSet.remove(clientId);
|
||||
sessions.remove(clientId);
|
||||
mServer.getProcessor().processOffline(session, true, () -> {
|
||||
databaseStore.updateSessionDeleted(session.getUsername(), clientId, 1);
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(session.username);
|
||||
sessionSet.remove(clientId);
|
||||
sessions.remove(clientId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,23 +785,25 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
return;
|
||||
}
|
||||
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(session.username);
|
||||
sessionSet.remove(clientID);
|
||||
mServer.getProcessor().processOffline(session, true, () -> {
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(session.username);
|
||||
sessionSet.remove(clientID);
|
||||
|
||||
// remove also the messages stored of type QoS1/2
|
||||
LOG.info("Removing stored messages with QoS 1 and 2. ClientId={}", clientID);
|
||||
// remove also the messages stored of type QoS1/2
|
||||
LOG.info("Removing stored messages with QoS 1 and 2. ClientId={}", clientID);
|
||||
|
||||
session.secondPhaseStore.clear();
|
||||
session.outboundFlightMessages.clear();
|
||||
session.inboundFlightMessages.clear();
|
||||
session.secondPhaseStore.clear();
|
||||
session.outboundFlightMessages.clear();
|
||||
session.inboundFlightMessages.clear();
|
||||
|
||||
LOG.info("Wiping existing subscriptions. ClientId={}", clientID);
|
||||
LOG.info("Wiping existing subscriptions. ClientId={}", clientID);
|
||||
|
||||
//remove also the enqueued messages
|
||||
dropQueue(clientID);
|
||||
//remove also the enqueued messages
|
||||
dropQueue(clientID);
|
||||
|
||||
// TODO this missing last step breaks the junit test
|
||||
sessions.remove(clientID);
|
||||
// TODO this missing last step breaks the junit test
|
||||
sessions.remove(clientID);
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public boolean isMultiEndpointSupported() {
|
||||
|
||||
@@ -150,7 +150,7 @@ public interface IMessagesStore {
|
||||
|
||||
ErrorCode updateUserInfo(InputOutputUserInfo userInfo, int flag);
|
||||
void addUserInfo(WFCMessage.User user, String password) throws Exception;
|
||||
void destoryUser(String userId);
|
||||
void destroyUser(String userId);
|
||||
void updateUserInfo(WFCMessage.User user) throws Exception;
|
||||
WFCMessage.User getUserInfo(String userId);
|
||||
WFCMessage.User getUserInfoByName(String name);
|
||||
@@ -193,6 +193,11 @@ public interface IMessagesStore {
|
||||
|
||||
boolean checkChatroomParticipantIdelTime(MemorySessionStore.Session session);
|
||||
|
||||
|
||||
String getApplicationAuthCode(String fromUser, String applicationId, int appType, String host);
|
||||
String verifyApplicationAuthCode(String token, String applicationId, int type);
|
||||
ErrorCode configApplication(String appId, int appType, long timestamp, String nonce, String signature);
|
||||
|
||||
ErrorCode getUserSettings(String userId, long version, WFCMessage.GetUserSettingResult.Builder builder);
|
||||
WFCMessage.UserSettingEntry getUserSetting(String userId, int scope, String key);
|
||||
List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope);
|
||||
@@ -209,7 +214,7 @@ public interface IMessagesStore {
|
||||
void clearUserChannels(String userId);
|
||||
ErrorCode modifyChannelInfo(String operator, String channelId, int modifyType, String value);
|
||||
ErrorCode transferChannel(String operator, String channelId, String newOwner);
|
||||
ErrorCode distoryChannel(String operator, String channelId, boolean isAdmin);
|
||||
ErrorCode destroyChannel(String operator, String channelId, boolean isAdmin);
|
||||
List<WFCMessage.ChannelInfo> searchChannel(String keyword, boolean buzzy, int page);
|
||||
ErrorCode listenChannel(String operator, String channelId, boolean listen);
|
||||
WFCMessage.ChannelInfo getChannelInfo(String channelId);
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.google.gson.Gson;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus;
|
||||
import cn.wildfirechat.pojos.SendMessageData;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import io.moquette.persistence.*;
|
||||
import io.moquette.persistence.MemorySessionStore.Session;
|
||||
@@ -179,7 +178,7 @@ public class MessagesPublisher {
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(SendMessageData.fromProtoMessage(finalMsg), SendMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(OutputMessageData.fromProtoMessage(finalMsg), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -598,7 +597,7 @@ public class MessagesPublisher {
|
||||
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -627,8 +626,8 @@ public class MessagesPublisher {
|
||||
pushContent = "[语音]";
|
||||
} else if(type == ProtoConstants.ContentType.Video) {
|
||||
pushContent = "[视频]";
|
||||
} else if(type == ProtoConstants.ContentType.RichMedia) {
|
||||
pushContent = "[图文]";
|
||||
} else if(type == ProtoConstants.ContentType.Link) {
|
||||
pushContent = "[链接]";
|
||||
} else if(type == ProtoConstants.ContentType.File) {
|
||||
pushContent = "[文件]";
|
||||
} else if(type == ProtoConstants.ContentType.Sticker) {
|
||||
|
||||
@@ -620,15 +620,27 @@ public class ProtocolProcessor {
|
||||
String username = NettyUtils.userName(channel);
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
|
||||
if(session != null) {
|
||||
session.refreshLastActiveTime();
|
||||
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), clearSession ? UserOnlineStatus.LOGOUT : UserOnlineStatus.OFFLINE, session.getAppName());
|
||||
processOffline(session, clearSession, () -> {
|
||||
ConnectionDescriptor oldConnDescr = new ConnectionDescriptor(clientID, channel);
|
||||
if(connectionDescriptors.removeConnection(oldConnDescr)) {
|
||||
m_interceptor.notifyClientConnectionLost(clientID, username);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ConnectionDescriptor oldConnDescr = new ConnectionDescriptor(clientID, channel);
|
||||
if(connectionDescriptors.removeConnection(oldConnDescr)) {
|
||||
m_interceptor.notifyClientConnectionLost(clientID, username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConnectionDescriptor oldConnDescr = new ConnectionDescriptor(clientID, channel);
|
||||
if(connectionDescriptors.removeConnection(oldConnDescr)) {
|
||||
m_interceptor.notifyClientConnectionLost(clientID, username);
|
||||
}
|
||||
public void processOffline(MemorySessionStore.Session session, boolean logout, Runnable runnable) {
|
||||
if(session != null) {
|
||||
session.refreshLastActiveTime();
|
||||
forwardOnlineStatusEvent(session.getUsername(), session.getClientID(), session.getPlatform(), logout ? UserOnlineStatus.LOGOUT : UserOnlineStatus.OFFLINE, session.getAppName());
|
||||
if(runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
m_messagesStore.updateUserOnlineSetting(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,14 +165,17 @@ public class Qos1PublishHandler extends QosPublishHandler {
|
||||
if (session != null && session.getUsername().equals(fromUser)) {
|
||||
if (data.length > 7*1024 && session.getMqttVersion().protocolLevel() >= MqttVersion.Wildfire_1.protocolLevel()) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip;
|
||||
GZIPOutputStream gzip = null;
|
||||
try {
|
||||
gzip = new GZIPOutputStream(out);
|
||||
gzip.write(data);
|
||||
gzip.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
} finally {
|
||||
if(gzip != null) {
|
||||
gzip.close();
|
||||
}
|
||||
}
|
||||
data = out.toByteArray();
|
||||
code = (byte)ErrorCode.ERROR_CODE_SUCCESS_GZIPED.code;
|
||||
|
||||
@@ -83,4 +83,7 @@ public interface IMTopic {
|
||||
String KickoffPCClientTopic = "KPCC";
|
||||
|
||||
String ClearSessionTopic = "CST";
|
||||
|
||||
String GetApplicationTokenRequestTopic = "ATR";
|
||||
String ApplicationConfigRequestTopic = "ACR";
|
||||
}
|
||||
|
||||
+8
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.84</version>
|
||||
<version>0.89</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -29,7 +29,13 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<version>2.8.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ public interface APIPath {
|
||||
String User_Get_Token = "/admin/user/get_token";
|
||||
String User_Update_Block_Status = "/admin/user/update_block_status";
|
||||
String User_Get_Info = "/admin/user/get_info";
|
||||
String User_Get_Robot_Info = "/admin/user/get_robot_info";
|
||||
String User_Get_Blocked_List = "/admin/user/get_blocked_list";
|
||||
String User_Check_Block_Status = "/admin/user/check_block_status";
|
||||
String User_Get_Online_Status = "/admin/user/onlinestatus";
|
||||
@@ -34,6 +35,7 @@ public interface APIPath {
|
||||
String User_Kickoff_Client = "/admin/user/kickoff_client";
|
||||
String User_Online_Count = "/admin/user/online_count";
|
||||
String User_Online_List = "/admin/user/online_list";
|
||||
String User_Application_Get_UserInfo = "/admin/user/app_get_user_info";
|
||||
|
||||
String Friend_Update_Status = "/admin/friend/status";
|
||||
String Friend_Get_List = "/admin/friend/list";
|
||||
@@ -50,6 +52,7 @@ public interface APIPath {
|
||||
String Msg_Recall = "/admin/message/recall";
|
||||
String Msg_Delete = "/admin/message/delete";
|
||||
String Msg_Update = "/admin/message/update";
|
||||
String Msg_GetOne = "/admin/message/get_one";
|
||||
String Msg_Broadcast = "/admin/message/broadcast";
|
||||
String Msg_Multicast = "/admin/message/multicast";
|
||||
String Msg_RecallBroadCast = "/admin/message/recall_broadcast";
|
||||
@@ -90,17 +93,16 @@ public interface APIPath {
|
||||
String Channel_Message_Send = "/channel/message/send";
|
||||
String Channel_Subscribe = "/channel/subscribe";
|
||||
String Channel_Subscriber_List = "/channel/subscriber_list";
|
||||
String Channel_Application_Get_UserInfo = "/channel/application/get_user_info";
|
||||
|
||||
String Robot_User_Info = "/robot/user_info";
|
||||
String Robot_Get_Profile = "/robot/profile";
|
||||
String Robot_Message_Send = "/robot/message/send";
|
||||
|
||||
String Robot_Set_Callback = "/robot/set_callback";
|
||||
String Robot_Get_Callback = "/robot/get_callback";
|
||||
String Robot_Delete_Callback = "/robot/delete_callback";
|
||||
String Robot_Update_Profile = "/robot/update_profile";
|
||||
|
||||
String Robot_Verify_Application_User = "/robot/user/verify";
|
||||
|
||||
String Robot_Application_Get_UserInfo = "/robot/application/get_user_info";
|
||||
String Robot_Group_Member_Add = "/robot/group/member/add";
|
||||
String Robot_Group_Allow_Member = "/robot/group/manager/allow";
|
||||
String Robot_Create_Group = "/robot/group/create";
|
||||
|
||||
@@ -28,7 +28,7 @@ public enum ErrorCode {
|
||||
ERROR_CODE_INVALID_MESSAGE(10, "invalid message"),
|
||||
|
||||
//Group error
|
||||
ERROR_CODE_GROUP_ALREADY_EXIST(11, "group aleady exist"),
|
||||
ERROR_CODE_GROUP_ALREADY_EXIST(11, "group already exist"),
|
||||
|
||||
//user error
|
||||
ERROR_CODE_FRIEND_ALREADY_REQUEST(16, "already send request"),
|
||||
@@ -48,6 +48,19 @@ public enum ErrorCode {
|
||||
ERROR_CODE_ROBOT_NO_TOKEN(27, "robot no token"),
|
||||
ERROR_CODE_WS_NOT_CONFIGURED_CORRECTLY(28, "ws not configured correctly"),
|
||||
ERROR_CODE_CONFERENCE_ROOM_NOT_EXIST(60, "conference room not exist"),
|
||||
ERROR_CODE_CONFERENCE_SERVICE_NOT_AVAILABLE(61, "conference service not available"),
|
||||
|
||||
ERROR_CODE_APPLICATION_TOKEN_ERROR_OR_TIMEOUT(70, "application token error or timeout"),
|
||||
|
||||
ERROR_CODE_SECRET_CHAT_ACCEPTED_BY_OTHER_CLIENT(81, "secret chat accepted by other client"),
|
||||
ERROR_CODE_SECRET_CHAT_SESSION_NOT_EXIST(82, "secret chat session not exist"),
|
||||
ERROR_CODE_SECRET_CHAT_NOT_SESSION_CLIENT(83, "not secret chat session client"),
|
||||
ERROR_CODE_SECRET_CHAT_SESSION_NOT_READY(84, "secret chat session not ready"),
|
||||
ERROR_CODE_SECRET_CHAT_SESSION_DESTROYED(85, "secret chat session destroyed"),
|
||||
ERROR_CODE_SECRET_CHAT_MO_DISABLED(86, "origin side disable secret chat"),
|
||||
ERROR_CODE_SECRET_CHAT_MT_DISABLED(87, "target side disable secret chat"),
|
||||
|
||||
ERROR_CODE_FUNCTION_DISABLED(220, "function disabled"),
|
||||
|
||||
ERROR_CODE_CHANNEL_NO_EXIST(236, "channel no exist"),
|
||||
ERROR_CODE_CHANNEL_NO_SECRET(237, "channel no secret"),
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package cn.wildfirechat.messagecontentbuilder;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ArticlesContentBuilder extends MessageContentBuilder{
|
||||
public static class Article {
|
||||
public String id;
|
||||
public String cover;
|
||||
public String title;
|
||||
public String url;
|
||||
public boolean readReport;
|
||||
}
|
||||
public Article topArticle;
|
||||
public List<Article> subArticles;
|
||||
|
||||
public static ArticlesContentBuilder newBuilder(String id, String cover, String title, String url, boolean readReport) {
|
||||
ArticlesContentBuilder builder = new ArticlesContentBuilder();
|
||||
builder.topArticle = new Article();
|
||||
builder.topArticle.id = id;
|
||||
builder.topArticle.cover = cover;
|
||||
builder.topArticle.title = title;
|
||||
builder.topArticle.url = url;
|
||||
builder.topArticle.readReport = readReport;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public ArticlesContentBuilder addSubArticle(String id, String cover, String title, String url, boolean readReport) {
|
||||
Article article = new Article();
|
||||
article.id = id;
|
||||
article.cover = cover;
|
||||
article.title = title;
|
||||
article.url = url;
|
||||
article.readReport = readReport;
|
||||
if(subArticles == null) {
|
||||
subArticles = new ArrayList<>();
|
||||
}
|
||||
subArticles.add(article);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static JSONObject toJSON(Article article) {
|
||||
JSONObject top = new JSONObject();
|
||||
if(!StringUtil.isNullOrEmpty(article.id))
|
||||
top.put("id", article.id);
|
||||
if(!StringUtil.isNullOrEmpty(article.cover))
|
||||
top.put("cover", article.cover);
|
||||
if(!StringUtil.isNullOrEmpty(article.title))
|
||||
top.put("title", article.title);
|
||||
if(!StringUtil.isNullOrEmpty(article.url))
|
||||
top.put("url", article.url);
|
||||
if(article.readReport)
|
||||
top.put("rr", article.readReport);
|
||||
return top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePayload build() {
|
||||
MessagePayload payload = encodeBase();
|
||||
payload.setType(ProtoConstants.ContentType.Articles);
|
||||
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
|
||||
payload.setSearchableContent(topArticle.title);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("top", toJSON(topArticle));
|
||||
if(subArticles != null && !subArticles.isEmpty()) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
subArticles.forEach(article -> jsonArray.add(toJSON(article)));
|
||||
jsonObject.put("subArticles", jsonArray);
|
||||
}
|
||||
|
||||
payload.setBase64edData(Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8)));
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cn.wildfirechat.messagecontentbuilder;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
|
||||
abstract public class MediaMessageContentBuilder extends MessageContentBuilder{
|
||||
private String remoteMediaUrl;
|
||||
|
||||
public MediaMessageContentBuilder remoteMediaUrl(String remoteMediaUrl) {
|
||||
this.remoteMediaUrl = remoteMediaUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MessagePayload encodeBase() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
payload.setRemoteMediaUrl(remoteMediaUrl);
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.wildfirechat.messagecontentbuilder;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MessageContentBuilder {
|
||||
private int mentionedType;
|
||||
private List<String> mentionedTargets;
|
||||
private String extra;
|
||||
public MessageContentBuilder mentionedType(int mentionedType) {
|
||||
this.mentionedType = mentionedType;
|
||||
return this;
|
||||
}
|
||||
public MessageContentBuilder mentionedTargets(List<String> mentionedTargets) {
|
||||
this.mentionedTargets = mentionedTargets;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MessageContentBuilder extra(String extra) {
|
||||
this.extra = extra;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected MessagePayload encodeBase() {
|
||||
MessagePayload payload = new MessagePayload();
|
||||
payload.setMentionedType(mentionedType);
|
||||
payload.setMentionedTarget(mentionedTargets);
|
||||
payload.setExtra(extra);
|
||||
return payload;
|
||||
}
|
||||
abstract public MessagePayload build();
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package cn.wildfirechat.messagecontentbuilder;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
public class RichNotificationContentBuilder extends MessageContentBuilder{
|
||||
private String title;
|
||||
private String desc;
|
||||
private String remark;
|
||||
private JSONArray datas;
|
||||
private String exName;
|
||||
private String exPortrait;
|
||||
private String exUrl;
|
||||
private String appId;
|
||||
|
||||
public static RichNotificationContentBuilder newBuilder(String title, String desc, String exUrl) {
|
||||
RichNotificationContentBuilder builder = new RichNotificationContentBuilder();
|
||||
builder.title = title;
|
||||
builder.desc = desc;
|
||||
builder.exUrl = exUrl;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public RichNotificationContentBuilder remark(String remark) {
|
||||
this.remark = remark;
|
||||
return this;
|
||||
}
|
||||
public RichNotificationContentBuilder exName(String exName) {
|
||||
this.exName = exName;
|
||||
return this;
|
||||
}
|
||||
public RichNotificationContentBuilder exPortrait(String exPortrait) {
|
||||
this.exPortrait = exPortrait;
|
||||
return this;
|
||||
}
|
||||
public RichNotificationContentBuilder appId(String appId) {
|
||||
this.appId = appId;
|
||||
return this;
|
||||
}
|
||||
public RichNotificationContentBuilder addItem(String key, String value) {
|
||||
return addItem(key, value, null);
|
||||
}
|
||||
public RichNotificationContentBuilder addItem(String key, String value, String color) {
|
||||
if(this.datas == null) {
|
||||
this.datas = new JSONArray();
|
||||
}
|
||||
JSONObject item = new JSONObject();
|
||||
item.put("key", key);
|
||||
item.put("value", value == null ? "" : value);
|
||||
if(!StringUtil.isNullOrEmpty(color)) {
|
||||
item.put("color", color);
|
||||
}
|
||||
this.datas.add(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePayload build() {
|
||||
MessagePayload payload = encodeBase();
|
||||
payload.setType(ProtoConstants.ContentType.Rich_Notification);
|
||||
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
|
||||
payload.setPushContent(title);
|
||||
payload.setContent(desc);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if(!StringUtil.isNullOrEmpty(remark))
|
||||
jsonObject.put("remark", remark);
|
||||
if(!StringUtil.isNullOrEmpty(exName))
|
||||
jsonObject.put("exName", exName);
|
||||
if(!StringUtil.isNullOrEmpty(exPortrait))
|
||||
jsonObject.put("exPortrait", exPortrait);
|
||||
if(!StringUtil.isNullOrEmpty(exUrl))
|
||||
jsonObject.put("exUrl", exUrl);
|
||||
if(!StringUtil.isNullOrEmpty(appId))
|
||||
jsonObject.put("appId", appId);
|
||||
if(datas != null && !datas.isEmpty())
|
||||
jsonObject.put("datas", datas);
|
||||
|
||||
payload.setBase64edData(Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8)));
|
||||
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package cn.wildfirechat.messagecontentbuilder;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class SoundMessageContentBuilder extends MediaMessageContentBuilder {
|
||||
private int duration;
|
||||
public static SoundMessageContentBuilder newBuilder(int duration) {
|
||||
SoundMessageContentBuilder builder = new SoundMessageContentBuilder();
|
||||
builder.duration = duration;
|
||||
return builder;
|
||||
}
|
||||
@Override
|
||||
public MessagePayload build() {
|
||||
MessagePayload payload = encodeBase();
|
||||
payload.setType(ProtoConstants.ContentType.Voice);
|
||||
payload.setMediaType(ProtoConstants.MessageMediaType.VOICE);
|
||||
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("duration", duration);
|
||||
payload.setContent(jsonObject.toJSONString());
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package cn.wildfirechat.messagecontentbuilder;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
|
||||
public class TextMessageContentBuilder extends MessageContentBuilder{
|
||||
private String text;
|
||||
public static TextMessageContentBuilder newBuilder(String text) {
|
||||
TextMessageContentBuilder builder = new TextMessageContentBuilder();
|
||||
builder.text = text;
|
||||
return builder;
|
||||
}
|
||||
@Override
|
||||
public MessagePayload build() {
|
||||
MessagePayload payload = encodeBase();
|
||||
payload.setType(ProtoConstants.ContentType.Text);
|
||||
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
|
||||
payload.setSearchableContent(text);
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public class GetOnlineUserResult {
|
||||
public int platform;
|
||||
}
|
||||
|
||||
ArrayList<GetOnlineUserResult.UserClient> userClients;
|
||||
public ArrayList<GetOnlineUserResult.UserClient> userClients;
|
||||
public int totalCount;
|
||||
public int offset;
|
||||
}
|
||||
|
||||
+6
-6
@@ -8,14 +8,14 @@
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class OutputVerifyApplicationUser {
|
||||
private String userId;
|
||||
public class InputApplicationGetUserInfo {
|
||||
private String authCode;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
public String getAuthCode() {
|
||||
return authCode;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
public void setAuthCode(String authCode) {
|
||||
this.authCode = authCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class InputMessageUid {
|
||||
public long messageUid;
|
||||
|
||||
public InputMessageUid() {
|
||||
}
|
||||
|
||||
public InputMessageUid(long messageUid) {
|
||||
this.messageUid = messageUid;
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -8,14 +8,14 @@
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class InputVerifyApplicationUser {
|
||||
private String token;
|
||||
public class InputRobotId {
|
||||
private String robotId;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
public String getRobotId() {
|
||||
return robotId;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
public void setRobotId(String robotId) {
|
||||
this.robotId = robotId;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 cn.wildfirechat.pojos;
|
||||
|
||||
public class OutputApplicationConfigData {
|
||||
private String appId;
|
||||
private int appType;
|
||||
private long timestamp;
|
||||
private String nonceStr;
|
||||
private String signature;
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public int getAppType() {
|
||||
return appType;
|
||||
}
|
||||
|
||||
public void setAppType(int appType) {
|
||||
this.appType = appType;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public void setSignature(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
}
|
||||
@@ -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 cn.wildfirechat.pojos;
|
||||
|
||||
public class OutputApplicationUserInfo {
|
||||
private String userId;
|
||||
private String displayName;
|
||||
private String portraitUrl;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getPortraitUrl() {
|
||||
return portraitUrl;
|
||||
}
|
||||
|
||||
public void setPortraitUrl(String portraitUrl) {
|
||||
this.portraitUrl = portraitUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
public class OutputRobot {
|
||||
private String userId;
|
||||
private String name;
|
||||
private String password;
|
||||
private String displayName;
|
||||
private String portrait;
|
||||
private int gender;
|
||||
private String mobile;
|
||||
private String email;
|
||||
private String address;
|
||||
private String company;
|
||||
private String social;
|
||||
private String extra;
|
||||
private long updateDt;
|
||||
|
||||
private String owner;
|
||||
private String secret;
|
||||
private String callback;
|
||||
private String robotExtra;
|
||||
|
||||
public String getSocial() {
|
||||
return social;
|
||||
}
|
||||
|
||||
public void setSocial(String social) {
|
||||
this.social = social;
|
||||
}
|
||||
|
||||
public long getUpdateDt() {
|
||||
return updateDt;
|
||||
}
|
||||
|
||||
public void setUpdateDt(long updateDt) {
|
||||
this.updateDt = updateDt;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getPortrait() {
|
||||
return portrait;
|
||||
}
|
||||
|
||||
public void setPortrait(String portrait) {
|
||||
this.portrait = portrait;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
|
||||
public void setMobile(String mobile) {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
public int getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(int gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getCallback() {
|
||||
return callback;
|
||||
}
|
||||
|
||||
public void setCallback(String callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public String getRobotExtra() {
|
||||
return robotExtra;
|
||||
}
|
||||
|
||||
public void setRobotExtra(String robotExtra) {
|
||||
this.robotExtra = robotExtra;
|
||||
}
|
||||
|
||||
public void fromUser(WFCMessage.User user) {
|
||||
userId = user.getUid();
|
||||
name = user.getName();
|
||||
displayName = user.getDisplayName();
|
||||
portrait = user.getPortrait();
|
||||
gender = user.getGender();
|
||||
mobile = user.getMobile();
|
||||
email = user.getEmail();
|
||||
address = user.getAddress();
|
||||
company = user.getCompany();
|
||||
social = user.getSocial();
|
||||
extra = user.getExtra();
|
||||
updateDt = user.getUpdateDt();
|
||||
}
|
||||
public void fromRobot(WFCMessage.Robot robot, boolean withSecret) {
|
||||
setOwner(robot.getOwner());
|
||||
if(withSecret) {
|
||||
setSecret(robot.getSecret());
|
||||
}
|
||||
setCallback(robot.getCallback());
|
||||
setRobotExtra(robot.getExtra());
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,60 @@ public class ProtoConstants {
|
||||
int File = 5;
|
||||
int Video = 6;
|
||||
int Sticker = 7;
|
||||
int RichMedia = 8;
|
||||
int Link = 8;
|
||||
int P_TEXT = 9;
|
||||
int Name_Card = 10;
|
||||
int Composited = 11;
|
||||
int Rich_Notification = 12;
|
||||
int Articles = 13;
|
||||
int Enter_Channel_Chat = 71;
|
||||
int Leave_Channel_Chat = 72;
|
||||
int Recall = 80;
|
||||
int Delete = 81;
|
||||
int Tip = 90;
|
||||
int Typing = 91;
|
||||
int Friend_Greeting = 92;
|
||||
int Friend_Added = 93;
|
||||
int PC_Login_Request = 94;
|
||||
int Create_Group = 104;
|
||||
int Add_Group_Member = 105;
|
||||
int Kickoff_Group_Member = 106;
|
||||
int Quit_Group = 107;
|
||||
int Dismiss_Group = 108;
|
||||
int Transfer_Group_Owner = 109;
|
||||
int Change_Group_Name = 110;;
|
||||
int Modify_Group_Alias = 111;
|
||||
int Change_Group_Portrait = 112;
|
||||
int Change_Group_Mute = 113;
|
||||
int Change_Group_JoinType = 114;
|
||||
int Change_Group_PrivateChat = 115;
|
||||
int Change_Group_Searchable = 116;
|
||||
int Set_Group_Manager = 117;
|
||||
int Mute_Group_Member = 118;
|
||||
int Allow_Group_Member = 119;
|
||||
int Kickoff_Group_Member_Visible_Notification = 120;
|
||||
int Quit_Group_Visible_Notification = 121;
|
||||
int Modify_Group_Extra = 122;
|
||||
int Modify_Group_Member_Extra = 123;
|
||||
}
|
||||
|
||||
public interface MessagePersistFlag {
|
||||
int NOT_PERSIST = 0;
|
||||
int PERSIST = 1;
|
||||
int PERSIST_AND_COUNT = 3;
|
||||
int TRANSPARENT = 4;
|
||||
}
|
||||
|
||||
public interface MessageMediaType {
|
||||
int GENERAL = 0;
|
||||
int IMAGE = 1;
|
||||
int VOICE = 2;
|
||||
int VIDEO = 3;
|
||||
int FILE = 4;
|
||||
int PORTRAIT = 5;
|
||||
int FAVORITE = 6;
|
||||
int STICKER = 7;
|
||||
int MOMENTS = 8;
|
||||
}
|
||||
|
||||
//ModifyGroupInfoRequest -> type
|
||||
@@ -230,6 +283,12 @@ public class ProtoConstants {
|
||||
Request_From_Channel;
|
||||
}
|
||||
|
||||
public interface ApplicationType {
|
||||
int ApplicationType_Robot = 0;
|
||||
int ApplicationType_Channel = 1;
|
||||
int ApplicationType_Admin = 2;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.84</version>
|
||||
<version>0.89</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>distribution</artifactId>
|
||||
|
||||
@@ -103,7 +103,6 @@ message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
|
||||
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
|
||||
message.no_forward_admin_message false
|
||||
|
||||
|
||||
##禁止搜索用户
|
||||
friend.disable_search false
|
||||
|
||||
@@ -113,13 +112,13 @@ friend.disable_nick_name_search false
|
||||
##禁止发送好友邀请,通过server api添加好友不受此限制(force参数需要为true)
|
||||
friend.disable_friend_request false
|
||||
|
||||
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为不限制
|
||||
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为无限长期限。
|
||||
friend.repeat_request_duration 604800000
|
||||
|
||||
##好友请求被拒绝后再次发送的间隔,单位是毫秒,默认是30天,0为不限制
|
||||
##好友请求被拒绝后再次发送的间隔,单位是毫秒,默认是30天,0为不限制。不能小于friend.repeat_request_duration。
|
||||
friend.reject_request_duration 2592000000
|
||||
|
||||
##好友请求过期时间,单位是毫秒,默认是7天,0为不限制
|
||||
##好友请求过期时间,单位是毫秒,默认是7天,0为无限长期限。
|
||||
friend.request_expiration_duration 604800000
|
||||
|
||||
##添加好友后会发送欢迎消息,比如"你们已经是好友了,可以聊天了"。这个开关控制是用旧的方式还是用新的方式。
|
||||
@@ -233,6 +232,9 @@ local.media.storage.root ./media
|
||||
# 建议使用false
|
||||
server.multi_endpoint false
|
||||
|
||||
## 是否支持PC多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PC端多端登录。
|
||||
server.multi_pc_endpoint false
|
||||
|
||||
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
|
||||
server.multi_platform_notification true
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>0.84</version>
|
||||
<version>0.89</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.84</version>
|
||||
<version>0.89</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<version>2.8.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<version>2.8.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -4,33 +4,37 @@ import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.ChannelHttpUtils;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ApplicationType.ApplicationType_Channel;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ApplicationType.ApplicationType_Robot;
|
||||
|
||||
//仅专业版支持,社区版不支持
|
||||
public class ChannelServiceApi {
|
||||
private final ChannelHttpUtils httpUtils;
|
||||
private final ChannelHttpUtils channelHttpUtils;
|
||||
|
||||
public ChannelServiceApi(String imurl, String channelId, String secret) {
|
||||
httpUtils = new ChannelHttpUtils(imurl, channelId, secret);
|
||||
channelHttpUtils = new ChannelHttpUtils(imurl, channelId, secret);
|
||||
}
|
||||
|
||||
public IMResult<InputOutputUserInfo> getUserInfo(String userId) throws Exception {
|
||||
String path = APIPath.Channel_User_Info;
|
||||
InputGetUserInfo getUserInfo = new InputGetUserInfo(userId, null, null);
|
||||
return httpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
return channelHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
}
|
||||
|
||||
public IMResult<InputOutputUserInfo> getUserInfoByName(String userName) throws Exception {
|
||||
String path = APIPath.Channel_User_Info;
|
||||
InputGetUserInfo getUserInfo = new InputGetUserInfo(null, userName, null);
|
||||
return httpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
return channelHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
}
|
||||
|
||||
public IMResult<InputOutputUserInfo> getUserInfoByMobile(String mobile) throws Exception {
|
||||
String path = APIPath.Channel_User_Info;
|
||||
InputGetUserInfo getUserInfo = new InputGetUserInfo(null, null, mobile);
|
||||
return httpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
return channelHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> modifyChannelInfo(/*ProtoConstants.ModifyChannelInfoType*/int type, String value) throws Exception {
|
||||
@@ -38,12 +42,12 @@ public class ChannelServiceApi {
|
||||
InputModifyChannelInfo modifyChannelInfo = new InputModifyChannelInfo();
|
||||
modifyChannelInfo.setType(type);
|
||||
modifyChannelInfo.setValue(value);
|
||||
return httpUtils.httpJsonPost(path, modifyChannelInfo, Void.class);
|
||||
return channelHttpUtils.httpJsonPost(path, modifyChannelInfo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<OutputGetChannelInfo> getChannelInfo() throws Exception {
|
||||
String path = APIPath.Channel_Get_Profile;
|
||||
return httpUtils.httpJsonPost(path, null, OutputGetChannelInfo.class);
|
||||
return channelHttpUtils.httpJsonPost(path, null, OutputGetChannelInfo.class);
|
||||
}
|
||||
|
||||
public IMResult<SendMessageResult> sendMessage(int line, List<String> targets, MessagePayload payload) throws Exception {
|
||||
@@ -52,7 +56,7 @@ public class ChannelServiceApi {
|
||||
messageData.setLine(0);
|
||||
messageData.setTargets(targets);
|
||||
messageData.setPayload(payload);
|
||||
return httpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
|
||||
return channelHttpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> subscribe(String userId) throws Exception {
|
||||
@@ -60,7 +64,7 @@ public class ChannelServiceApi {
|
||||
InputChannelSubscribe input = new InputChannelSubscribe();
|
||||
input.setTarget(userId);
|
||||
input.setSubscribe(1);
|
||||
return httpUtils.httpJsonPost(path, input, Void.class);
|
||||
return channelHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> unsubscribe(String userId) throws Exception {
|
||||
@@ -68,12 +72,33 @@ public class ChannelServiceApi {
|
||||
InputChannelSubscribe input = new InputChannelSubscribe();
|
||||
input.setTarget(userId);
|
||||
input.setSubscribe(0);
|
||||
return httpUtils.httpJsonPost(path, input, Void.class);
|
||||
return channelHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<OutputStringList> getSubscriberList() throws Exception {
|
||||
String path = APIPath.Channel_Subscriber_List;
|
||||
return httpUtils.httpJsonPost(path, null, OutputStringList.class);
|
||||
return channelHttpUtils.httpJsonPost(path, null, OutputStringList.class);
|
||||
}
|
||||
|
||||
public IMResult<OutputApplicationUserInfo> applicationGetUserInfo(String authCode) throws Exception {
|
||||
String path = APIPath.Channel_Application_Get_UserInfo;
|
||||
InputApplicationGetUserInfo input = new InputApplicationGetUserInfo();
|
||||
input.setAuthCode(authCode);
|
||||
return channelHttpUtils.httpJsonPost(path, input, OutputApplicationUserInfo.class);
|
||||
}
|
||||
|
||||
public OutputApplicationConfigData getApplicationSignature() {
|
||||
int nonce = (int)(Math.random() * 100000 + 3);
|
||||
long timestamp = System.currentTimeMillis()/1000;
|
||||
String str = nonce + "|" + channelHttpUtils.getChannelId() + "|" + timestamp + "|" + channelHttpUtils.getChannelSecret();
|
||||
String sign = DigestUtils.sha1Hex(str);
|
||||
OutputApplicationConfigData configData = new OutputApplicationConfigData();
|
||||
configData.setAppId(channelHttpUtils.getChannelId());
|
||||
configData.setAppType(ApplicationType_Channel);
|
||||
configData.setTimestamp(timestamp);
|
||||
configData.setNonceStr(nonce+"");
|
||||
configData.setSignature(sign);
|
||||
return configData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.messagecontentbuilder.RichNotificationContentBuilder;
|
||||
import cn.wildfirechat.messagecontentbuilder.TextMessageContentBuilder;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
@@ -95,6 +97,14 @@ public class Main {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<OutputRobot> outputRobotIMResult = UserAdmin.getRobotInfo("robot1");
|
||||
if(outputRobotIMResult != null && outputRobotIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("Get robot success");
|
||||
} else {
|
||||
System.out.println("Get robot failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<Void> destroyResult = UserAdmin.destroyRobot("robot1");
|
||||
if(destroyResult != null && destroyResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("success");
|
||||
@@ -653,13 +663,11 @@ public class Main {
|
||||
//***********************************************
|
||||
static void testMessage() throws Exception {
|
||||
Conversation conversation = new Conversation();
|
||||
conversation.setTarget("user2");
|
||||
conversation.setTarget("ff2");
|
||||
conversation.setType(ProtoConstants.ConversationType.ConversationType_Private);
|
||||
MessagePayload payload = new MessagePayload();
|
||||
payload.setType(1);
|
||||
payload.setSearchableContent("hello world");
|
||||
MessagePayload payload = TextMessageContentBuilder.newBuilder("Hello world").build();
|
||||
|
||||
IMResult<SendMessageResult> resultSendMessage = MessageAdmin.sendMessage("user1", conversation, payload, null);
|
||||
IMResult<SendMessageResult> resultSendMessage = MessageAdmin.sendMessage("ff1", conversation, payload, null);
|
||||
if (resultSendMessage != null && resultSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("send message success");
|
||||
} else {
|
||||
@@ -667,6 +675,31 @@ public class Main {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
RichNotificationContentBuilder builder = RichNotificationContentBuilder.newBuilder("产品审核通知", "您好,您的SSL证书以审核通过并成功办理,请关注", "https://www.baidu.com")
|
||||
.remark("谢谢惠顾")
|
||||
.exName("证书小助手")
|
||||
.appId("1234567890")
|
||||
.addItem("登陆账户", "野火IM", "#173177")
|
||||
.addItem("产品名称", "域名wildifrechat.cn申请的免费SSL证书", "#173177")
|
||||
.addItem("审核通过", "通过", "#173177")
|
||||
.addItem("说明", "请登陆账户查看处理", "#173177");
|
||||
|
||||
|
||||
resultSendMessage = MessageAdmin.sendMessage("ff1", conversation, builder.build(), null);
|
||||
if (resultSendMessage != null && resultSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("send message success");
|
||||
} else {
|
||||
System.out.println("send message failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<OutputMessageData> outputMessageDataIMResult = MessageAdmin.getMessage(resultSendMessage.result.getMessageUid());
|
||||
if(outputMessageDataIMResult != null && outputMessageDataIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && outputMessageDataIMResult.getResult().getMessageId() == resultSendMessage.getResult().getMessageUid()) {
|
||||
System.out.println("get message success");
|
||||
} else {
|
||||
System.out.println("get message failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<Void> voidIMResult = MessageAdmin.recallMessage("user1", resultSendMessage.getResult().getMessageUid());
|
||||
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
@@ -996,8 +1029,8 @@ public class Main {
|
||||
//**** 机器人API
|
||||
//***********************************************
|
||||
|
||||
IMResult<InputOutputUserInfo> userInfoIMResult = robotService.getProfile(robotId);
|
||||
if(userInfoIMResult != null && userInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
IMResult<OutputRobot> robotProfileIMResult = robotService.getProfile();
|
||||
if(robotProfileIMResult != null && robotProfileIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get profile success");
|
||||
} else {
|
||||
System.out.println("get profile failure");
|
||||
@@ -1012,8 +1045,8 @@ public class Main {
|
||||
System.out.println("modify profile failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
userInfoIMResult = robotService.getProfile(robotId);
|
||||
if(userInfoIMResult != null && userInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && displayName.equals(userInfoIMResult.getResult().getDisplayName())) {
|
||||
robotProfileIMResult = robotService.getProfile();
|
||||
if(robotProfileIMResult != null && robotProfileIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && displayName.equals(robotProfileIMResult.getResult().getDisplayName())) {
|
||||
System.out.println("get profile success");
|
||||
} else {
|
||||
System.out.println("get profile failure");
|
||||
@@ -1181,6 +1214,9 @@ public class Main {
|
||||
System.out.println("cancel group manager failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
OutputApplicationConfigData config = robotService.getApplicationSignature();
|
||||
System.out.println(config);
|
||||
}
|
||||
|
||||
|
||||
@@ -1321,58 +1357,54 @@ public class Main {
|
||||
ChannelServiceApi channelServiceApi = new ChannelServiceApi(IMUrl, resultCreateChannel.getResult().getTargetId(), secret);
|
||||
|
||||
|
||||
|
||||
if (commercialServer) {
|
||||
//3. 测试channel api功能
|
||||
IMResult<Void> resultVoid = channelServiceApi.subscribe("userId2");
|
||||
if (resultVoid != null && resultVoid.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("subscribe success");
|
||||
} else {
|
||||
System.out.println("subscribe failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
resultVoid = channelServiceApi.subscribe("userId3");
|
||||
if (resultVoid != null && resultVoid.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("subscribe done");
|
||||
} else {
|
||||
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");
|
||||
} else {
|
||||
System.out.println("get subscriber failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
resultVoid = channelServiceApi.unsubscribe("userId2");
|
||||
if (resultVoid != null && resultVoid.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("unsubscriber done");
|
||||
} else {
|
||||
System.out.println("unsubscriber failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
resultStringList = channelServiceApi.getSubscriberList();
|
||||
if (resultStringList != null && resultStringList.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && resultStringList.getResult().getList().contains("userId3") && !resultStringList.getResult().getList().contains("userId2")) {
|
||||
System.out.println("get subscriber done");
|
||||
} else {
|
||||
System.out.println("get subscriber failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<InputOutputUserInfo> resultGetUserInfo1 = channelServiceApi.getUserInfo("userId3");
|
||||
if (resultGetUserInfo1 != null && resultGetUserInfo1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get user info success");
|
||||
} else {
|
||||
System.out.println("get user info failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
//3. 测试channel api功能
|
||||
IMResult<Void> resultVoid = channelServiceApi.subscribe("userId2");
|
||||
if (resultVoid != null && resultVoid.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("subscribe success");
|
||||
} else {
|
||||
System.out.println("subscribe failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
resultVoid = channelServiceApi.subscribe("userId3");
|
||||
if (resultVoid != null && resultVoid.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("subscribe done");
|
||||
} else {
|
||||
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");
|
||||
} else {
|
||||
System.out.println("get subscriber failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
resultVoid = channelServiceApi.unsubscribe("userId2");
|
||||
if (resultVoid != null && resultVoid.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("unsubscriber done");
|
||||
} else {
|
||||
System.out.println("unsubscriber failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
resultStringList = channelServiceApi.getSubscriberList();
|
||||
if (resultStringList != null && resultStringList.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && resultStringList.getResult().getList().contains("userId3") && !resultStringList.getResult().getList().contains("userId2")) {
|
||||
System.out.println("get subscriber done");
|
||||
} else {
|
||||
System.out.println("get subscriber failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<InputOutputUserInfo> resultGetUserInfo1 = channelServiceApi.getUserInfo("userId3");
|
||||
if (resultGetUserInfo1 != null && resultGetUserInfo1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get user info success");
|
||||
} else {
|
||||
System.out.println("get user info failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
MessagePayload payload = new MessagePayload();
|
||||
payload.setType(1);
|
||||
@@ -1396,23 +1428,23 @@ public class Main {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
if (commercialServer) {
|
||||
IMResult<Void> voidIMResult = channelServiceApi.modifyChannelInfo(ProtoConstants.ModifyChannelInfoType.Modify_Channel_Desc, "this is a test channel, update at:" + new Date().toString());
|
||||
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("modify channel profile success");
|
||||
} else {
|
||||
System.out.println("modify channel profile failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<OutputGetChannelInfo> outputGetChannelInfoIMResult = channelServiceApi.getChannelInfo();
|
||||
if (outputGetChannelInfoIMResult != null && outputGetChannelInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get channel info success");
|
||||
} else {
|
||||
System.out.println("get channel info failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
IMResult<Void> voidIMResult = channelServiceApi.modifyChannelInfo(ProtoConstants.ModifyChannelInfoType.Modify_Channel_Desc, "this is a test channel, update at:" + new Date().toString());
|
||||
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("modify channel profile success");
|
||||
} else {
|
||||
System.out.println("modify channel profile failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<OutputGetChannelInfo> outputGetChannelInfoIMResult = channelServiceApi.getChannelInfo();
|
||||
if (outputGetChannelInfoIMResult != null && outputGetChannelInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get channel info success");
|
||||
} else {
|
||||
System.out.println("get channel info failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
OutputApplicationConfigData config = channelServiceApi.getApplicationSignature();
|
||||
System.out.println(config);
|
||||
}
|
||||
static void testSensitiveApi() throws Exception {
|
||||
List<String> words = Arrays.asList("a","b","c");
|
||||
|
||||
@@ -48,7 +48,17 @@ public class MessageAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, updateMessageContentData, Void.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取单条消息。如果想要更多消息的读取,可以直接读取IM服务的数据库。
|
||||
* @param messageUid
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static IMResult<OutputMessageData> getMessage(long messageUid) throws Exception {
|
||||
String path = APIPath.Msg_GetOne;
|
||||
InputMessageUid inputMessageUid = new InputMessageUid(messageUid);
|
||||
return AdminHttpUtils.httpJsonPost(path, inputMessageUid, OutputMessageData.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回群发或者广播的消息
|
||||
|
||||
@@ -4,10 +4,12 @@ import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.RobotHttpUtils;
|
||||
import cn.wildfirechat.sdk.utilities.RobotHttpUtils;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ApplicationType.ApplicationType_Robot;
|
||||
|
||||
public class RobotService {
|
||||
private final RobotHttpUtils robotHttpUtils;
|
||||
|
||||
@@ -59,8 +61,9 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, null, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<InputOutputUserInfo> getProfile(String robotId) throws Exception {
|
||||
return getUserInfo(robotId);
|
||||
public IMResult<OutputRobot> getProfile() throws Exception {
|
||||
String path = APIPath.Robot_Get_Profile;
|
||||
return robotHttpUtils.httpJsonPost(path, null, OutputRobot.class);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -214,4 +217,27 @@ public class RobotService {
|
||||
input.setNotify_message(notify_message);
|
||||
return robotHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<OutputApplicationUserInfo> applicationGetUserInfo(String authCode) throws Exception {
|
||||
String path = APIPath.Robot_Application_Get_UserInfo;
|
||||
InputApplicationGetUserInfo input = new InputApplicationGetUserInfo();
|
||||
input.setAuthCode(authCode);
|
||||
return robotHttpUtils.httpJsonPost(path, input, OutputApplicationUserInfo.class);
|
||||
}
|
||||
|
||||
public OutputApplicationConfigData getApplicationSignature() {
|
||||
int nonce = (int)(Math.random() * 100000 + 3);
|
||||
long timestamp = System.currentTimeMillis()/1000;
|
||||
String str = nonce + "|" + robotHttpUtils.getRobotId() + "|" + timestamp + "|" + robotHttpUtils.getRobotSecret();
|
||||
String sign = DigestUtils.sha1Hex(str);
|
||||
OutputApplicationConfigData configData = new OutputApplicationConfigData();
|
||||
configData.setAppId(robotHttpUtils.getRobotId());
|
||||
configData.setAppType(ApplicationType_Robot);
|
||||
configData.setTimestamp(timestamp);
|
||||
configData.setNonceStr(nonce+"");
|
||||
configData.setSignature(sign);
|
||||
return configData;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -52,6 +52,13 @@ public class UserAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, inputDestroyUser, Void.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputRobot> getRobotInfo(String robotId) throws Exception {
|
||||
String path = APIPath.User_Get_Robot_Info;
|
||||
InputRobotId getRobotInfo = new InputRobotId();
|
||||
getRobotInfo.setRobotId(robotId);
|
||||
return AdminHttpUtils.httpJsonPost(path, getRobotInfo, OutputRobot.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputGetIMTokenData> getUserToken(String userId, String clientId, int platform) throws Exception {
|
||||
String path = APIPath.User_Get_Token;
|
||||
InputGetToken getToken = new InputGetToken(userId, clientId, platform);
|
||||
@@ -129,4 +136,11 @@ public class UserAdmin {
|
||||
request.count = count;
|
||||
return AdminHttpUtils.httpJsonPost(APIPath.User_Online_List, request, GetOnlineUserResult.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputApplicationUserInfo> applicationGetUserInfo(String authCode) throws Exception {
|
||||
String path = APIPath.User_Application_Get_UserInfo;
|
||||
InputApplicationGetUserInfo input = new InputApplicationGetUserInfo();
|
||||
input.setAuthCode(authCode);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputApplicationUserInfo.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
public class AdminHttpUtils {
|
||||
public class AdminHttpUtils extends JsonUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AdminHttpUtils.class);
|
||||
|
||||
private static String adminUrl;
|
||||
@@ -152,17 +152,4 @@ public class AdminHttpUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> IMResult<T> fromJsonObject(String content, Class<T> clazz) {
|
||||
Type type = TypeBuilder
|
||||
.newInstance(IMResult.class)
|
||||
.addTypeParam(clazz)
|
||||
.build();
|
||||
return new Gson().fromJson(content, type);
|
||||
}
|
||||
|
||||
private static boolean isNullOrEmpty(String str) {
|
||||
return str == null || str.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
public class ChannelHttpUtils {
|
||||
public class ChannelHttpUtils extends JsonUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChannelHttpUtils.class);
|
||||
|
||||
private String imurl;
|
||||
@@ -103,16 +103,11 @@ public class ChannelHttpUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> IMResult<T> fromJsonObject(String content, Class<T> clazz) {
|
||||
Type type = TypeBuilder
|
||||
.newInstance(IMResult.class)
|
||||
.addTypeParam(clazz)
|
||||
.build();
|
||||
return new Gson().fromJson(content, type);
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
private static boolean isNullOrEmpty(String str) {
|
||||
return str == null || str.isEmpty();
|
||||
public String getChannelSecret() {
|
||||
return channelSecret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.wildfirechat.sdk.utilities;
|
||||
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import com.google.gson.Gson;
|
||||
import ikidou.reflect.TypeBuilder;
|
||||
|
||||
public class JsonUtils {
|
||||
|
||||
public static <T> IMResult<T> fromJsonObject(String content, Class<T> clazz) {
|
||||
TypeBuilder builder = TypeBuilder.newInstance(IMResult.class);
|
||||
if (!clazz.equals(Void.class)) {
|
||||
builder.addTypeParam(clazz);
|
||||
}
|
||||
return new Gson().fromJson(content, builder.build());
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(String str) {
|
||||
return str == null || str.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
public class RobotHttpUtils {
|
||||
public class RobotHttpUtils extends JsonUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RobotHttpUtils.class);
|
||||
|
||||
private final String url;
|
||||
@@ -106,16 +106,11 @@ public class RobotHttpUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> IMResult<T> fromJsonObject(String content, Class<T> clazz) {
|
||||
Type type = TypeBuilder
|
||||
.newInstance(IMResult.class)
|
||||
.addTypeParam(clazz)
|
||||
.build();
|
||||
return new Gson().fromJson(content, type);
|
||||
public String getRobotId() {
|
||||
return robotId;
|
||||
}
|
||||
|
||||
private static boolean isNullOrEmpty(String str) {
|
||||
return str == null || str.isEmpty();
|
||||
public String getRobotSecret() {
|
||||
return robotSecret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user