Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ced74280d8 | ||
|
|
18617c67f4 | ||
|
|
883866ce39 | ||
|
|
2e135d4794 | ||
|
|
1d6faa5796 | ||
|
|
731fa00cc9 | ||
|
|
4da9173c5f | ||
|
|
94e430cc83 | ||
|
|
7e92d1e0c5 | ||
|
|
4fa79bfeac | ||
|
|
98388a5129 | ||
|
|
1a89714df9 | ||
|
|
a855652c26 | ||
|
|
21aadd9c0b | ||
|
|
5522a8689d | ||
|
|
bf52a00304 | ||
|
|
3349e2a4e5 | ||
|
|
70f3f96f7a | ||
|
|
5e9d411f1b | ||
|
|
e74fd0c660 | ||
|
|
d1232abe39 | ||
|
|
1df192f730 | ||
|
|
f897e640fc | ||
|
|
ee6e4f96fb | ||
|
|
d14dc74566 | ||
|
|
ff75379779 | ||
|
|
b95a6b7785 | ||
|
|
5acb3044ac | ||
|
|
ae084063f4 | ||
|
|
cb3a82559d | ||
|
|
9191204bb0 | ||
|
|
6587a88ca9 | ||
|
|
86c1a2e140 | ||
|
|
83e9679339 | ||
|
|
dafb0cd4d9 | ||
|
|
cbcc8310c4 | ||
|
|
ade58efc11 | ||
|
|
d45da9674e | ||
|
|
f603a677ea | ||
|
|
03894aea9a | ||
|
|
8635153e59 | ||
|
|
3d98d17b0d | ||
|
|
0549bc502f | ||
|
|
1b8cf3e5f9 | ||
|
|
f3f08b3026 | ||
|
|
78e6efce14 | ||
|
|
462423a6f3 | ||
|
|
55190a4f76 | ||
|
|
4ed21ecb03 | ||
|
|
1ff3b592bd | ||
|
|
fbc2351d82 | ||
|
|
dd1783d4ac | ||
|
|
845e6ff8aa | ||
|
|
6d91f3869e | ||
|
|
d100bd5fb1 | ||
|
|
bf22b365a8 | ||
|
|
f1298a51ae | ||
|
|
41f62c6354 | ||
|
|
a45de0ecd1 | ||
|
|
fc35865478 |
@@ -9,7 +9,7 @@
|
||||
* 安全加密。网络连接AES加密。客户端数据库SqlCipher加密。安全无小事。
|
||||
* 全平台客户端,支持Android、iOS、鸿蒙、Web、小程序、UniApp、Flutter、Windows、Mac OS、Linux等所有常见平台。
|
||||
* 四端同时在线(移动端,pc端,web端和小程序端),数据和状态多端完美同步。
|
||||
* 支持国产化。支持国产化操作系统、国产化芯片和国产操作系统。支持国密加密。
|
||||
* 支持国产化。支持国产化操作系统、国产化芯片和国产数据库。支持国密加密。
|
||||
* 客户端使用微信[mars](https://github.com/tencent/mars)连接库,野火IM可能是最适应中国网络国情的即时通讯服务。
|
||||
* 支持加速点加速,即可用于全球应用,也可用于政企内外双网复杂的网络环境。
|
||||
* 支持阅读回执和在线状态功能,适用于办公环境。
|
||||
@@ -25,7 +25,7 @@
|
||||
* 支持多个IM服务组网互通,打破孤岛,适用于集团公司下多个分公司互联互通。
|
||||
* 社区版IM服务和移动端免费商用,可以免费构建出完备的移动互联网应用。
|
||||
* 收费项目非常便宜,野火独有的试用模式,可以先部署到客户环境试用6个月,试用满意后再购买,避免上当受骗。
|
||||
* 技术支持专业和高效,***核心研发***及时处理issue和工单,能最快解决用户的技术难题。
|
||||
* 技术支持专业高效,***核心研发***及时处理issue和工单,能最快解决用户的技术难题。技术支持不收费,让客户顺利使用是我们最大的愿望。
|
||||
|
||||
## 野火开源项目
|
||||
主要包括以下项目:
|
||||
|
||||
@@ -95,9 +95,15 @@ message.disable_stranger_chat false
|
||||
##当禁止陌生人聊天时,允许聊天的用户id,比如管理员或者文件传输助手等。用户id以英文逗号分割。
|
||||
message.allow_stranger_chat_list admin,FireRobot,wfc_file_transfer
|
||||
|
||||
##当禁止陌生人聊天时,允许聊天的线路。
|
||||
#message.allow_stranger_line 100,101
|
||||
|
||||
##黑名单策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃
|
||||
message.blacklist.strategy 0
|
||||
|
||||
##拉黑对方后,对方不能发送消息给你。这个开关确定拉黑对方后你还能不能给对方发送消息。
|
||||
message.blacklist.allow_send_to_black false
|
||||
|
||||
##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段
|
||||
message.disable_remote_search false
|
||||
|
||||
@@ -105,7 +111,7 @@ message.disable_remote_search false
|
||||
##如果要避免数据库中明文存储消息内容,请打开这个开关和message.disable_remote_search开关
|
||||
message.encrypt_message_content false
|
||||
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。0是不允许撤回;-1是无限制撤回。
|
||||
##Server API不受此限制,可以撤回任意时限内的消息
|
||||
##群组管理员或群主撤回群成员消息不受此限制,可以撤回任意时限内的消息。但管理员或群主撤回自己的消息还是需要准守此时间限制。
|
||||
##修改此参数需要同步修改客户端UI,客户端UI代码有判断撤回是否显示的逻辑。
|
||||
@@ -146,12 +152,33 @@ message.no_forward_admin_message false
|
||||
## 消息转发功能开启时,转发信息是否带上用户clientId和平台类型。
|
||||
message.forward_with_client_info false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上发送者的用户信息
|
||||
message.forward_with_sender_info false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上目标的信息,单聊时是对方用户信息,群聊时是群组信息,频道时是频道信息
|
||||
message.forward_with_target_info false
|
||||
|
||||
## 允许发送单聊消息给被封禁用户
|
||||
message.allow_send_to_forbidden_user false
|
||||
|
||||
## 机器人回调信息是否带上用户clientId和平台类型。
|
||||
robot.callback_with_client_info false
|
||||
|
||||
## 机器人回调信息是否带上发送者的用户信息
|
||||
robot.callback_with_sender_info false
|
||||
|
||||
## 机器人回调信息是否带上目标的信息,单聊时是对方用户信息,群聊时是群组信息,频道时是频道信息
|
||||
robot.callback_with_target_info false
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
## 频道回调信息是否带上发送者的用户信息。
|
||||
channel.callback_with_sender_info false
|
||||
|
||||
## 频道回调信息是否带上频道信息
|
||||
channel.callback_with_target_info false
|
||||
|
||||
## 频道回调新方式,在新方式下,如果有callback地址就会总是回调客户端发送的消息(包括owner和订阅者)。automatic属性控制订阅者发送的消息是否发给owner, 0发,1不发。
|
||||
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
||||
channel.new_callback_feature true
|
||||
@@ -177,6 +204,9 @@ friend.reject_request_duration 2592000000
|
||||
##好友请求过期时间,单位是毫秒,默认是7天,0为无限长期限。
|
||||
friend.request_expiration_duration 604800000
|
||||
|
||||
##好友请求限制频率,一个用户24小时之内允许请求好友的次数,默认不限频。
|
||||
friend.request_rate_limit 30
|
||||
|
||||
##请求添加机器人为好友时,机器人是否自动接受,默认为true
|
||||
friend.robot_auto_accept true
|
||||
|
||||
@@ -321,7 +351,7 @@ server.mobile_default_silent_when_pc_online true
|
||||
|
||||
## 客户端是否支持kickoff事件。当客户端被其他端登录踢出时,如果此开关为false时,客户端协议栈上报secret_mismatch。如果此开关为ture时,客户端协议栈上报kicked_off。
|
||||
## 客户端被踢时上报kicked_off是在2021.9.15之后才加上的。如果客户端协议栈全部为此日期之后的版本才可以打开此开关。
|
||||
server.client_support_kickoff_event false
|
||||
server.client_support_kickoff_event true
|
||||
|
||||
#*********************************************************************
|
||||
# Push server configuration
|
||||
@@ -335,6 +365,10 @@ push.android.server.address http://localhost:8085/android/push
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
push.ios.server.address http://localhost:8085/ios/push
|
||||
|
||||
##鸿蒙推送服务器地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
push.harmony.server.address http://localhost:8085/harmony/push
|
||||
|
||||
#*********************************************************************
|
||||
# 监控配置
|
||||
#*********************************************************************
|
||||
@@ -408,7 +442,10 @@ push.ios.server.address http://localhost:8085/ios/push
|
||||
## 内置文本敏感词过滤处理方法,当命中敏感词后,消息会被记录到t_sensitive_messages表中,然后根据type类型做不同的处理,处理方式如下:
|
||||
## 0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***然后正常发送;3 正常发送。
|
||||
## 如果开启 message.sensitive.forward.url 配置,命中敏感词的消息还会被回调到这个地址
|
||||
sensitive.filter.type 0
|
||||
sensitive.filter.type 2
|
||||
|
||||
## 敏感词添加或者删除有2种方式,一种是通过Server API进行,这种方式会立即生效。另外一种方法是修改数据库,直接中数据库的t_sensitive_word表中处理
|
||||
## 修改数据库的方法不会立即生效,IM服务会2个小时重新加载一次敏感词。所以如果直接修改敏感词表,需要等2个小时,或者重启才能生效。
|
||||
|
||||
## 如果内置敏感词库无法满足您的需求,可以开发部署独立敏感词审核服务。配置如下地址和消息类型,IM服务会把指定消息类型的消息回调到指定地址,内置的敏感词审核和敏感词转发功能就不再起作用了。
|
||||
## 审核服务返回状态码200表示继续发送,如果需要替换内容,返回状态码200并且内容为替换后的内容。返回403表示不允许发送。其它错误继续发送。
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
CREATE INDEX `user_gid_mid_dt_index` ON `t_group_member` (`_gid`, `_mid`, `_dt`);
|
||||
@@ -0,0 +1 @@
|
||||
CREATE INDEX `user_gid_mid_dt_index` ON `t_group_member` (`_gid`, `_mid`, `_dt`);
|
||||
@@ -9,6 +9,7 @@ server {
|
||||
root html;
|
||||
index index.html index.htm index.php;
|
||||
|
||||
#同步服务设置
|
||||
location /route {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
@@ -16,7 +17,7 @@ server {
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
|
||||
#社区版需要启用下面一段,专业版不能用
|
||||
#客户端短连接业务
|
||||
location /im {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
@@ -24,14 +25,21 @@ server {
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
|
||||
#版本检查/api/version,可以删掉
|
||||
location /api {
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
|
||||
#内置文件上传和下载
|
||||
location /fs {
|
||||
client_max_body_size 200M;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
|
||||
#机器人API
|
||||
location /robot {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
@@ -39,6 +47,7 @@ server {
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
|
||||
#频道API
|
||||
location /channel {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.2.9</version>
|
||||
<version>1.3.6</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
|
||||
@@ -34,7 +34,9 @@ public class PushMessage {
|
||||
public String voipDeviceToken;
|
||||
public boolean isHiddenDetail;
|
||||
public String language;
|
||||
public boolean republish;
|
||||
public long messageId;
|
||||
public long callStartUid;
|
||||
|
||||
public PushMessage(String sender, int conversationType, String target, int line, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionedType, boolean isHiddenDetail, String language) {
|
||||
this.sender = sender;
|
||||
@@ -65,6 +67,7 @@ public class PushMessage {
|
||||
this.mentionedType = mentionedType;
|
||||
this.isHiddenDetail = isHiddenDetail;
|
||||
this.language = language;
|
||||
this.republish = messageContentType == 80 || messageContentType == 81;
|
||||
}
|
||||
public PushMessage(String sender, String target, long serverTime, String senderName, int unReceivedMsg, String language, int pushMessageType) {
|
||||
this.sender = sender;
|
||||
|
||||
@@ -24,8 +24,7 @@ import win.liyufan.im.Utility;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static io.moquette.BrokerConstants.PUSH_ANDROID_SERVER_ADDRESS;
|
||||
import static io.moquette.BrokerConstants.PUSH_IOS_SERVER_ADDRESS;
|
||||
import static io.moquette.BrokerConstants.*;
|
||||
import static win.liyufan.im.HttpUtils.HttpPostType.POST_TYPE_Push;
|
||||
|
||||
public class PushServer {
|
||||
@@ -47,6 +46,7 @@ public class PushServer {
|
||||
|
||||
private String androidPushServerUrl;
|
||||
private String iOSPushServerUrl;
|
||||
private String harmonyPushServerUrl;
|
||||
|
||||
private PushServer() {
|
||||
}
|
||||
@@ -59,6 +59,7 @@ public class PushServer {
|
||||
this.sessionsStore = sessionsStore;
|
||||
this.androidPushServerUrl = config.getProperty(PUSH_ANDROID_SERVER_ADDRESS);
|
||||
this.iOSPushServerUrl = config.getProperty(PUSH_IOS_SERVER_ADDRESS);
|
||||
this.harmonyPushServerUrl = config.getProperty(PUSH_HARMONY_SERVER_ADDRESS);
|
||||
}
|
||||
|
||||
public void pushMessage(PushMessage pushMessage, String deviceId, String pushContent) {
|
||||
@@ -106,6 +107,8 @@ public class PushServer {
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_iPad) {
|
||||
url = iOSPushServerUrl;
|
||||
pushMessage.voipDeviceToken = session.getVoipDeviceToken();
|
||||
} else if (session.getPlatform() == ProtoConstants.Platform.Platform_Harmony || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad) {
|
||||
url = harmonyPushServerUrl;
|
||||
}
|
||||
HttpUtils.httpJsonPost(url, gson.toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push);
|
||||
} else {
|
||||
|
||||
@@ -8,9 +8,13 @@
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.channel.ChannelAction;
|
||||
import com.xiaoleilu.loServer.action.robot.RobotAction;
|
||||
import com.xiaoleilu.loServer.annotation.RequireAuthentication;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
@@ -23,7 +27,10 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import win.liyufan.im.RateLimiter;
|
||||
import win.liyufan.im.Utility;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@@ -38,6 +45,7 @@ import static io.moquette.BrokerConstants.*;
|
||||
*/
|
||||
|
||||
abstract public class Action {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Action.class);
|
||||
public static IMessagesStore messagesStore = null;
|
||||
public static ISessionsStore sessionsStore = null;
|
||||
protected static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
||||
@@ -153,9 +161,22 @@ abstract public class Action {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = new String(bytes, StandardCharsets.UTF_8);//contribute by JiaRG from github
|
||||
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
|
||||
try {
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
} catch (JsonSyntaxException e) {
|
||||
e.printStackTrace();
|
||||
LOG.error("Object {} from json {} failure", cls.getName(), content);
|
||||
int exception = IMExceptionEvent.EventType.ADMIN_API_Exception;
|
||||
if (this instanceof RobotAction) {
|
||||
exception = IMExceptionEvent.EventType.ROBOT_API_Exception;
|
||||
} else if (this instanceof ChannelAction) {
|
||||
exception = IMExceptionEvent.EventType.CHANNEL_API_Exception;
|
||||
}
|
||||
Utility.printExecption(LOG, e, exception);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.file.Files;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
@@ -13,6 +16,7 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.ServerSetting;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
@@ -90,11 +94,26 @@ public class FileAction extends Action {
|
||||
}
|
||||
|
||||
response.setContent(file);
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
|
||||
if (isAudioOrVideoFile(file.getName())) {
|
||||
response.setHeader("Accept-Ranges", "bytes");
|
||||
} else {
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isAudioOrVideoFile(String name) {
|
||||
try {
|
||||
if (StringUtil.isNullOrEmpty(name)) return false;
|
||||
|
||||
String mimeType = Files.probeContentType(new File(name).toPath());
|
||||
return mimeType != null && (mimeType.startsWith("audio/") || mimeType.startsWith("video/"));
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&\"].*");
|
||||
private static final SimpleDateFormat HTTP_DATE_FORMATER = new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
|
||||
|
||||
|
||||
@@ -51,14 +51,7 @@ public class AliasPutAction extends AdminAction {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
byte[] data = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.readBytes(data);
|
||||
String channelId = new String(data);
|
||||
return new Result(ErrorCode.ERROR_CODE_SUCCESS, new OutputCreateChannel(channelId));
|
||||
} else {
|
||||
return new Result(errorCode);
|
||||
}
|
||||
return new Result(errorCode);
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
|
||||
@@ -53,8 +53,11 @@ public class CreateChannelAction extends AdminAction {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
byte[] data = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.readBytes(data);
|
||||
String channelId = new String(data);
|
||||
return new Result(ErrorCode.ERROR_CODE_SUCCESS, new OutputCreateChannel(channelId));
|
||||
String str = new String(data);
|
||||
String[] ss = str.split("\\|");
|
||||
String channelId = ss[0];
|
||||
String secret = ss[1];
|
||||
return new Result(ErrorCode.ERROR_CODE_SUCCESS, new OutputCreateChannel(channelId, secret));
|
||||
} else {
|
||||
return new Result(errorCode);
|
||||
}
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
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.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.User_Batch_Get_Infos)
|
||||
@HttpMethod("POST")
|
||||
public class GetBatchUserAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputStringList inputUserId = getRequestBody(request.getNettyRequest(), InputStringList.class);
|
||||
if (inputUserId != null && inputUserId.getList() != null && !inputUserId.getList().isEmpty()) {
|
||||
|
||||
OutputUserInfoList res = new OutputUserInfoList();
|
||||
res.userInfos = new ArrayList<>();
|
||||
for (String userId : inputUserId.getList()) {
|
||||
WFCMessage.User user = messagesStore.getUserInfo(userId);
|
||||
if(user == null || StringUtil.isNullOrEmpty(user.getName())) {
|
||||
continue;
|
||||
}
|
||||
InputOutputUserInfo inputOutputUserInfo = InputOutputUserInfo.fromPbUser(user);
|
||||
res.userInfos.add(inputOutputUserInfo);
|
||||
}
|
||||
RestResult result = RestResult.ok(res);
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import win.liyufan.im.GitRepositoryState;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.Base64;
|
||||
@@ -53,7 +54,7 @@ public class GetIMTokenAction extends AdminAction {
|
||||
|
||||
LOG.info("get im token success {},{},{}", userId, input.getClientId(), token.substring(0, Math.min(10, token.length())));
|
||||
|
||||
return new Result(errorCode1, new OutputGetIMTokenData(userId, token));
|
||||
return new Result(errorCode1, new OutputGetIMTokenData(userId, token, GitRepositoryState.globalLabel));
|
||||
} else {
|
||||
return new Result(errorCode1);
|
||||
}
|
||||
|
||||
@@ -105,18 +105,6 @@ abstract public class ChannelAction extends Action {
|
||||
response.send();
|
||||
}
|
||||
|
||||
protected <T> T getRequestBody(HttpRequest request, Class<T> cls) {
|
||||
if (request instanceof FullHttpRequest) {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = new String(bytes, StandardCharsets.UTF_8);
|
||||
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void sendApiMessage(Response response, String topic, byte[] message, Callback callback) {
|
||||
sendApiMessage(response, channelInfo.getOwner(), topic, message, callback);
|
||||
}
|
||||
|
||||
@@ -106,24 +106,6 @@ abstract public class RobotAction extends Action {
|
||||
response.send();
|
||||
}
|
||||
|
||||
protected <T> T getRequestBody(HttpRequest request, Class<T> cls) {
|
||||
if (request instanceof FullHttpRequest) {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = null;
|
||||
try {
|
||||
content = new String(bytes, "UTF-8");
|
||||
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void sendApiRequest(Response response, String topic, byte[] message, Callback callback) {
|
||||
ServerAPIHelper.sendRequest(robot.getUid(), null, topic, message, new ServerAPIHelper.Callback() {
|
||||
@Override
|
||||
|
||||
@@ -90,6 +90,7 @@ public final class BrokerConstants {
|
||||
|
||||
public static final String PUSH_ANDROID_SERVER_ADDRESS = "push.android.server.address";
|
||||
public static final String PUSH_IOS_SERVER_ADDRESS = "push.ios.server.address";
|
||||
public static final String PUSH_HARMONY_SERVER_ADDRESS = "push.harmony.server.address";
|
||||
|
||||
public static final String MONITOR_Exception_Event_Address = "monitor.exception_event_address";
|
||||
|
||||
@@ -151,8 +152,10 @@ public final class BrokerConstants {
|
||||
|
||||
public static final String MESSAGE_Disable_Stranger_Chat = "message.disable_stranger_chat";
|
||||
public static final String MESSAGE_Allow_Stranger_Chat_List = "message.allow_stranger_chat_list";
|
||||
public static final String MESSAGE_Allow_Stranger_Line = "message.allow_stranger_line";
|
||||
|
||||
public static final String MESSAGE_Blacklist_Strategy = "message.blacklist.strategy";
|
||||
public static final String MESSAGE_Blacklist_Allow_Send = "message.blacklist.allow_send_to_black";
|
||||
|
||||
public static final String MESSAGE_NO_Forward_Admin_Message = "message.no_forward_admin_message";
|
||||
|
||||
@@ -160,11 +163,20 @@ public final class BrokerConstants {
|
||||
public static final String MESSAGE_Force_Push_Types = "message.force_push_types";
|
||||
|
||||
public static final String MESSAGE_Forward_With_Client_Info = "message.forward_with_client_info";
|
||||
public static final String MESSAGE_Forward_With_Sender_Info = "message.forward_with_sender_info";
|
||||
public static final String MESSAGE_Forward_With_Target_Info = "message.forward_with_target_info";
|
||||
|
||||
public static final String BROADCAST_Target_From_User_Table = "message.broadcast.target_from_user_table";
|
||||
|
||||
public static final String MESSAGES_ALLOW_SEND_TO_FORBIDDEN_USER = "message.allow_send_to_forbidden_user";
|
||||
|
||||
public static final String ROBOT_Callback_With_Client_Info = "robot.callback_with_client_info";
|
||||
public static final String ROBOT_Callback_With_Sender_Info = "robot.callback_with_sender_info";
|
||||
public static final String ROBOT_Callback_With_Target_Info = "robot.callback_with_target_info";
|
||||
|
||||
public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_info";
|
||||
public static final String CHANNEL_Callback_With_Sender_Info = "channel.callback_with_sender_info";
|
||||
public static final String CHANNEL_Callback_With_Target_Info = "channel.callback_with_target_info";
|
||||
public static final String CHANNEL_New_Callback_Feature = "channel.new_callback_feature";
|
||||
|
||||
|
||||
@@ -175,6 +187,7 @@ public final class BrokerConstants {
|
||||
public static final String FRIEND_Repeat_Request_Duration = "friend.repeat_request_duration";
|
||||
public static final String FRIEND_Reject_Request_Duration = "friend.reject_request_duration";
|
||||
public static final String FRIEND_Request_Expiration_Duration = "friend.request_expiration_duration";
|
||||
public static final String FRIEND_Request_Rate_Limit = "friend.request_rate_limit";
|
||||
public static final String FRIEND_Request_Robot_Auto_Accept = "friend.robot_auto_accept";
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ public class AddFriendHandler extends GroupHandler<WFCMessage.AddFriendRequest>
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.AddFriendRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
long[] head = new long[1];
|
||||
boolean isAdmin = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Admin;
|
||||
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head, isAdmin);
|
||||
boolean isRobot = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Robot;
|
||||
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head, isAdmin, isRobot);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
WFCMessage.User user = m_messagesStore.getUserInfo(request.getTargetUid());
|
||||
if (user != null && user.getType() == ProtoConstants.UserType.UserType_Normal) {
|
||||
|
||||
@@ -43,7 +43,7 @@ public class AddGroupMember extends GroupHandler<WFCMessage.AddGroupMemberReques
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, getMemberIdList(request.getAddedMemberList())).getAddGroupNotifyContent();
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, getMemberIdList(request.getAddedMemberList())).setExtra(request.getExtra()).getAddGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import static cn.wildfirechat.proto.ProtoConstants.RequestSourceType.Request_From_Admin;
|
||||
import static win.liyufan.im.IMTopic.PutUserSettingTopic;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingMyChannels;
|
||||
|
||||
@@ -42,7 +43,13 @@ public class CreateChannelHandler extends GroupHandler<WFCMessage.ChannelInfo> {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingMyChannels).setKey(request.getTargetId()).setValue("1").build();
|
||||
mServer.onApiMessage(fromUser, null, modifyUserSettingReq.toByteArray(), 0, fromUser, PutUserSettingTopic, requestSourceType);
|
||||
byte[] data = request.getTargetId().getBytes();
|
||||
byte[] data;
|
||||
if (requestSourceType == Request_From_Admin) {
|
||||
//When server api create channel, need return channelId and secret together.
|
||||
data = (request.getTargetId() + "|" + request.getSecret()).getBytes();
|
||||
} else {
|
||||
data = request.getTargetId().getBytes();
|
||||
}
|
||||
ackPayload.ensureWritable(data.length).writeBytes(data);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
} else {
|
||||
|
||||
@@ -63,7 +63,7 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").getCreateGroupNotifyContent();
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").setExtra(request.getMemberExtra()).getCreateGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), content);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,9 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
private Set<Integer> mForwardExcludeMessageTypes = new HashSet<>();
|
||||
private String mMentionForwardUrl = null;
|
||||
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
|
||||
private boolean mBlacklistAllowSend2Black = true;
|
||||
private boolean mNoForwardAdminMessage = false;
|
||||
private boolean mAllowSend2ForbiddenUser = false;
|
||||
|
||||
private String mRemoteSensitiveServerUrl = null;
|
||||
private Set<Integer> mRemoteSensitiveMessageTypes;
|
||||
@@ -69,6 +71,12 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
mBlacklistAllowSend2Black = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Blacklist_Allow_Send, "true"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
mRemoteSensitiveServerUrl = mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Server_URL);
|
||||
if(!StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) {
|
||||
@@ -94,6 +102,9 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
mAllowSend2ForbiddenUser = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGES_ALLOW_SEND_TO_FORBIDDEN_USER, "false"));
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
private void parseTypes(Collection<Integer> collection, String types) {
|
||||
@@ -145,7 +156,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
|
||||
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
if(!m_messagesStore.getBlackListExceptionTypes().contains(message.getContent().getType())) {
|
||||
errorCode = m_messagesStore.isAllowUserMessage(message.getConversation().getTarget(), fromUser);
|
||||
errorCode = m_messagesStore.isAllowUserMessage(message.getConversation().getTarget(), fromUser, message.getConversation().getLine());
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_IN_BLACK_LIST && mBlacklistStrategy != ProtoConstants.BlacklistStrategy.Message_Reject) {
|
||||
ignoreMsg = true;
|
||||
@@ -154,11 +165,20 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
if(!mBlacklistAllowSend2Black) {
|
||||
errorCode = m_messagesStore.isBlacked(fromUser, message.getConversation().getTarget());
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
userStatus = m_messagesStore.getUserStatus(message.getConversation().getTarget());
|
||||
if (userStatus == ProtoConstants.UserStatus.Forbidden) {
|
||||
return ErrorCode.ERROR_CODE_USER_FORBIDDEN;
|
||||
if (!mAllowSend2ForbiddenUser) {
|
||||
userStatus = m_messagesStore.getUserStatus(message.getConversation().getTarget());
|
||||
if (userStatus == ProtoConstants.UserStatus.Forbidden) {
|
||||
return ErrorCode.ERROR_CODE_USER_FORBIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,20 +223,13 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
}
|
||||
message = message.toBuilder().setFromUser(fromUser).setMessageId(messageId).setServerTimestamp(timestamp).build();
|
||||
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isForwardMessageWithClientInfo() && requestSourceType == ProtoConstants.RequestSourceType.Request_From_User && !StringUtil.isNullOrEmpty(clientID)) {
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
|
||||
if(session != null && session.getUsername().equals(fromUser)) {
|
||||
outputClient = new OutputClient(session.getPlatform(), clientID);
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtil.isNullOrEmpty(mForwardUrl) && (mForwardMessageTypes.isEmpty() || mForwardMessageTypes.contains(message.getContent().getType())) && !(isAdmin && mNoForwardAdminMessage) && !mForwardExcludeMessageTypes.contains(message.getContent().getType())) {
|
||||
publisher.forwardMessage(message, mForwardUrl, outputClient);
|
||||
publisher.forwardMessage(message, mForwardUrl, clientID);
|
||||
}
|
||||
|
||||
if(!StringUtil.isNullOrEmpty(mMentionForwardUrl) && message.hasContent() && message.getContent().getMentionedType() != 0 && !(isAdmin && mNoForwardAdminMessage)) {
|
||||
publisher.forwardMessage(message, mMentionForwardUrl, outputClient);
|
||||
publisher.forwardMessage(message, mMentionForwardUrl, clientID);
|
||||
}
|
||||
|
||||
if (!isAdmin) {
|
||||
@@ -225,7 +238,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
m_messagesStore.storeSensitiveMessage(message);
|
||||
if (!StringUtil.isNullOrEmpty(mSensitiveMessageForwardUrl)) {
|
||||
publisher.forwardMessage(message, mSensitiveMessageForwardUrl, outputClient);
|
||||
publisher.forwardMessage(message, mSensitiveMessageForwardUrl, clientID);
|
||||
}
|
||||
if (mSensitiveType == 0) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
@@ -242,7 +255,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
} else {
|
||||
if(mRemoteSensitiveMessageTypes.contains(message.getContent().getType())) {
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
publisher.forwardMessageWithCallback(message, mRemoteSensitiveServerUrl, new HttpUtils.HttpCallback() {
|
||||
publisher.forwardMessageWithCallback(message, clientID, mRemoteSensitiveServerUrl, new HttpUtils.HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(String content) {
|
||||
if(StringUtil.isNullOrEmpty(content)) {
|
||||
|
||||
@@ -75,7 +75,7 @@ import static io.moquette.BrokerConstants.*;
|
||||
import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE;
|
||||
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
|
||||
import static cn.wildfirechat.pojos.MyInfoType.*;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingAddFriendNoVerify;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingAddFriendStrategy;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline;
|
||||
|
||||
public class MemoryMessagesStore implements IMessagesStore {
|
||||
@@ -155,6 +155,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private long mFriendRequestDuration = 7 * 24 * 60 * 60 * 1000;
|
||||
private long mFriendRejectDuration = 30 * 24 * 60 * 60 * 1000;
|
||||
private long mFriendRequestExpiration = 7 * 24 * 60 * 60 * 1000;
|
||||
private RateLimiter mFriendRateLimiter;
|
||||
private boolean mFriendRobotAutoAccept = true;
|
||||
|
||||
private long mPushExpiredTimes = 604800000L;
|
||||
@@ -164,6 +165,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private boolean mMobileDefaultSilentWhenPCOnline = true;
|
||||
private boolean mDisableStrangerChat = false;
|
||||
private Set<String> mAllowStrangerChatSet = new HashSet<>();
|
||||
private Set<Integer> mAllowStrangerLineSet = new HashSet<>();
|
||||
private boolean mDisableStrangerAddGroup = false;
|
||||
|
||||
private boolean mIDUseUUID = true;
|
||||
@@ -203,8 +205,16 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private boolean mBroadcastTargetFromUserTable = false;
|
||||
|
||||
private boolean mForwardMessageWithClientInfo = false;
|
||||
private boolean mForwardMessageWithSenderInfo = false;
|
||||
private boolean mForwardMessageWithTargetInfo = false;
|
||||
|
||||
private boolean mRobotCallbackWithClientInfo = false;
|
||||
private boolean mRobotCallbackWithSenderInfo = false;
|
||||
private boolean mRobotCallbackWithTargetInfo = false;
|
||||
|
||||
private boolean mChannelCallbackWithClientInfo = false;
|
||||
private boolean mChannelCallbackWithSenderInfo = false;
|
||||
private boolean mChannelCallbackWithTargetInfo = false;
|
||||
private boolean mChannelNewCallbackFeature = true;
|
||||
|
||||
private Set<Integer> mUserHideProperties = new HashSet<>();
|
||||
@@ -264,6 +274,18 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
String allowStrangerList = m_Server.getConfig().getProperty(BrokerConstants.MESSAGE_Allow_Stranger_Line);
|
||||
if(!StringUtil.isNullOrEmptyAfterTrim(allowStrangerList)) {
|
||||
allowStrangerList = allowStrangerList.replace(",", ",");
|
||||
for (String s : allowStrangerList.split(",")) {
|
||||
mAllowStrangerLineSet.add(Integer.parseInt(s.trim()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
String forcePushTypes = m_Server.getConfig().getProperty(BrokerConstants.MESSAGE_Force_Push_Types);
|
||||
if(!StringUtil.isNullOrEmptyAfterTrim(forcePushTypes)) {
|
||||
@@ -344,6 +366,13 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
printMissConfigLog(FRIEND_Request_Expiration_Duration, mFriendRequestExpiration + "");
|
||||
}
|
||||
|
||||
try {
|
||||
int friendRequestRateLimit = Integer.parseInt(m_Server.getConfig().getProperty(FRIEND_Request_Rate_Limit, "0"));
|
||||
if(friendRequestRateLimit > 0) {
|
||||
mFriendRateLimiter = new RateLimiter(86400, friendRequestRateLimit);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
mFriendRobotAutoAccept = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Request_Robot_Auto_Accept, "true"));
|
||||
@@ -587,9 +616,13 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
try {
|
||||
mForwardMessageWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mForwardMessageWithSenderInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Sender_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mForwardMessageWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Target_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mBroadcastTargetFromUserTable = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.BROADCAST_Target_From_User_Table, "false"));
|
||||
@@ -599,17 +632,27 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
try {
|
||||
mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotCallbackWithSenderInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Sender_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotCallbackWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Target_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
}
|
||||
try {
|
||||
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mChannelCallbackWithSenderInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Sender_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mChannelCallbackWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Target_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mChannelNewCallbackFeature = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_New_Callback_Feature, "true"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url);
|
||||
@@ -725,7 +768,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
pullType = ProtoConstants.PullType.Pull_Normal;
|
||||
} else if (type == ProtoConstants.ConversationType.ConversationType_ChatRoom) {
|
||||
boolean isDirect = !StringUtil.isNullOrEmpty(message.getToUser());
|
||||
boolean isDirect = !StringUtil.isNullOrEmpty(message.getToUser()) || !message.getToList().isEmpty();
|
||||
Collection<UserClientEntry> entries = getChatroomMembers(message.getConversation().getTarget());
|
||||
for (UserClientEntry entry : entries) {
|
||||
if (isDirect) {
|
||||
@@ -733,6 +776,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
notifyReceivers.add(message.getToUser());
|
||||
break;
|
||||
}
|
||||
if (message.getToList().contains(entry.userId)) {
|
||||
notifyReceivers.add(entry.userId);
|
||||
}
|
||||
} else {
|
||||
notifyReceivers.add(entry.userId);
|
||||
}
|
||||
@@ -876,11 +922,13 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
session.setPullHistoryMsg(true);
|
||||
}
|
||||
|
||||
long previousCurrent;
|
||||
while (true) {
|
||||
Map.Entry<Long, Long> entry = maps.higherEntry(current);
|
||||
if (entry == null) {
|
||||
break;
|
||||
}
|
||||
previousCurrent = current;
|
||||
current = entry.getKey();
|
||||
long targetMessageId = entry.getValue();
|
||||
|
||||
@@ -909,6 +957,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
if (size >= 512 * 1024) { //3M
|
||||
if(builder.getMessageCount() == 0){
|
||||
builder.addMessage(bundle.getMessage());
|
||||
} else {
|
||||
current = previousCurrent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1913,6 +1963,14 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
newInfoBuilder.setPrivateChat(Integer.parseInt(value));
|
||||
else if(modifyType == Modify_Group_Searchable)
|
||||
newInfoBuilder.setSearchable(Integer.parseInt(value));
|
||||
else if(modifyType == Modify_Group_Type) {
|
||||
int newType = Integer.parseInt(value);
|
||||
if(newType < 0 || newType > ProtoConstants.GroupType.GroupType_Organization) {
|
||||
LOG.error("modify group type failure, invalid group type {}", newType);
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
newInfoBuilder.setType(newType);
|
||||
}
|
||||
else
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
|
||||
@@ -2242,15 +2300,29 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
//check the new owner is in member list? is that necessary?
|
||||
long updateDt = System.currentTimeMillis();
|
||||
groupInfo = groupInfo.toBuilder().setOwner(newOwner).setUpdateDt(updateDt).setMemberUpdateDt(updateDt).build();
|
||||
mIMap.set(groupId, groupInfo);
|
||||
|
||||
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
|
||||
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
|
||||
if (members == null || members.size() == 0) {
|
||||
members = loadGroupMemberFromDB(hzInstance, groupId);
|
||||
}
|
||||
|
||||
boolean isNewOwnerInGroup = false;
|
||||
for (WFCMessage.GroupMember member : members) {
|
||||
if (member.getMemberId().equals(newOwner)) {
|
||||
if(member.getType() != GroupMemberType_Removed) {
|
||||
isNewOwnerInGroup = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!isNewOwnerInGroup) {
|
||||
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
|
||||
}
|
||||
|
||||
long updateDt = System.currentTimeMillis();
|
||||
groupInfo = groupInfo.toBuilder().setOwner(newOwner).setUpdateDt(updateDt).setMemberUpdateDt(updateDt).build();
|
||||
mIMap.set(groupId, groupInfo);
|
||||
|
||||
int modifyMemeberCount = 0;
|
||||
for (WFCMessage.GroupMember member : members) {
|
||||
if (modifyMemeberCount == 2) {
|
||||
@@ -2416,7 +2488,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
boolean isExpired = false;
|
||||
if (!canRecall && message.getFromUser().equals(operatorId)) {
|
||||
if (now - message.getServerTimestamp() > mRecallTimeLimit * 1000) {
|
||||
if (mRecallTimeLimit >= 0 && now - message.getServerTimestamp() > mRecallTimeLimit * 1000) {
|
||||
isExpired = true;
|
||||
} else {
|
||||
canRecall = true;
|
||||
@@ -3185,7 +3257,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode isAllowUserMessage(String targetUser, String fromUser) {
|
||||
public ErrorCode isAllowUserMessage(String targetUser, String fromUser, int line) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
|
||||
|
||||
@@ -3212,7 +3284,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
if (mDisableStrangerChat) {
|
||||
//在禁止私聊时,是否是允许私聊的用户id
|
||||
if(mAllowStrangerChatSet.contains(targetUser) || mAllowStrangerChatSet.contains(fromUser)) {
|
||||
if(mAllowStrangerChatSet.contains(targetUser) || mAllowStrangerChatSet.contains(fromUser) || mAllowStrangerLineSet.contains(line)) {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3236,6 +3308,30 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode isBlacked(String fromUser, String userId) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
|
||||
|
||||
Collection<FriendData> friendDatas = friendsMap.get(fromUser);
|
||||
|
||||
if (friendDatas == null || friendDatas.size() == 0) {
|
||||
friendDatas = loadFriend(friendsMap, fromUser);
|
||||
}
|
||||
|
||||
for (FriendData friendData : friendDatas) {
|
||||
if (friendData.getFriendUid().equals(userId)) {
|
||||
if (friendData.getBlacked() == 1) {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
synchronized Collection<FriendData> loadFriend(MultiMap<String, FriendData> friendsMap, String userId) {
|
||||
Collection<FriendData> friends = databaseStore.getPersistFriends(userId);
|
||||
if (friends != null) {
|
||||
@@ -3353,16 +3449,28 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin) {
|
||||
public ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin, boolean isRobot) {
|
||||
if (!isAdmin && mDisableFriendRequest) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
if(!isRobot && !isAdmin && mFriendRateLimiter != null) {
|
||||
if(!mFriendRateLimiter.isGranted(userId)) {
|
||||
LOG.error("User {} request add friend over frequency", userId);
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
MultiMap<String, WFCMessage.FriendRequest> requestMap = hzInstance.getMultiMap(USER_FRIENDS_REQUEST);
|
||||
|
||||
WFCMessage.UserSettingEntry userSettingData = getUserSetting(request.getTargetUid(), kUserSettingAddFriendNoVerify, "");
|
||||
WFCMessage.UserSettingEntry userSettingData = getUserSetting(request.getTargetUid(), kUserSettingAddFriendStrategy, "");
|
||||
boolean noVerify = userSettingData != null && "1".equals(userSettingData.getValue());
|
||||
boolean noAllow = userSettingData != null && "2".equals(userSettingData.getValue());
|
||||
|
||||
if(noAllow) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
Collection<WFCMessage.FriendRequest> requests = requestMap.get(userId);
|
||||
if (requests == null || requests.size() == 0) {
|
||||
@@ -4384,7 +4492,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
} else if(modifyType == Modify_Channel_Menu) {
|
||||
OutputGetChannelInfo.OutputMenuList outputMenuButtons = GsonUtil.gson.fromJson(value, OutputGetChannelInfo.OutputMenuList.class);
|
||||
if (!outputMenuButtons.isEmpty()) {
|
||||
for (OutputGetChannelInfo.OutputMenu outputMenuButton : outputMenuButtons) {
|
||||
for (PojoChannelMenu outputMenuButton : outputMenuButtons) {
|
||||
newInfoBuilder.addMenu(outputMenuButton.toPbInfo());
|
||||
}
|
||||
}
|
||||
@@ -4650,16 +4758,46 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return mForwardMessageWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForwardMessageWithSenderInfo() {
|
||||
return mForwardMessageWithSenderInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForwardMessageWithTargetInfo() {
|
||||
return mForwardMessageWithTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotCallbackWithClientInfo() {
|
||||
return mRobotCallbackWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotCallbackWithSenderInfo() {
|
||||
return mRobotCallbackWithSenderInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotCallbackWithTargetInfo() {
|
||||
return mRobotCallbackWithTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithClientInfo() {
|
||||
return mChannelCallbackWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithSenderInfo() {
|
||||
return mChannelCallbackWithSenderInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithTargetInfo() {
|
||||
return mChannelCallbackWithTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelNewCallbackFeature() {
|
||||
return mChannelNewCallbackFeature;
|
||||
|
||||
@@ -140,7 +140,7 @@ public class Server {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(instance::stopServer));
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(httpServer::shutdown));
|
||||
|
||||
System.out.println("Wildfire IM server start success...");
|
||||
System.out.println("Wildfire IM server start success.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -179,13 +179,14 @@ public interface IMessagesStore {
|
||||
void clearUserFriend(String userId);
|
||||
List<WFCMessage.FriendRequest> getFriendRequestList(String userId, long version);
|
||||
|
||||
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin);
|
||||
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin, boolean isRobot);
|
||||
ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin);
|
||||
ErrorCode deleteFriend(String userId, String friendUid, long[] head);
|
||||
ErrorCode blackUserRequest(String fromUser, String targetUserId, int status, long[] head);
|
||||
FriendData getFriendData(String fromUser, String targetUserId);
|
||||
ErrorCode SyncFriendRequestUnread(String userId, long unreadDt, long[] head);
|
||||
ErrorCode isAllowUserMessage(String fromUser, String userId);
|
||||
ErrorCode isAllowUserMessage(String fromUser, String userId, int line);
|
||||
ErrorCode isBlacked(String fromUser, String userId);
|
||||
ErrorCode setFriendAliasRequest(String fromUser, String targetUserId, String alias, long[] head);
|
||||
ErrorCode setFriendExtraRequest(String fromUser, String targetUserId, String extra, long[] head);
|
||||
|
||||
@@ -241,8 +242,16 @@ public interface IMessagesStore {
|
||||
int getGroupForbiddenClientOperation();
|
||||
|
||||
boolean isForwardMessageWithClientInfo();
|
||||
boolean isForwardMessageWithSenderInfo();
|
||||
boolean isForwardMessageWithTargetInfo();
|
||||
|
||||
boolean isRobotCallbackWithClientInfo();
|
||||
boolean isRobotCallbackWithSenderInfo();
|
||||
boolean isRobotCallbackWithTargetInfo();
|
||||
|
||||
boolean isChannelCallbackWithClientInfo();
|
||||
boolean isChannelCallbackWithSenderInfo();
|
||||
boolean isChannelCallbackWithTargetInfo();
|
||||
boolean isChannelNewCallbackFeature();
|
||||
|
||||
boolean isRobotAutoAcceptFriendRequest();
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
package io.moquette.spi.impl;
|
||||
|
||||
import cn.wildfirechat.pojos.OutputClient;
|
||||
import cn.wildfirechat.pojos.OutputMessageData;
|
||||
import org.json.simple.JSONObject;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import cn.wildfirechat.push.PushServer;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import io.moquette.persistence.*;
|
||||
import io.moquette.persistence.MemorySessionStore.Session;
|
||||
@@ -34,12 +33,14 @@ import io.moquette.spi.ISessionsStore;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.mqtt.*;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import win.liyufan.im.*;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -47,6 +48,7 @@ import java.util.concurrent.Executors;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ConversationType.*;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
|
||||
|
||||
public class MessagesPublisher {
|
||||
@@ -157,7 +159,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
}
|
||||
|
||||
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageId, Collection<String> receivers, String pushContent, String pushData, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag, boolean directing) {
|
||||
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageId, Collection<String> receivers, String pushContent, String pushData, long callStartUid, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag, boolean directing) {
|
||||
if (persistFlag == Transparent) {
|
||||
publishTransparentMessage2Receivers(messageId, receivers, pullType, exceptClientId);
|
||||
return;
|
||||
@@ -283,7 +285,7 @@ public class MessagesPublisher {
|
||||
|
||||
if (!user.equals(sender)) {
|
||||
WFCMessage.Conversation conversation;
|
||||
if (conversationType == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
if (conversationType == ConversationType_Private) {
|
||||
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(sender).build();
|
||||
} else {
|
||||
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build();
|
||||
@@ -398,7 +400,7 @@ public class MessagesPublisher {
|
||||
|
||||
if(!sendNameLoaded) {
|
||||
List<String> list = new ArrayList<>();
|
||||
senderName = getUserDisplayName(sender, conversationType == ProtoConstants.ConversationType.ConversationType_Group ? target : null, list);
|
||||
senderName = getUserDisplayName(sender, conversationType == ConversationType_Group ? target : null, list);
|
||||
if(!list.isEmpty()) {
|
||||
senderPortrait = list.get(0);
|
||||
}
|
||||
@@ -421,7 +423,7 @@ public class MessagesPublisher {
|
||||
name = fd.getAlias();
|
||||
}
|
||||
}
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageId, targetSession.getClientID(), pushContent, pushData, messageContentType, serverTime, name, senderPortrait, targetName, targetPortrait, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageId, targetSession.getClientID(), pushContent, pushData, callStartUid, messageContentType, serverTime, name, senderPortrait, targetName, targetPortrait, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -451,6 +453,7 @@ public class MessagesPublisher {
|
||||
WFCMessage.Message message = m_messagesStore.getMessage(messageHead);
|
||||
|
||||
if (message != null) {
|
||||
message = message.toBuilder().setMessageId(0).build();
|
||||
for (String user : receivers) {
|
||||
Collection<Session> sessions = m_sessionsStore.sessionForUser(user);
|
||||
|
||||
@@ -485,19 +488,10 @@ public class MessagesPublisher {
|
||||
if (userInfo != null && userInfo.getType() == ProtoConstants.UserType.UserType_Robot) {
|
||||
WFCMessage.Robot robot = m_messagesStore.getRobot(user);
|
||||
if (robot != null && !StringUtil.isNullOrEmpty(robot.getCallback())) {
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isRobotCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
|
||||
Session session = m_sessionsStore.getSession(exceptClientId);
|
||||
if(session != null && session.getUsername().equals(message.getFromUser())) {
|
||||
outputClient = new OutputClient(session.getPlatform(), exceptClientId);
|
||||
}
|
||||
}
|
||||
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
OutputClient finalOutputClient = outputClient;
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, exceptClientId, m_messagesStore.isRobotCallbackWithClientInfo() , m_messagesStore.isRobotCallbackWithSenderInfo(), m_messagesStore.isRobotCallbackWithTargetInfo());
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(finalMsg, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(outputMessageData, OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -529,9 +523,9 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
String getTargetName(String targetId, int cnvType, String fromUser, List<String> portraitList) {
|
||||
if (cnvType == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
if (cnvType == ConversationType_Private) {
|
||||
return getUserDisplayName(targetId, null, portraitList);
|
||||
} else if(cnvType == ProtoConstants.ConversationType.ConversationType_Group) {
|
||||
} else if(cnvType == ConversationType_Group) {
|
||||
WFCMessage.GroupInfo group = m_messagesStore.getGroupInfo(targetId);
|
||||
if(group != null) {
|
||||
if(!StringUtil.isNullOrEmpty(group.getPortrait())) {
|
||||
@@ -544,7 +538,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
return group.getName();
|
||||
}
|
||||
} else if(cnvType == ProtoConstants.ConversationType.ConversationType_Channel) {
|
||||
} else if(cnvType == ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(targetId);
|
||||
if (channelInfo != null) {
|
||||
if(!StringUtil.isNullOrEmpty(channelInfo.getPortrait())) {
|
||||
@@ -666,7 +660,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
public void publish2Receivers(WFCMessage.Message message, Set<String> receivers, String exceptClientId, int pullType) {
|
||||
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
|
||||
if (message.getConversation().getType() == ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
|
||||
|
||||
boolean forwardMsg;
|
||||
@@ -677,18 +671,10 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
if (forwardMsg) {
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isChannelCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
|
||||
Session session = m_sessionsStore.getSession(exceptClientId);
|
||||
if(session != null && session.getUsername().equals(message.getFromUser())) {
|
||||
outputClient = new OutputClient(session.getPlatform(), exceptClientId);
|
||||
}
|
||||
}
|
||||
|
||||
OutputClient finalOutputClient = outputClient;
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, exceptClientId, m_messagesStore.isChannelCallbackWithClientInfo() , m_messagesStore.isChannelCallbackWithSenderInfo(), m_messagesStore.isChannelCallbackWithTargetInfo());
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", GsonUtil.gson.toJson(outputMessageData, OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -732,18 +718,92 @@ public class MessagesPublisher {
|
||||
pushContent = null;
|
||||
}
|
||||
|
||||
long callStartUid = 0;
|
||||
if (message.getContent().getType() == 402) {
|
||||
try {
|
||||
String str = new String(message.getContent().getData().toByteArray(), StandardCharsets.UTF_8);
|
||||
JSONObject jsonObject = (JSONObject)(new JSONParser().parse(str));
|
||||
if (jsonObject.containsKey("u")) {
|
||||
callStartUid = (Long)jsonObject.get("u");
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
|
||||
publish2Receivers(message.getFromUser(),
|
||||
message.getConversation().getType(), message.getConversation().getTarget(), message.getConversation().getLine(),
|
||||
messageId,
|
||||
receivers,
|
||||
pushContent, message.getContent().getPushData(), exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag(), message.hasToUser() || !message.getToList().isEmpty());
|
||||
pushContent, message.getContent().getPushData(), callStartUid, exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag(), message.hasToUser() || !message.getToList().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
public void forwardMessage(final WFCMessage.Message message, String forwardUrl, OutputClient outputClient) {
|
||||
private OutputMessageData getOutputMessageWithExtraInfo(WFCMessage.Message message, String clientId, boolean withClient, boolean withSender, boolean withTarget) {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
OutputClient outputClient = null;
|
||||
if (withClient && !StringUtil.isNullOrEmpty(clientId)) {
|
||||
Session session = m_sessionsStore.getSession(clientId);
|
||||
if(session != null && session.getUsername().equals(message.getFromUser())) {
|
||||
outputClient = new OutputClient(session.getPlatform(), clientId);
|
||||
}
|
||||
}
|
||||
|
||||
OutputMessageData outputMessageData = OutputMessageData.fromProtoMessage(message, outputClient);
|
||||
if (withSender) {
|
||||
WFCMessage.User senderInfo = m_messagesStore.getUserInfo(message.getFromUser());
|
||||
outputMessageData.setSenderUserInfo(InputOutputUserInfo.fromPbUser(senderInfo));
|
||||
}
|
||||
|
||||
if (withTarget) {
|
||||
if (message.getConversation().getType() == ConversationType_Private) {
|
||||
WFCMessage.User targetInfo = m_messagesStore.getUserInfo(message.getConversation().getTarget());
|
||||
if (targetInfo != null) {
|
||||
outputMessageData.setTargetUserInfo(InputOutputUserInfo.fromPbUser(targetInfo));
|
||||
}
|
||||
} else if(message.getConversation().getType() == ConversationType_Group) {
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.getGroupInfo(message.getConversation().getTarget());
|
||||
if (groupInfo != null) {
|
||||
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
|
||||
pojoGroupInfo.setExtra(groupInfo.getExtra());
|
||||
pojoGroupInfo.setName(groupInfo.getName());
|
||||
pojoGroupInfo.setOwner(groupInfo.getOwner());
|
||||
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
|
||||
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
|
||||
pojoGroupInfo.setType(groupInfo.getType());
|
||||
pojoGroupInfo.setMember_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setMute(groupInfo.getMute());
|
||||
pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
|
||||
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
|
||||
pojoGroupInfo.setSearchable(groupInfo.getSearchable());
|
||||
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
|
||||
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
|
||||
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
|
||||
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
|
||||
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
|
||||
outputMessageData.setTargetGroupInfo(pojoGroupInfo);
|
||||
}
|
||||
} else if(message.getConversation().getType() == ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo targetInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
|
||||
if (targetInfo != null) {
|
||||
outputMessageData.setTargetChannelInfo(OutputGetChannelInfo.fromPbInfo(targetInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outputMessageData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void forwardMessage(final WFCMessage.Message message, String forwardUrl, String fromClientId) {
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, fromClientId, m_messagesStore.isForwardMessageWithClientInfo() , m_messagesStore.isForwardMessageWithSenderInfo(), m_messagesStore.isForwardMessageWithTargetInfo());
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message, outputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(outputMessageData), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -751,9 +811,10 @@ public class MessagesPublisher {
|
||||
});
|
||||
}
|
||||
|
||||
public void forwardMessageWithCallback(final WFCMessage.Message message, String forwardUrl, HttpUtils.HttpCallback callback) {
|
||||
public void forwardMessageWithCallback(final WFCMessage.Message message, String fromClientId, String forwardUrl, HttpUtils.HttpCallback callback) {
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, fromClientId, m_messagesStore.isForwardMessageWithClientInfo() , m_messagesStore.isForwardMessageWithSenderInfo(), m_messagesStore.isForwardMessageWithTargetInfo());
|
||||
try {
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), new HttpUtils.HttpCallback() {
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(outputMessageData), new HttpUtils.HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(String content) {
|
||||
Server.getServer().getImBusinessScheduler().execute(()->{
|
||||
|
||||
@@ -37,12 +37,13 @@ class PersistentQueueMessageSender {
|
||||
this.connectionDescriptorStore = connectionDescriptorStore;
|
||||
}
|
||||
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageId, String deviceId, String pushContent, String pushData, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageId, String deviceId, String pushContent, String pushData, long callStartUid, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
|
||||
LOG.info("Send push to {}, message from {}", deviceId, sender);
|
||||
PushMessage pushMessage = new PushMessage(sender, conversationType, target, line, messageContentType, serverTime, senderName, senderPortrait, targetName, targetPortrait, unReceivedMsg, mentionType, isHiddenDetail, language);
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.pushData = pushData;
|
||||
pushMessage.messageId = messageId;
|
||||
pushMessage.callStartUid = callStartUid;
|
||||
PushServer.getServer().pushMessage(pushMessage, deviceId, pushContent);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import io.moquette.server.Server;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GitRepositoryState {
|
||||
public final String tags;
|
||||
@@ -28,6 +29,8 @@ public class GitRepositoryState {
|
||||
public final String commitMessageFull;
|
||||
public final String commitMessageShort;
|
||||
public final String commitTime;
|
||||
public static final String globalLabel = UUID.randomUUID().toString();
|
||||
public String label;
|
||||
public final String closestTagName;
|
||||
public final String closestTagCommitCount;
|
||||
|
||||
@@ -63,6 +66,7 @@ public class GitRepositoryState {
|
||||
this.buildHost = String.valueOf(properties.get("git.build.host"));
|
||||
this.buildVersion = String.valueOf(properties.get("git.build.version"));
|
||||
this.runTime = Server.getServer().getRunTime();
|
||||
this.label = globalLabel;
|
||||
}
|
||||
|
||||
public static GitRepositoryState getGitRepositoryState() throws IOException {
|
||||
|
||||
@@ -20,5 +20,5 @@ public interface UserSettingScope {
|
||||
int kUserSettingPttSilent = 25;
|
||||
int kUserSettingGroupRemark = 26;
|
||||
int kUserSettingPrivacySearchable = 27;
|
||||
int kUserSettingAddFriendNoVerify = 28;
|
||||
int kUserSettingAddFriendStrategy = 28;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.2.9</version>
|
||||
<version>1.3.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ public interface APIPath {
|
||||
|
||||
String Handle_Friend_Send_Request = "/admin/friend/handle_send_request";
|
||||
|
||||
String Admin_Moments_Post_Feed = "/admin/moments/feed/post";
|
||||
|
||||
String Msg_Send = "/admin/message/send";
|
||||
String Msg_Publish = "/admin/message/publish";
|
||||
String Msg_Recall = "/admin/message/recall";
|
||||
@@ -71,6 +73,8 @@ public interface APIPath {
|
||||
String Msg_Multicast = "/admin/message/multicast";
|
||||
String Msg_RecallBroadCast = "/admin/message/recall_broadcast";
|
||||
String Msg_RecallMultiCast = "/admin/message/recall_multicast";
|
||||
String Msg_DeleteBroadCast = "/admin/message/delete_broadcast";
|
||||
String Msg_DeleteMultiCast = "/admin/message/delete_multicast";
|
||||
String Msg_ConvRead = "/admin/message/conv_read";
|
||||
String Msg_Delivery = "/admin/message/delivery";
|
||||
String Conversation_Delete = "/admin/conversation/delete";
|
||||
@@ -155,5 +159,17 @@ public interface APIPath {
|
||||
String Robot_Group_Transfer = "/robot/group/transfer";
|
||||
String Robot_Group_Set_Manager = "/robot/group/manager/set";
|
||||
|
||||
String Robot_Moments_Post_Feed = "/robot/moments/feed/post";
|
||||
String Robot_Moments_Pull_Feeds = "/robot/moments/feed/pull";
|
||||
String Robot_Moments_Update_Feed = "/robot/moments/feed/update";
|
||||
String Robot_Moments_Post_Comment = "/robot/moments/comment/post";
|
||||
String Robot_Moments_Pull_Comment = "/robot/moments/comment/pull";
|
||||
String Robot_Moments_Fetch_Feed = "/robot/moments/feed/pull_one";
|
||||
String Robot_Moments_Fetch_Profiles = "/robot/moments/profiles/pull";
|
||||
String Robot_Moments_Recall_Comment = "/robot/moments/comment/recall";
|
||||
String Robot_Moments_Recall_Feed = "/robot/moments/feed/recall";
|
||||
String Robot_Moments_Update_Profiles_List_Value = "/robot/moments/profiles/list/push";
|
||||
String Robot_Moments_Update_Profiles_Value = "/robot/moments/profiles/value/push";
|
||||
|
||||
String Robot_Conference_Request = "/robot/conference/request";
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,6 +33,8 @@ public class GroupNotificationBinaryContent {
|
||||
//value2(member or something)
|
||||
private String m;
|
||||
|
||||
private String extra;
|
||||
|
||||
public GroupNotificationBinaryContent() {
|
||||
}
|
||||
|
||||
@@ -89,8 +92,18 @@ public class GroupNotificationBinaryContent {
|
||||
this.ms = ms;
|
||||
}
|
||||
|
||||
public GroupNotificationBinaryContent setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WFCMessage.MessageContent getGroupNotifyContent(int groupContentType) {
|
||||
return WFCMessage.MessageContent.newBuilder().setType(groupContentType).setData(ByteString.copyFromUtf8(new GsonBuilder().disableHtmlEscaping().create().toJson(this))).build();
|
||||
WFCMessage.MessageContent.Builder builder = WFCMessage.MessageContent.newBuilder().setType(groupContentType).setData(ByteString.copyFromUtf8(new GsonBuilder().disableHtmlEscaping().create().toJson(this)));
|
||||
if(!StringUtil.isNullOrEmpty(extra)) {
|
||||
builder.setExtra(extra);
|
||||
}
|
||||
return builder.build();
|
||||
|
||||
}
|
||||
|
||||
public WFCMessage.MessageContent getAddGroupNotifyContent() {
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.List;
|
||||
public class InputAddGroupMember extends InputGroupBase {
|
||||
private String group_id;
|
||||
private List<PojoGroupMember> members;
|
||||
private String member_extra;
|
||||
|
||||
public String getGroup_id() {
|
||||
return group_id;
|
||||
@@ -34,6 +35,14 @@ public class InputAddGroupMember extends InputGroupBase {
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public String getMember_extra() {
|
||||
return member_extra;
|
||||
}
|
||||
|
||||
public void setMemberExtra(String extra) {
|
||||
this.member_extra = extra;
|
||||
}
|
||||
|
||||
public boolean isValide() {
|
||||
return true;
|
||||
}
|
||||
@@ -41,6 +50,9 @@ public class InputAddGroupMember extends InputGroupBase {
|
||||
public WFCMessage.AddGroupMemberRequest toProtoGroupRequest() {
|
||||
WFCMessage.AddGroupMemberRequest.Builder addGroupBuilder = WFCMessage.AddGroupMemberRequest.newBuilder();
|
||||
addGroupBuilder.setGroupId(group_id);
|
||||
if(!StringUtil.isNullOrEmpty(member_extra)) {
|
||||
addGroupBuilder.setExtra(member_extra);
|
||||
}
|
||||
for (PojoGroupMember pojoGroupMember : getMembers()) {
|
||||
WFCMessage.GroupMember.Builder groupMemberBuilder = WFCMessage.GroupMember.newBuilder().setMemberId(pojoGroupMember.getMember_id());
|
||||
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getAlias())) {
|
||||
|
||||
@@ -12,6 +12,9 @@ package cn.wildfirechat.pojos;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InputCreateChannel {
|
||||
private String owner;
|
||||
private String name;
|
||||
@@ -24,6 +27,7 @@ public class InputCreateChannel {
|
||||
private int state;
|
||||
private String extra;
|
||||
private long updateDt;
|
||||
public List<PojoChannelMenu> menus;
|
||||
|
||||
public WFCMessage.ChannelInfo toProtoChannelInfo() {
|
||||
WFCMessage.ChannelInfo.Builder builder = WFCMessage.ChannelInfo.newBuilder().setOwner(owner);
|
||||
@@ -48,6 +52,12 @@ public class InputCreateChannel {
|
||||
else
|
||||
builder = builder.setUpdateDt(System.currentTimeMillis());
|
||||
|
||||
if (menus != null && !menus.isEmpty()) {
|
||||
for (PojoChannelMenu menu : menus) {
|
||||
builder.addMenu(menu.toPbInfo());
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,10 @@ import java.util.List;
|
||||
|
||||
public class InputCreateGroup extends InputGroupBase {
|
||||
private PojoGroup group;
|
||||
private String member_extra;
|
||||
|
||||
public boolean isValide() {
|
||||
return true;
|
||||
return !StringUtil.isNullOrEmpty(operator) && group != null;
|
||||
}
|
||||
|
||||
public WFCMessage.CreateGroupRequest toProtoGroupRequest() {
|
||||
@@ -87,6 +88,9 @@ public class InputCreateGroup extends InputGroupBase {
|
||||
|
||||
WFCMessage.CreateGroupRequest.Builder createGroupReqBuilder = WFCMessage.CreateGroupRequest.newBuilder();
|
||||
createGroupReqBuilder.setGroup(groupBuilder);
|
||||
if(!StringUtil.isNullOrEmpty(member_extra)) {
|
||||
createGroupReqBuilder.setMemberExtra(member_extra);
|
||||
}
|
||||
if (to_lines != null) {
|
||||
for (Integer line : to_lines
|
||||
) {
|
||||
@@ -107,4 +111,12 @@ public class InputCreateGroup extends InputGroupBase {
|
||||
public void setGroup(PojoGroup group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public String getMember_extra() {
|
||||
return member_extra;
|
||||
}
|
||||
|
||||
public void setMember_extra(String member_extra) {
|
||||
this.member_extra = member_extra;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InputStringList {
|
||||
private List<String> list;
|
||||
|
||||
public InputStringList() {
|
||||
}
|
||||
|
||||
public InputStringList(List<String> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public List<String> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<String> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,11 @@ import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
public class OutputCreateChannel {
|
||||
private String targetId;
|
||||
private String secret;
|
||||
|
||||
public OutputCreateChannel(String targetId) {
|
||||
public OutputCreateChannel(String targetId, String secret) {
|
||||
this.targetId = targetId;
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getTargetId() {
|
||||
@@ -25,4 +27,12 @@ public class OutputCreateChannel {
|
||||
public void setTargetId(String targetId) {
|
||||
this.targetId = targetId;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,61 +16,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OutputGetChannelInfo {
|
||||
public static class OutputMenu {
|
||||
public String menuId;
|
||||
public String type;
|
||||
public String name;
|
||||
public String key;
|
||||
public String url;
|
||||
public String mediaId;
|
||||
public String articleId;
|
||||
public String appId;
|
||||
public String appPage;
|
||||
public String extra;
|
||||
public List<OutputMenu> subMenus;
|
||||
|
||||
public static OutputMenu fromPbInfo(WFCMessage.ChannelMenu channelMenuMenu) {
|
||||
OutputMenu out = new OutputMenu();
|
||||
out.menuId = channelMenuMenu.getMenuId();
|
||||
out.type = channelMenuMenu.getType();
|
||||
out.name = channelMenuMenu.getName();
|
||||
out.key = channelMenuMenu.getKey();
|
||||
out.url = channelMenuMenu.getUrl();
|
||||
out.mediaId = channelMenuMenu.getMediaId();
|
||||
out.articleId = channelMenuMenu.getArticleId();
|
||||
out.appId = channelMenuMenu.getAppId();
|
||||
out.appPage = channelMenuMenu.getAppPage();
|
||||
out.extra = channelMenuMenu.getExtra();
|
||||
if (channelMenuMenu.getSubMenuCount() > 0) {
|
||||
out.subMenus = new ArrayList<>();
|
||||
for (WFCMessage.ChannelMenu menuMenu : channelMenuMenu.getSubMenuList()) {
|
||||
out.subMenus.add(fromPbInfo(menuMenu));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public WFCMessage.ChannelMenu.Builder toPbInfo() {
|
||||
WFCMessage.ChannelMenu.Builder builder = WFCMessage.ChannelMenu.newBuilder();
|
||||
builder.setType(type);
|
||||
builder.setName(name);
|
||||
if (!StringUtil.isNullOrEmpty(menuId)) builder.setMenuId(menuId);
|
||||
if (!StringUtil.isNullOrEmpty(key)) builder.setKey(key);
|
||||
if (!StringUtil.isNullOrEmpty(url)) builder.setUrl(url);
|
||||
if (!StringUtil.isNullOrEmpty(mediaId)) builder.setMediaId(mediaId);
|
||||
if (!StringUtil.isNullOrEmpty(articleId)) builder.setArticleId(articleId);
|
||||
if (!StringUtil.isNullOrEmpty(appId)) builder.setAppId(appId);
|
||||
if (!StringUtil.isNullOrEmpty(appPage)) builder.setAppPage(appPage);
|
||||
if (!StringUtil.isNullOrEmpty(extra)) builder.setExtra(extra);
|
||||
if (subMenus != null && !subMenus.isEmpty()) {
|
||||
subMenus.forEach(menuMenu -> builder.addSubMenu(menuMenu.toPbInfo()));
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OutputMenuList extends ArrayList<OutputMenu> {
|
||||
|
||||
public static class OutputMenuList extends ArrayList<PojoChannelMenu> {
|
||||
}
|
||||
|
||||
private String channelId;
|
||||
@@ -85,7 +31,7 @@ public class OutputGetChannelInfo {
|
||||
private String callback;
|
||||
private int automatic;
|
||||
private String secret;
|
||||
public List<OutputMenu> menus;
|
||||
public List<PojoChannelMenu> menus;
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
@@ -200,7 +146,7 @@ public class OutputGetChannelInfo {
|
||||
if (channelInfo.getMenuCount() > 0) {
|
||||
out.menus = new ArrayList<>();
|
||||
for (WFCMessage.ChannelMenu channelMenuMenu : channelInfo.getMenuList()) {
|
||||
out.menus.add(OutputMenu.fromPbInfo(channelMenuMenu));
|
||||
out.menus.add(PojoChannelMenu.fromPbInfo(channelMenuMenu));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
||||
@@ -3,13 +3,15 @@ package cn.wildfirechat.pojos;
|
||||
public class OutputGetIMTokenData {
|
||||
private String userId;
|
||||
private String token;
|
||||
private String serverLabel;
|
||||
|
||||
public OutputGetIMTokenData() {
|
||||
}
|
||||
|
||||
public OutputGetIMTokenData(String userId, String imToken) {
|
||||
public OutputGetIMTokenData(String userId, String imToken, String label) {
|
||||
this.userId = userId;
|
||||
this.token = imToken;
|
||||
this.serverLabel = label;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
@@ -27,4 +29,12 @@ public class OutputGetIMTokenData {
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getServerLabel() {
|
||||
return serverLabel;
|
||||
}
|
||||
|
||||
public void setServerLabel(String serverLabel) {
|
||||
this.serverLabel = serverLabel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ public class OutputMessageData {
|
||||
private long timestamp;
|
||||
private OutputClient client;
|
||||
|
||||
private InputOutputUserInfo senderUserInfo;
|
||||
private InputOutputUserInfo targetUserInfo;
|
||||
private PojoGroupInfo targetGroupInfo;
|
||||
private OutputGetChannelInfo targetChannelInfo;
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
@@ -78,6 +83,38 @@ public class OutputMessageData {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public InputOutputUserInfo getSenderUserInfo() {
|
||||
return senderUserInfo;
|
||||
}
|
||||
|
||||
public void setSenderUserInfo(InputOutputUserInfo senderUserInfo) {
|
||||
this.senderUserInfo = senderUserInfo;
|
||||
}
|
||||
|
||||
public InputOutputUserInfo getTargetUserInfo() {
|
||||
return targetUserInfo;
|
||||
}
|
||||
|
||||
public void setTargetUserInfo(InputOutputUserInfo targetUserInfo) {
|
||||
this.targetUserInfo = targetUserInfo;
|
||||
}
|
||||
|
||||
public PojoGroupInfo getTargetGroupInfo() {
|
||||
return targetGroupInfo;
|
||||
}
|
||||
|
||||
public void setTargetGroupInfo(PojoGroupInfo targetGroupInfo) {
|
||||
this.targetGroupInfo = targetGroupInfo;
|
||||
}
|
||||
|
||||
public OutputGetChannelInfo getTargetChannelInfo() {
|
||||
return targetChannelInfo;
|
||||
}
|
||||
|
||||
public void setTargetChannelInfo(OutputGetChannelInfo targetChannelInfo) {
|
||||
this.targetChannelInfo = targetChannelInfo;
|
||||
}
|
||||
|
||||
public static OutputMessageData fromProtoMessage(WFCMessage.Message protoMessage) {
|
||||
return fromProtoMessage(protoMessage, null);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PojoChannelMenu {
|
||||
public String menuId;
|
||||
public String type;
|
||||
public String name;
|
||||
public String key;
|
||||
public String url;
|
||||
public String mediaId;
|
||||
public String articleId;
|
||||
public String appId;
|
||||
public String appPage;
|
||||
public String extra;
|
||||
public List<PojoChannelMenu> subMenus;
|
||||
|
||||
public static PojoChannelMenu fromPbInfo(WFCMessage.ChannelMenu channelMenuMenu) {
|
||||
PojoChannelMenu out = new PojoChannelMenu();
|
||||
out.menuId = channelMenuMenu.getMenuId();
|
||||
out.type = channelMenuMenu.getType();
|
||||
out.name = channelMenuMenu.getName();
|
||||
out.key = channelMenuMenu.getKey();
|
||||
out.url = channelMenuMenu.getUrl();
|
||||
out.mediaId = channelMenuMenu.getMediaId();
|
||||
out.articleId = channelMenuMenu.getArticleId();
|
||||
out.appId = channelMenuMenu.getAppId();
|
||||
out.appPage = channelMenuMenu.getAppPage();
|
||||
out.extra = channelMenuMenu.getExtra();
|
||||
if (channelMenuMenu.getSubMenuCount() > 0) {
|
||||
out.subMenus = new ArrayList<>();
|
||||
for (WFCMessage.ChannelMenu menuMenu : channelMenuMenu.getSubMenuList()) {
|
||||
out.subMenus.add(fromPbInfo(menuMenu));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public WFCMessage.ChannelMenu.Builder toPbInfo() {
|
||||
WFCMessage.ChannelMenu.Builder builder = WFCMessage.ChannelMenu.newBuilder();
|
||||
builder.setType(type);
|
||||
builder.setName(name);
|
||||
if (!StringUtil.isNullOrEmpty(menuId)) builder.setMenuId(menuId);
|
||||
if (!StringUtil.isNullOrEmpty(key)) builder.setKey(key);
|
||||
if (!StringUtil.isNullOrEmpty(url)) builder.setUrl(url);
|
||||
if (!StringUtil.isNullOrEmpty(mediaId)) builder.setMediaId(mediaId);
|
||||
if (!StringUtil.isNullOrEmpty(articleId)) builder.setArticleId(articleId);
|
||||
if (!StringUtil.isNullOrEmpty(appId)) builder.setAppId(appId);
|
||||
if (!StringUtil.isNullOrEmpty(appPage)) builder.setAppPage(appPage);
|
||||
if (!StringUtil.isNullOrEmpty(extra)) builder.setExtra(extra);
|
||||
if (subMenus != null && !subMenus.isEmpty()) {
|
||||
subMenus.forEach(menuMenu -> builder.addSubMenu(menuMenu.toPbInfo()));
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommentMsgPojo {
|
||||
//commentId;
|
||||
public long commentId;
|
||||
|
||||
//sender;
|
||||
public String sender;
|
||||
|
||||
//timestamp
|
||||
public long serverTime;
|
||||
|
||||
//feedId
|
||||
public long feedId;
|
||||
|
||||
//type
|
||||
public int type;
|
||||
|
||||
//content
|
||||
public String text;
|
||||
|
||||
//to replyTo
|
||||
public String replyTo;
|
||||
|
||||
//extra
|
||||
public String extra;
|
||||
|
||||
public int ftype;
|
||||
|
||||
public String fcontent;
|
||||
|
||||
public String fsender;
|
||||
|
||||
public List<MediaEntry> fmedias;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class CommentPojo {
|
||||
//commentId;
|
||||
public long commentId;
|
||||
|
||||
//replyId;
|
||||
public long replyId;
|
||||
|
||||
//sender;
|
||||
public String sender;
|
||||
|
||||
//timestamp
|
||||
public long timestamp;
|
||||
|
||||
//feedId
|
||||
public long feedId;
|
||||
|
||||
//type
|
||||
public int type;
|
||||
|
||||
//content
|
||||
public String text;
|
||||
|
||||
//to replyTo
|
||||
public String replyTo;
|
||||
|
||||
//extra
|
||||
public String extra;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FeedPojo {
|
||||
//feedid
|
||||
public long feedId;
|
||||
|
||||
//sender
|
||||
public String sender;
|
||||
|
||||
//timestamp
|
||||
public long timestamp;
|
||||
|
||||
//type
|
||||
public int type;
|
||||
|
||||
//content
|
||||
public String text;
|
||||
|
||||
//media urls
|
||||
public List<MediaEntry> medias;
|
||||
|
||||
//to users
|
||||
public List<String> to;
|
||||
|
||||
//excloud users
|
||||
public List<String> ex;
|
||||
|
||||
//mentioned users
|
||||
public List<String> mu;
|
||||
|
||||
//extra
|
||||
public String extra;
|
||||
|
||||
public List<CommentPojo> comments;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FeedsPojo {
|
||||
public List<FeedPojo> feeds;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class IdPojo {
|
||||
//feedid
|
||||
public long id;
|
||||
|
||||
//feedid
|
||||
public long id2;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class MediaEntry {
|
||||
public String m;
|
||||
public String t;
|
||||
public int w;
|
||||
public int h;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MomentProfilePojo {
|
||||
public String bgUrl;
|
||||
public List<String> blackList;
|
||||
public List<String> blockList;
|
||||
//stranger visiable count
|
||||
public int svc;
|
||||
public int visiableScope;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class PostFeedResult {
|
||||
public long id;
|
||||
public long timestamp;
|
||||
|
||||
public PostFeedResult(long id, long timestamp) {
|
||||
this.id = id;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PullCommentsRequestPojo {
|
||||
public static class IdPair {
|
||||
public long fid;
|
||||
public long cid;
|
||||
}
|
||||
public List<IdPair> ids;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class PullFeedRequestPojo {
|
||||
//feedid
|
||||
public long feedId;
|
||||
public int count;
|
||||
public String user;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class PullOneFeedRequestPojo {
|
||||
public long feedId;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class PullProfileRequestPojo {
|
||||
//userId
|
||||
public String u;
|
||||
|
||||
//update date
|
||||
public long d;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PushProfileListRequestPojo {
|
||||
//block or black
|
||||
public boolean b;
|
||||
|
||||
//add user list
|
||||
public List<String> al;
|
||||
|
||||
//remove user list
|
||||
public List<String> rl;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.wildfirechat.pojos.moments;
|
||||
|
||||
public class PushProfileValueRequestPojo {
|
||||
/*
|
||||
WFMUpdateUserProfileType_BackgroudUrl,
|
||||
WFMUpdateUserProfileType_StrangerVisiableCount,
|
||||
WFMUpdateUserProfileType_VisiableScope
|
||||
*/
|
||||
public int t;
|
||||
|
||||
//string value depends on t
|
||||
public String v;
|
||||
|
||||
//int value depends on t
|
||||
public int i;
|
||||
}
|
||||
@@ -172,6 +172,7 @@ public class ProtoConstants {
|
||||
int Modify_Group_Max_Member_Count = 8;
|
||||
//仅专业版的server api支持
|
||||
int Modify_Group_Super_Group = 9;
|
||||
int Modify_Group_Type = 10;
|
||||
}
|
||||
|
||||
//ModifyGroupInfoRequest -> type
|
||||
@@ -347,6 +348,25 @@ public class ProtoConstants {
|
||||
int Forbidden_Mute_Group_Member = 0x800;
|
||||
}
|
||||
|
||||
public interface MomentsContentType {
|
||||
int Moments_Content_Text_Type = 0;
|
||||
int Moments_Content_Image_Type = 1;
|
||||
int Moments_Content_Video_Type = 2;
|
||||
int Moments_Content_Link_Type = 3;
|
||||
}
|
||||
|
||||
public interface MomentsCommentType {
|
||||
int Moments_Comment_Text_Type = 0;
|
||||
int Moments_Comment_Thumbup_Type = 1;
|
||||
}
|
||||
|
||||
public interface MomentsVisibleScope {
|
||||
int Moments_VisibleScope_NoLimit = 0;
|
||||
int Moments_VisibleScope_3Days = 1;
|
||||
int Moments_VisibleScope_1Month = 2;
|
||||
int Moments_VisibleScope_6Months = 3;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.2.9</version>
|
||||
<version>1.3.6</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>distribution</artifactId>
|
||||
|
||||
@@ -33,6 +33,8 @@ local_port 80
|
||||
## MySQL需要把事物隔离级别改成"Read committed",使用命令来修改"set global transaction_isolation='read-committed';",其他数据库默认已经是这个级别不用修改
|
||||
## 如果使用MySQL,请在c3p0.xml文件中配置JDBC信息。
|
||||
## 如果是MySQL5.7,需要开启长索引的支持,在数据库中执行命令:"set global innodb_large_prefix=on;"。其他版本默认支持,不用修改。
|
||||
## 如果使用MySQL 8.0.30以上版本,有个特性是创建表时如果没有主键将会自动创建一个主键"my_key_id",如果此功能打开,在执行mysql脚本V19__add_id_for_sensitive_word.sql时将会报错,提示不能2个主键。
|
||||
## 解决办法就是运行出错后删除掉系统自动创建的主键"my_key_id",然后继续执行。
|
||||
embed.db 1
|
||||
|
||||
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
|
||||
@@ -93,6 +95,9 @@ message.disable_stranger_chat false
|
||||
##当禁止陌生人聊天时,允许聊天的用户id,比如管理员或者文件传输助手等。用户id以英文逗号分割。
|
||||
message.allow_stranger_chat_list admin,FireRobot,wfc_file_transfer
|
||||
|
||||
##当禁止陌生人聊天时,允许聊天的线路。
|
||||
#message.allow_stranger_line 100,101
|
||||
|
||||
##黑名单策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃
|
||||
message.blacklist.strategy 0
|
||||
|
||||
@@ -103,7 +108,7 @@ message.disable_remote_search false
|
||||
##如果要避免数据库中明文存储消息内容,请打开这个开关和message.disable_remote_search开关
|
||||
message.encrypt_message_content false
|
||||
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。0是不允许撤回;-1是无限制撤回。
|
||||
##Server API不受此限制,可以撤回任意时限内的消息
|
||||
##群组管理员或群主撤回群成员消息不受此限制,可以撤回任意时限内的消息。但管理员或群主撤回自己的消息还是需要准守此时间限制。
|
||||
##修改此参数需要同步修改客户端UI,客户端UI代码有判断撤回是否显示的逻辑。
|
||||
@@ -144,12 +149,33 @@ message.no_forward_admin_message false
|
||||
## 消息转发功能开启时,转发信息是否带上用户clientId和平台类型。
|
||||
message.forward_with_client_info false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上发送者的用户信息
|
||||
message.forward_with_sender_info false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上目标的信息,单聊时是对方用户信息,群聊时是群组信息,频道时是频道信息
|
||||
message.forward_with_target_info false
|
||||
|
||||
## 允许发送单聊消息给被封禁用户
|
||||
message.allow_send_to_forbidden_user false
|
||||
|
||||
## 机器人回调信息是否带上用户clientId和平台类型。
|
||||
robot.callback_with_client_info false
|
||||
|
||||
## 机器人回调信息是否带上发送者的用户信息
|
||||
robot.callback_with_sender_info false
|
||||
|
||||
## 机器人回调信息是否带上目标的信息,单聊时是对方用户信息,群聊时是群组信息,频道时是频道信息
|
||||
robot.callback_with_target_info false
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
## 频道回调信息是否带上发送者的用户信息。
|
||||
channel.callback_with_sender_info false
|
||||
|
||||
## 频道回调信息是否带上频道信息
|
||||
channel.callback_with_target_info false
|
||||
|
||||
## 频道回调新方式,在新方式下,如果有callback地址就会总是回调客户端发送的消息(包括owner和订阅者)。automatic属性控制订阅者发送的消息是否发给owner, 0发,1不发。
|
||||
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
||||
channel.new_callback_feature true
|
||||
@@ -175,6 +201,9 @@ friend.reject_request_duration 2592000000
|
||||
##好友请求过期时间,单位是毫秒,默认是7天,0为无限长期限。
|
||||
friend.request_expiration_duration 604800000
|
||||
|
||||
##好友请求限制频率,一个用户24小时之内允许请求好友的次数,默认不限频。
|
||||
#friend.request_rate_limit 30
|
||||
|
||||
##请求添加机器人为好友时,机器人是否自动接受,默认为true
|
||||
friend.robot_auto_accept true
|
||||
|
||||
@@ -218,7 +247,7 @@ group.visible_quit_or_kickoff_notification 0
|
||||
group.disable_stranger_invite false
|
||||
|
||||
## 群组信息是否标记删除
|
||||
group.enable_mark_deletion false
|
||||
group.enable_mark_deletion true
|
||||
|
||||
## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开;
|
||||
## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。
|
||||
@@ -319,7 +348,7 @@ server.mobile_default_silent_when_pc_online true
|
||||
|
||||
## 客户端是否支持kickoff事件。当客户端被其他端登录踢出时,如果此开关为false时,客户端协议栈上报secret_mismatch。如果此开关为ture时,客户端协议栈上报kicked_off。
|
||||
## 客户端被踢时上报kicked_off是在2021.9.15之后才加上的。如果客户端协议栈全部为此日期之后的版本才可以打开此开关。
|
||||
server.client_support_kickoff_event false
|
||||
server.client_support_kickoff_event true
|
||||
|
||||
#*********************************************************************
|
||||
# Push server configuration
|
||||
@@ -333,6 +362,10 @@ push.android.server.address http://localhost:8085/android/push
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
push.ios.server.address http://localhost:8085/ios/push
|
||||
|
||||
##鸿蒙推送服务器地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
push.harmony.server.address http://localhost:8085/harmony/push
|
||||
|
||||
#*********************************************************************
|
||||
# 监控配置
|
||||
#*********************************************************************
|
||||
@@ -416,7 +449,10 @@ push.ios.server.address http://localhost:8085/ios/push
|
||||
## 内置文本敏感词过滤处理方法,当命中敏感词后,消息会被记录到t_sensitive_messages表中,然后根据type类型做不同的处理,处理方式如下:
|
||||
## 0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***然后正常发送;3 正常发送。
|
||||
## 如果开启 message.sensitive.forward.url 配置,命中敏感词的消息还会被回调到这个地址
|
||||
sensitive.filter.type 0
|
||||
sensitive.filter.type 2
|
||||
|
||||
## 敏感词添加或者删除有2种方式,一种是通过Server API进行,这种方式会立即生效。另外一种方法是修改数据库,直接中数据库的t_sensitive_word表中处理
|
||||
## 修改数据库的方法不会立即生效,IM服务会2个小时重新加载一次敏感词。所以如果直接修改敏感词表,需要等2个小时,或者重启才能生效。
|
||||
|
||||
## 如果内置敏感词库无法满足您的需求,可以开发部署独立敏感词审核服务。配置如下地址和消息类型,IM服务会把指定消息类型的消息回调到指定地址,内置的敏感词审核和敏感词转发功能就不再起作用了。
|
||||
## 审核服务返回状态码200表示继续发送,如果需要替换内容,返回状态码200并且内容为替换后的内容。返回403表示不允许发送。其它错误继续发送。
|
||||
|
||||
@@ -75,11 +75,9 @@ rem set JAVA_OPTS=%JAVA_OPTS% -XX:GCLogFileSize=10M"
|
||||
rem If the JDK version is 9 or above, please open this configuration.
|
||||
rem set JAVA_OPTS=%JAVA_OPTS% --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED
|
||||
|
||||
echo
|
||||
echo "Please set Xmx and Xms parameters!"
|
||||
echo "Please set Xmx and Xms parameters!"
|
||||
echo "Please set Xmx and Xms parameters!"
|
||||
echo
|
||||
|
||||
rem set JAVA_OPTS=%JAVA_OPTS% -Xmx2G
|
||||
rem set JAVA_OPTS=%JAVA_OPTS% -Xms2G
|
||||
|
||||
@@ -90,7 +90,8 @@ JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=500"
|
||||
#JAVA_OPTS="$JAVA_OPTS --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED"
|
||||
|
||||
echo "警告:没有设置JVM内存参数!"
|
||||
echo "请设置JVM参数Xmx和Xms,设置为您为IM服务预留的内存大小,注意需要刨除操作系统占用,如果有其它系统也需要相应去除占用。"
|
||||
echo "请设置JVM参数Xmx和Xms,设置为您为IM服务预留的内存大小,注意需要刨除操作系统占用,如果有其它系统也需要相应去除占用,还需要减去堆外内存占用。"
|
||||
echo "建议设置为总内存的60%以下,比如16G总内存,Xmx可以设置为9G"
|
||||
echo ""
|
||||
#JAVA_OPTS="$JAVA_OPTS -Xmx2G"
|
||||
#JAVA_OPTS="$JAVA_OPTS -Xms2G"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>1.2.9</version>
|
||||
<version>1.3.6</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
@@ -12,6 +12,57 @@
|
||||
|
||||
# 更新记录
|
||||
|
||||
--------------
|
||||
Release note 1.3.6:
|
||||
1. Server API创建频道时,返回频道ID和频道密钥。
|
||||
2. 解决外置审核替换内容没有成功的问题。
|
||||
3. 修改撤回消息限制,可以运行不限制撤回。
|
||||
4. 创建/更新频道接口可以传菜单参数。
|
||||
5. Server API支持修改群组类型。
|
||||
|
||||
--------------
|
||||
Release note 1.3.5:
|
||||
1. 转发消息回调中可以配置带上发送者和目标信息。
|
||||
2. Server SDK中添加撤回和删除消息。
|
||||
3. Server SDK中添加发送朋友圈接口。
|
||||
4. 添加配置是否允许发送消息给被封禁用户。
|
||||
5. 音视频通话挂断推送中带上发起消息的ID
|
||||
|
||||
--------------
|
||||
Release note 1.3.4:
|
||||
1. 优化Server SDK中消息内容的处理方式。
|
||||
2. Server SDK中添加注册消息接口,在使用自定义消息时,不需要修改Server SDK源码。
|
||||
3. 用户撤回时间配置允许为负数,为负数时可以任意时间撤回。
|
||||
4. Server SDK添加超时参数。
|
||||
5. 解决当分段拉取消息时,可能丢失消息的问题。
|
||||
|
||||
--------------
|
||||
Release note 1.3.3:
|
||||
1. 转移群组时检查新群主是否在群中。
|
||||
2. 机器人API添加定向消息接口。
|
||||
|
||||
--------------
|
||||
Release note 1.3.2:
|
||||
1. 机器人Server SDK添加朋友圈相关接口。
|
||||
2. Server API添加批量获取用户接口。
|
||||
3. 解决聊天室定向消息无效的问题。
|
||||
4. 添加配置,可以在禁止私聊时添加例外聊天线路。
|
||||
|
||||
--------------
|
||||
Release note 1.3.1:
|
||||
1. 透传消息去掉消息ID,减少消息传输大小。
|
||||
2. 修改添加好友策略,可以设置禁止加自己好友。
|
||||
3. Server API创建群组时,检查是否设置operator。
|
||||
4. SDK添加删除广播和组播消息接口
|
||||
|
||||
--------------
|
||||
Release note 1.3.0:
|
||||
1. 推送信息中添加republish参数,用于标识消息是重新发布的。
|
||||
2. 添加好友请求限频功能,在IM服务配置中可以配置每天限制添加的好友数。
|
||||
3. 添加配置,是否允许用户发送消息给被拉黑的用户。
|
||||
4. 添加鸿蒙回调地址。
|
||||
5. 创建群组或者添加群组成员时,群组成员的Extra会放到通知消息的extra中,这样便于业务处理通知消息。
|
||||
|
||||
--------------
|
||||
Release note 1.2.9:
|
||||
1. 解决server api获取群组信息不全的问题。
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.2.9</version>
|
||||
<version>1.3.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ChannelServiceApi {
|
||||
return channelHttpUtils.httpJsonPost(path, null, OutputGetChannelInfo.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> modifyChannelMenu(List<OutputGetChannelInfo.OutputMenu> menus) throws Exception {
|
||||
public IMResult<Void> modifyChannelMenu(List<PojoChannelMenu> menus) throws Exception {
|
||||
String menuStr = new Gson().toJson(menus);
|
||||
return modifyChannelInfo(ProtoConstants.ModifyChannelInfoType.Modify_Channel_Menu, menuStr);
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class ChannelServiceApi {
|
||||
public IMResult<SendMessageResult> sendMessage(int line, List<String> targets, MessagePayload payload) throws Exception {
|
||||
String path = APIPath.Channel_Message_Send;
|
||||
SendChannelMessageData messageData = new SendChannelMessageData();
|
||||
messageData.setLine(0);
|
||||
messageData.setLine(line);
|
||||
messageData.setTargets(targets);
|
||||
messageData.setPayload(payload);
|
||||
return channelHttpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 生成测试数据。本应用生成以下数据:
|
||||
* 1. 创建${totalUserCount}个用户
|
||||
* 2. 每个用户同其他${friendCount}个用户建立好友关系
|
||||
* 3. 确保每个人都加入${smallGroupCount}个群组成员数为${smallGroupMemberSize}的小群组
|
||||
* 4. 确保每个人都加入${middleGroupCount}个群组成员数为${middleGroupMemberSize}的中群组
|
||||
* 5. 确保每个人都加入${bigGroupCount}个群组成员数为${bigGroupMemberSize}的大群组
|
||||
* 6. 把数据分片${splitFileCount}个保存在文件中
|
||||
*
|
||||
* 好友关系和群组关系都是随机生成,有可能会出现最后几个用户无法满足精确好友数或者群组数的问题,但绝大部分数据都能满足需求。
|
||||
*/
|
||||
public class GenerateTestData {
|
||||
//IM服务Server API
|
||||
private static String AdminUrl = "http://10.206.0.5:18080";
|
||||
private static String AdminSecret = "123456";
|
||||
|
||||
private static int totalUserCount = 20000;
|
||||
|
||||
//每个用户的好友数
|
||||
private static int friendCount = 100;
|
||||
|
||||
//每个用户拥有的小群数,和小群的大小。
|
||||
private static int smallGroupCount = 100;
|
||||
private static int smallGroupMemberSize = 20;
|
||||
|
||||
//每个用户拥有的中群数,和中群的大小。
|
||||
private static int middleGroupCount = 100;
|
||||
private static int middleGroupMemberSize = 100;
|
||||
|
||||
//每个用户拥有的大群数,和大群的大小。
|
||||
private static int bigGroupCount = 20;
|
||||
private static int bigGroupMemberSize = 1000;
|
||||
|
||||
//数据文件分割成几个文件存储。
|
||||
private static int splitFileCount = 1;
|
||||
|
||||
|
||||
//统计添加好友数和创建群组数。
|
||||
private static AtomicInteger addFriendCount = new AtomicInteger(0);
|
||||
private static AtomicInteger createGroupCount = new AtomicInteger(0);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AdminConfig.initAdmin(AdminUrl, AdminSecret);
|
||||
int addFriendRequestCount = friendCount*totalUserCount/2;
|
||||
int createSmallGroupCount = smallGroupCount * totalUserCount / smallGroupMemberSize;
|
||||
int createMiddleGroupCount = middleGroupCount * totalUserCount / middleGroupMemberSize;
|
||||
int createBigGroupCount = bigGroupCount * totalUserCount / bigGroupMemberSize;
|
||||
System.out.println("根据当前的参数,将创建 " + totalUserCount + " 名用户");
|
||||
System.out.println("添加大概 " + addFriendRequestCount + " 次好友请求");
|
||||
System.out.println("创建大概 " + createSmallGroupCount + " 个小型群组");
|
||||
System.out.println("创建大概 " + createMiddleGroupCount + " 个中等群组");
|
||||
System.out.println("创建大概 " + createBigGroupCount + " 个大型群组");
|
||||
System.out.println("等待10秒开始");
|
||||
Thread.sleep(10*1000);
|
||||
|
||||
List<String> userIds = generateUserIds(totalUserCount);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(5);
|
||||
|
||||
new Thread(() -> {
|
||||
createUsers(userIds);
|
||||
latch.countDown();
|
||||
}).start();
|
||||
|
||||
Map<String, Integer> unfulfilledFriendMap = new HashMap<>();
|
||||
new Thread(() -> {
|
||||
addFriends(userIds, friendCount, unfulfilledFriendMap);
|
||||
latch.countDown();
|
||||
}).start();
|
||||
|
||||
Map<String, Set<String>> userSmallGroupMap = new HashMap<>();
|
||||
Map<String, Integer> unfulfilledSmallMap = new HashMap<>();
|
||||
new Thread(() ->{
|
||||
for (String userId : userIds) {
|
||||
createGroup(userId, userIds, userSmallGroupMap, smallGroupCount, smallGroupMemberSize, unfulfilledSmallMap);
|
||||
}
|
||||
latch.countDown();
|
||||
}).start();
|
||||
|
||||
Map<String, Set<String>> userMiddleGroupMap = new HashMap<>();
|
||||
Map<String, Integer> unfulfilledMiddleMap = new HashMap<>();
|
||||
new Thread(() ->{
|
||||
for (String userId : userIds) {
|
||||
createGroup(userId, userIds, userMiddleGroupMap, middleGroupCount, middleGroupMemberSize, unfulfilledMiddleMap);
|
||||
}
|
||||
latch.countDown();
|
||||
}).start();
|
||||
|
||||
Map<String, Set<String>> userBigGroupMap = new HashMap<>();
|
||||
Map<String, Integer> unfulfilledBigMap = new HashMap<>();
|
||||
new Thread(() ->{
|
||||
for (String userId : userIds) {
|
||||
createGroup(userId, userIds, userBigGroupMap, bigGroupCount, bigGroupMemberSize, unfulfilledBigMap);
|
||||
}
|
||||
latch.countDown();
|
||||
}).start();
|
||||
|
||||
latch.await();
|
||||
|
||||
System.out.println("数据初始化结束,实际建立好友关系: " + addFriendCount.get() + " 条。");
|
||||
if (!unfulfilledFriendMap.isEmpty()) {
|
||||
System.out.println("有部分用户没有建立" + friendCount + "个好友关系,分别是:");
|
||||
printUnfulfilledMap(unfulfilledFriendMap);
|
||||
}
|
||||
|
||||
System.out.println("数据初始化结束,创建群组: " + createGroupCount.get() + " 个。");
|
||||
if (!unfulfilledSmallMap.isEmpty()) {
|
||||
System.out.println("有部分用户没有建立" + smallGroupMemberSize + "个群组成员的群,分别是:");
|
||||
printUnfulfilledMap(unfulfilledSmallMap);
|
||||
}
|
||||
if (!unfulfilledMiddleMap.isEmpty()) {
|
||||
System.out.println("有部分用户没有建立" + middleGroupMemberSize + "个群组成员的群,分别是:");
|
||||
printUnfulfilledMap(unfulfilledMiddleMap);
|
||||
}
|
||||
if (!unfulfilledBigMap.isEmpty()) {
|
||||
System.out.println("有部分用户没有建立" + bigGroupMemberSize + "个群组成员的群,分别是:");
|
||||
printUnfulfilledMap(unfulfilledBigMap);
|
||||
}
|
||||
|
||||
|
||||
System.out.println("保存数据到" + splitFileCount + "个文件中。");
|
||||
for (int i = 0; i < splitFileCount; i++) {
|
||||
String filePath = "data"+i+".csv"; // 文件路径
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(filePath));
|
||||
int partSize = totalUserCount/splitFileCount;
|
||||
for (int j = 0; j < partSize; j++) {
|
||||
String userId = userIds.get(i*partSize+j);
|
||||
writeDeviceInfo(writer, userId, 3);
|
||||
Set<String> smallGroupIds = userSmallGroupMap.get(userId);
|
||||
writeGroupIds(writer, smallGroupIds);
|
||||
Set<String> middleGroupIds = userMiddleGroupMap.get(userId);
|
||||
writeGroupIds(writer, middleGroupIds);
|
||||
Set<String> bigGroupIds = userBigGroupMap.get(userId);
|
||||
writeGroupIds(writer, bigGroupIds);
|
||||
}
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
System.out.println("保存结束。");
|
||||
}
|
||||
|
||||
private static void printUnfulfilledMap(Map<String, Integer> map) {
|
||||
if(map.isEmpty())
|
||||
return;
|
||||
|
||||
map.forEach((s, integer) -> System.out.print(s + ":" + integer + " "));
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static void writeDeviceInfo(BufferedWriter writer, String userId, int platform) throws IOException {
|
||||
writer.write(userId);
|
||||
writer.write(",");
|
||||
writer.write(UUID.randomUUID().toString());
|
||||
writer.write(",");
|
||||
writer.write(""+platform);
|
||||
writer.write("\n");
|
||||
}
|
||||
|
||||
private static void writeGroupIds(BufferedWriter writer, Set<String> groupIds) throws IOException {
|
||||
int writeCount = 0;
|
||||
for (String bigGroupId : groupIds) {
|
||||
writer.write(bigGroupId);
|
||||
writeCount++;
|
||||
if(writeCount < groupIds.size()) {
|
||||
writer.write(",");
|
||||
} else {
|
||||
writer.write("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void createGroup(String userId, List<String> userIds, Map<String, Set<String>> userGroupMap, int groupCount, int memberSize, Map<String, Integer> unfulfilledUserMap) {
|
||||
Set<String> groupIds = userGroupMap.computeIfAbsent(userId, s -> new HashSet<>());
|
||||
int i = 0;
|
||||
while (groupIds.size() < groupCount){
|
||||
PojoGroupInfo groupInfo = new PojoGroupInfo();
|
||||
groupInfo.setTarget_id(UUID.randomUUID().toString());
|
||||
groupInfo.setOwner(userId);
|
||||
groupInfo.setName("Group_"+userId+i++);
|
||||
groupInfo.setType(2);
|
||||
groupIds.add(groupInfo.getTarget_id());
|
||||
|
||||
List<String> memberCandidates = new ArrayList<>(userIds);
|
||||
List<String> memberIds = new ArrayList<>();
|
||||
memberIds.add(userId);
|
||||
|
||||
while (!memberCandidates.isEmpty() && memberIds.size() < memberSize) {
|
||||
String memberId = memberCandidates.get((int)(Math.random()*memberCandidates.size()));
|
||||
memberCandidates.remove(memberId);
|
||||
if(memberId.equals(userId)) {
|
||||
continue;
|
||||
}
|
||||
if (memberIds.contains(memberId)) {
|
||||
continue;
|
||||
}
|
||||
Set<String> memberGroupIds = userGroupMap.computeIfAbsent(memberId, s -> new HashSet<>());
|
||||
if(memberGroupIds.contains(groupInfo.getTarget_id()) || memberGroupIds.size() >= groupCount) {
|
||||
continue;
|
||||
}
|
||||
memberGroupIds.add(groupInfo.getTarget_id());
|
||||
memberIds.add(memberId);
|
||||
}
|
||||
|
||||
List<PojoGroupMember> members = new ArrayList<>();
|
||||
for (String memberId : memberIds) {
|
||||
PojoGroupMember member1 = new PojoGroupMember();
|
||||
member1.setMember_id(memberId);
|
||||
members.add(member1);
|
||||
}
|
||||
|
||||
try {
|
||||
IMResult<OutputCreateGroupResult> resultCreateGroup = GroupAdmin.createGroup(groupInfo.getOwner(), groupInfo, members, null, null, null);
|
||||
if (resultCreateGroup != null && resultCreateGroup.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("create group success");
|
||||
} else {
|
||||
System.out.println("create group failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("create group failure:" + e);
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
createGroupCount.incrementAndGet();
|
||||
if(memberIds.size() < memberSize) {
|
||||
unfulfilledUserMap.put(userId + "'s group " + groupInfo.getTarget_id(), memberIds.size());
|
||||
System.out.println("Error, can not find enough user to create group for user:" + userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFriends(List<String> userIds, int count, Map<String, Integer> unfulfilledFriendMap) {
|
||||
ConcurrentLinkedQueue<Pair<String, String>> toAddSet = new ConcurrentLinkedQueue<>();
|
||||
Map<String, Set<String>> userFriends = new HashMap<>();
|
||||
for (String userId : userIds) {
|
||||
List<String> candidates = new ArrayList<>(userIds);
|
||||
Set<String> currentUserFriends = userFriends.computeIfAbsent(userId, s -> new HashSet<>());
|
||||
while (!candidates.isEmpty() && currentUserFriends.size() < count) {
|
||||
String friendId = candidates.get((int) (Math.random()*candidates.size()));
|
||||
candidates.remove(friendId);
|
||||
if(friendId.equals(userId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!currentUserFriends.contains(friendId)) {
|
||||
Set<String> targetUserFriends = userFriends.computeIfAbsent(friendId, s -> new HashSet<>());
|
||||
if(targetUserFriends.size() < count) {
|
||||
currentUserFriends.add(friendId);
|
||||
targetUserFriends.add(userId);
|
||||
toAddSet.add(new Pair<>(userId, friendId));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentUserFriends.size() < count) {
|
||||
unfulfilledFriendMap.put(userId, currentUserFriends.size());
|
||||
System.out.println("Error, can not find enough user to add friend for user:" + userId);
|
||||
}
|
||||
}
|
||||
int threadNum = 5;
|
||||
CountDownLatch latch = new CountDownLatch(threadNum);
|
||||
for (int i = 0; i < threadNum; i++) {
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
Pair<String, String> pair = toAddSet.poll();
|
||||
if(pair == null) {
|
||||
latch.countDown();
|
||||
break;
|
||||
}
|
||||
try {
|
||||
IMResult<Void> result = RelationAdmin.setUserFriend(pair.first, pair.second, true, null);
|
||||
if (result != null && (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS || result.getErrorCode() == ErrorCode.ERROR_CODE_ALREADY_FRIENDS)) {
|
||||
System.out.println("add friend success");
|
||||
addFriendCount.incrementAndGet();
|
||||
} else {
|
||||
System.out.println("failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("failure:" + e);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("failure:" + e);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateUserId(int index) {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
private static List<String> generateUserIds(int count) {
|
||||
List<String> userIds = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
userIds.add(generateUserId(i));
|
||||
}
|
||||
return userIds;
|
||||
}
|
||||
|
||||
private static void createUsers(List<String> userIds) {
|
||||
for (int i = 0; i < userIds.size(); i++) {
|
||||
InputOutputUserInfo userInfo = generateUserInfo(userIds.get(i), i);
|
||||
try {
|
||||
IMResult<OutputCreateUser> resultCreateUser = UserAdmin.createUser(userInfo);
|
||||
if (resultCreateUser != null && resultCreateUser.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("Create user " + resultCreateUser.getResult().getName() + " success");
|
||||
} else {
|
||||
System.out.println("Create user failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Create user failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static InputOutputUserInfo generateUserInfo(String userId, int index) {
|
||||
InputOutputUserInfo userInfo = new InputOutputUserInfo();
|
||||
//用户ID,必须保证唯一性
|
||||
userInfo.setUserId(userId);
|
||||
//用户名,一般是用户登录帐号,也必须保证唯一性。也就是说所有用户的userId必须不能重复,所有用户的name必须不能重复,但可以同一个用户的userId和name是同一个,一般建议userId使用一个uuid,name是"微信号"且可以修改,
|
||||
userInfo.setName(userId);
|
||||
userInfo.setMobile((11000000000L+index) + "");
|
||||
userInfo.setDisplayName("User"+index);
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
static class Pair<K, V> {
|
||||
K first;
|
||||
V second;
|
||||
|
||||
public Pair() {
|
||||
}
|
||||
|
||||
public Pair(K first, V second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,13 @@ package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupAdmin {
|
||||
public static IMResult<OutputCreateGroupResult> createGroup(String operator, PojoGroupInfo group_info, List<PojoGroupMember> members, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public static IMResult<OutputCreateGroupResult> createGroup(String operator, PojoGroupInfo group_info, List<PojoGroupMember> members, String member_extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Create_Group;
|
||||
PojoGroup pojoGroup = new PojoGroup();
|
||||
pojoGroup.setGroup_info(group_info);
|
||||
@@ -17,6 +16,7 @@ public class GroupAdmin {
|
||||
InputCreateGroup createGroup = new InputCreateGroup();
|
||||
createGroup.setGroup(pojoGroup);
|
||||
createGroup.setOperator(operator);
|
||||
createGroup.setMember_extra(member_extra);
|
||||
createGroup.setTo_lines(to_lines);
|
||||
createGroup.setNotify_message(notify_message);
|
||||
|
||||
@@ -85,12 +85,13 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, PojoGroupMember.class);
|
||||
}
|
||||
|
||||
public static IMResult<Void> addGroupMembers(String operator, String groupId, List<PojoGroupMember> groupMembers, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public static IMResult<Void> addGroupMembers(String operator, String groupId, List<PojoGroupMember> groupMembers, String member_extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Member_Add;
|
||||
InputAddGroupMember addGroupMember = new InputAddGroupMember();
|
||||
addGroupMember.setGroup_id(groupId);
|
||||
addGroupMember.setMembers(groupMembers);
|
||||
addGroupMember.setOperator(operator);
|
||||
addGroupMember.setMemberExtra(member_extra);
|
||||
addGroupMember.setTo_lines(to_lines);
|
||||
addGroupMember.setNotify_message(notify_message);
|
||||
return AdminHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -81,13 +81,7 @@ public class MessageAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, inputMessageUid, OutputMessageData.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回群发或者广播的消息
|
||||
* @param operator 操作者
|
||||
* @param messageUid 消息唯一ID
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
//仅专业版支持
|
||||
public static IMResult<Void> recallBroadCastMessage(String operator, long messageUid) throws Exception {
|
||||
String path = APIPath.Msg_RecallBroadCast;
|
||||
RecallMessageData messageData = new RecallMessageData();
|
||||
@@ -102,10 +96,28 @@ public class MessageAdmin {
|
||||
messageData.operator = operator;
|
||||
messageData.messageUid = messageUid;
|
||||
messageData.receivers = receivers;
|
||||
|
||||
return AdminHttpUtils.httpJsonPost(path, messageData, Void.class);
|
||||
}
|
||||
|
||||
//仅专业版支持
|
||||
public static IMResult<Void> deleteBroadCastMessage(String operator, long messageUid) throws Exception {
|
||||
String path = APIPath.Msg_DeleteBroadCast;
|
||||
RecallMessageData messageData = new RecallMessageData();
|
||||
messageData.setOperator(operator);
|
||||
messageData.setMessageUid(messageUid);
|
||||
return AdminHttpUtils.httpJsonPost(path, messageData, Void.class);
|
||||
}
|
||||
|
||||
public static IMResult<Void> deleteMultiCastMessage(String operator, long messageUid, List<String> receivers) throws Exception {
|
||||
String path = APIPath.Msg_DeleteMultiCast;
|
||||
RecallMultiCastMessageData messageData = new RecallMultiCastMessageData();
|
||||
messageData.operator = operator;
|
||||
messageData.messageUid = messageUid;
|
||||
messageData.receivers = receivers;
|
||||
return AdminHttpUtils.httpJsonPost(path, messageData, Void.class);
|
||||
}
|
||||
|
||||
//仅专业版支持
|
||||
public static IMResult<BroadMessageResult> broadcastMessage(String sender, int line, MessagePayload payload) throws Exception {
|
||||
String path = APIPath.Msg_Broadcast;
|
||||
BroadMessageData messageData = new BroadMessageData();
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.pojos.moments.FeedPojo;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
|
||||
public class MomentsAdmin {
|
||||
public static IMResult<SendMessageResult> postFeeds(FeedPojo feedPojo) throws Exception {
|
||||
String path = APIPath.Admin_Moments_Post_Feed;
|
||||
return AdminHttpUtils.httpJsonPost(path, feedPojo, SendMessageResult.class);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.pojos.moments.*;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.RobotHttpUtils;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
@@ -22,10 +24,15 @@ public class RobotService {
|
||||
}
|
||||
|
||||
public IMResult<SendMessageResult> sendMessage(String sender, Conversation conversation, MessagePayload payload) throws Exception {
|
||||
return sendMessage(sender, conversation, payload, null);
|
||||
}
|
||||
|
||||
public IMResult<SendMessageResult> sendMessage(String sender, Conversation conversation, MessagePayload payload, List<String> toUsers) throws Exception {
|
||||
String path = APIPath.Robot_Message_Send;
|
||||
SendMessageData messageData = new SendMessageData();
|
||||
messageData.setSender(sender);
|
||||
messageData.setConv(conversation);
|
||||
messageData.setToUsers(toUsers);
|
||||
messageData.setPayload(payload);
|
||||
return robotHttpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
|
||||
}
|
||||
@@ -96,13 +103,14 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, pojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<OutputCreateGroupResult> createGroup(PojoGroupInfo group_info, List<PojoGroupMember> members, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<OutputCreateGroupResult> createGroup(PojoGroupInfo group_info, List<PojoGroupMember> members, String member_extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Create_Group;
|
||||
PojoGroup pojoGroup = new PojoGroup();
|
||||
pojoGroup.setGroup_info(group_info);
|
||||
pojoGroup.setMembers(members);
|
||||
InputCreateGroup createGroup = new InputCreateGroup();
|
||||
createGroup.setGroup(pojoGroup);
|
||||
createGroup.setMember_extra(member_extra);
|
||||
createGroup.setTo_lines(to_lines);
|
||||
createGroup.setNotify_message(notify_message);
|
||||
|
||||
@@ -117,7 +125,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, input, PojoGroupInfo.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> dismissGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> dismissGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Dismiss;
|
||||
InputDismissGroup dismissGroup = new InputDismissGroup();
|
||||
dismissGroup.setGroup_id(groupId);
|
||||
@@ -126,7 +134,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, dismissGroup, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> transferGroup(String groupId, String newOwner, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> transferGroup(String groupId, String newOwner, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Transfer;
|
||||
InputTransferGroup transferGroup = new InputTransferGroup();
|
||||
transferGroup.setGroup_id(groupId);
|
||||
@@ -136,7 +144,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, transferGroup, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> modifyGroupInfo(String groupId, /*ModifyGroupInfoType*/int type, String value, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> modifyGroupInfo(String groupId, /*ModifyGroupInfoType*/int type, String value, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Modify_Info;
|
||||
InputModifyGroupInfo modifyGroupInfo = new InputModifyGroupInfo();
|
||||
modifyGroupInfo.setGroup_id(groupId);
|
||||
@@ -163,17 +171,18 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, input, PojoGroupMember.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> addGroupMembers(String groupId, List<PojoGroupMember> groupMembers, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> addGroupMembers(String groupId, List<PojoGroupMember> groupMembers, String member_extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Member_Add;
|
||||
InputAddGroupMember addGroupMember = new InputAddGroupMember();
|
||||
addGroupMember.setGroup_id(groupId);
|
||||
addGroupMember.setMembers(groupMembers);
|
||||
addGroupMember.setMemberExtra(member_extra);
|
||||
addGroupMember.setTo_lines(to_lines);
|
||||
addGroupMember.setNotify_message(notify_message);
|
||||
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> setGroupManager(String groupId, List<String> groupMemberIds, boolean isManager, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> setGroupManager(String groupId, List<String> groupMemberIds, boolean isManager, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Set_Manager;
|
||||
InputSetGroupManager addGroupMember = new InputSetGroupManager();
|
||||
addGroupMember.setGroup_id(groupId);
|
||||
@@ -184,7 +193,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> muteGroupMember(String groupId, List<String> groupMemberIds, boolean isMute, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> muteGroupMember(String groupId, List<String> groupMemberIds, boolean isMute, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Mute_Member;
|
||||
InputMuteGroupMember addGroupMember = new InputMuteGroupMember();
|
||||
addGroupMember.setGroup_id(groupId);
|
||||
@@ -195,7 +204,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> allowGroupMember(String groupId, List<String> groupMemberIds, boolean isAllow, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> allowGroupMember(String groupId, List<String> groupMemberIds, boolean isAllow, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Allow_Member;
|
||||
InputMuteGroupMember addGroupMember = new InputMuteGroupMember();
|
||||
addGroupMember.setGroup_id(groupId);
|
||||
@@ -206,7 +215,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> kickoffGroupMembers(String groupId, List<String> groupMemberIds, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> kickoffGroupMembers(String groupId, List<String> groupMemberIds, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Member_Kickoff;
|
||||
InputKickoffGroupMember kickoffGroupMember = new InputKickoffGroupMember();
|
||||
kickoffGroupMember.setGroup_id(groupId);
|
||||
@@ -216,7 +225,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, kickoffGroupMember, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> quitGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> quitGroup(String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Member_Quit;
|
||||
InputQuitGroup quitGroup = new InputQuitGroup();
|
||||
quitGroup.setGroup_id(groupId);
|
||||
@@ -225,7 +234,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, quitGroup, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> setGroupMemberAlias(String groupId, String memberId, String alias, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> setGroupMemberAlias(String groupId, String memberId, String alias, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Set_Member_Alias;
|
||||
InputSetGroupMemberAlias input = new InputSetGroupMemberAlias();
|
||||
input.setGroup_id(groupId);
|
||||
@@ -236,7 +245,7 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> setGroupMemberExtra(String groupId, String memberId, String extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
public IMResult<Void> setGroupMemberExtra(String groupId, String memberId, String extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Robot_Group_Set_Member_Extra;
|
||||
InputSetGroupMemberExtra input = new InputSetGroupMemberExtra();
|
||||
input.setGroup_id(groupId);
|
||||
@@ -274,4 +283,144 @@ public class RobotService {
|
||||
return robotHttpUtils.httpJsonPost(path, input, String.class);
|
||||
}
|
||||
|
||||
public IMResult<FeedPojo> postMomentsFeed(int/*MomentsContentType*/ type, String text, List<MediaEntry> medias, List<String> toUsers, List<String> excludeUsers, List<String> mentionedUsers, String extra) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Post_Feed;
|
||||
FeedPojo feedPojo = new FeedPojo();
|
||||
feedPojo.type = type;
|
||||
feedPojo.text = text;
|
||||
feedPojo.medias = medias;
|
||||
feedPojo.to = toUsers;
|
||||
feedPojo.ex = excludeUsers;
|
||||
feedPojo.mu = mentionedUsers;
|
||||
feedPojo.extra = extra;
|
||||
IMResult<PostFeedResult> imResult = robotHttpUtils.httpJsonPost(path, feedPojo, PostFeedResult.class);
|
||||
IMResult<FeedPojo> feedResult = new IMResult<>();
|
||||
if(imResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
feedPojo.feedId = imResult.result.id;
|
||||
feedPojo.timestamp = imResult.result.timestamp;
|
||||
feedResult.setCode(ErrorCode.ERROR_CODE_SUCCESS.getCode());
|
||||
feedResult.setResult(feedPojo);
|
||||
} else {
|
||||
feedResult.setCode(imResult.getCode());
|
||||
feedResult.setMsg(imResult.getMsg());
|
||||
}
|
||||
return feedResult;
|
||||
}
|
||||
|
||||
public IMResult<Void> updateMomentsFeed(long feedId, int/*MomentsContentType*/ type, String text, List<MediaEntry> medias, List<String> toUsers, List<String> excludeUsers, List<String> mentionedUsers, String extra) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Update_Feed;
|
||||
FeedPojo feedPojo = new FeedPojo();
|
||||
feedPojo.feedId = feedId;
|
||||
feedPojo.type = type;
|
||||
feedPojo.text = text;
|
||||
feedPojo.medias = medias;
|
||||
feedPojo.to = toUsers;
|
||||
feedPojo.ex = excludeUsers;
|
||||
feedPojo.mu = mentionedUsers;
|
||||
feedPojo.extra = extra;
|
||||
return robotHttpUtils.httpJsonPost(path, feedPojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<FeedsPojo> getMomentsFeeds(long feedId, int count, String user) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Pull_Feeds;
|
||||
PullFeedRequestPojo requestPojo = new PullFeedRequestPojo();
|
||||
requestPojo.feedId = feedId;
|
||||
requestPojo.count = count;
|
||||
requestPojo.user = user;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, FeedsPojo.class);
|
||||
}
|
||||
|
||||
public IMResult<FeedPojo> getMomentsFeed(long feedId) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Fetch_Feed;
|
||||
PullOneFeedRequestPojo requestPojo = new PullOneFeedRequestPojo();
|
||||
requestPojo.feedId = feedId;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, FeedPojo.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> deleteMomentsFeed(long feedId) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Recall_Feed;
|
||||
IdPojo requestPojo = new IdPojo();
|
||||
requestPojo.id = feedId;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<CommentPojo> postMomentsComment(long feedId, long replyId, int/*MomentsCommentType*/ type, String text, String replyTo, String extra) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Post_Comment;
|
||||
CommentPojo commentPojo = new CommentPojo();
|
||||
commentPojo.type = type;
|
||||
commentPojo.text = text;
|
||||
commentPojo.replyId = replyId;
|
||||
commentPojo.feedId = feedId;
|
||||
commentPojo.replyTo = replyTo;
|
||||
commentPojo.extra = extra;
|
||||
IMResult<PostFeedResult> imResult = robotHttpUtils.httpJsonPost(path, commentPojo, PostFeedResult.class);
|
||||
IMResult<CommentPojo> feedResult = new IMResult<>();
|
||||
if(imResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
commentPojo.commentId = imResult.result.id;
|
||||
commentPojo.timestamp = imResult.result.timestamp;
|
||||
feedResult.setCode(ErrorCode.ERROR_CODE_SUCCESS.getCode());
|
||||
feedResult.setResult(commentPojo);
|
||||
} else {
|
||||
feedResult.setCode(imResult.getCode());
|
||||
feedResult.setMsg(imResult.getMsg());
|
||||
}
|
||||
return feedResult;
|
||||
}
|
||||
|
||||
public IMResult<Void> deleteMomentsComment(long feedId, long commentId) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Recall_Comment;
|
||||
IdPojo requestPojo = new IdPojo();
|
||||
requestPojo.id = commentId;
|
||||
requestPojo.id2 = feedId;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<MomentProfilePojo> getUserMomentsProfile(String userId) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Fetch_Profiles;
|
||||
PullProfileRequestPojo requestPojo = new PullProfileRequestPojo();
|
||||
requestPojo.u = userId;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, MomentProfilePojo.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> updateMomentsBackgroundUrl(String url) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Update_Profiles_Value;
|
||||
PushProfileValueRequestPojo requestPojo = new PushProfileValueRequestPojo();
|
||||
requestPojo.t = 0;
|
||||
requestPojo.v = url;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> updateMomentsStrangerVisibleCount(int count) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Update_Profiles_Value;
|
||||
PushProfileValueRequestPojo requestPojo = new PushProfileValueRequestPojo();
|
||||
requestPojo.t = 1;
|
||||
requestPojo.i = count;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> updateMomentsVisibleScope(int/*MomentsVisibleScope*/ scope) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Update_Profiles_Value;
|
||||
PushProfileValueRequestPojo requestPojo = new PushProfileValueRequestPojo();
|
||||
requestPojo.t = 2;
|
||||
requestPojo.i = scope;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> updateMomentsBlackList(List<String> addList, List<String> removeList) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Update_Profiles_List_Value;
|
||||
PushProfileListRequestPojo requestPojo = new PushProfileListRequestPojo();
|
||||
requestPojo.b = false;
|
||||
requestPojo.al = addList;
|
||||
requestPojo.rl = removeList;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, Void.class);
|
||||
}
|
||||
|
||||
public IMResult<Void> updateMomentsBlockList(List<String> addList, List<String> removeList) throws Exception {
|
||||
String path = APIPath.Robot_Moments_Update_Profiles_List_Value;
|
||||
PushProfileListRequestPojo requestPojo = new PushProfileListRequestPojo();
|
||||
requestPojo.b = true;
|
||||
requestPojo.al = addList;
|
||||
requestPojo.rl = removeList;
|
||||
return robotHttpUtils.httpJsonPost(path, requestPojo, Void.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserAdmin {
|
||||
public static IMResult<InputOutputUserInfo> getUserByName(String name) throws Exception {
|
||||
String path = APIPath.User_Get_Info;
|
||||
@@ -37,6 +39,13 @@ public class UserAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputGetUserList.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputUserInfoList> getBatchUsers(List<String> userIds) throws Exception {
|
||||
String path = APIPath.User_Batch_Get_Infos;
|
||||
InputStringList input = new InputStringList();
|
||||
input.setList(userIds);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputUserInfoList.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputCreateUser> createUser(InputOutputUserInfo user) throws Exception {
|
||||
String path = APIPath.Create_User;
|
||||
return AdminHttpUtils.httpJsonPost(path, user, OutputCreateUser.class);
|
||||
|
||||
@@ -32,7 +32,7 @@ public class ArticlesMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent(topArticle.title);
|
||||
JSONObject object = new JSONObject();
|
||||
|
||||
@@ -53,6 +53,7 @@ public class ArticlesMessageContent extends MessageContent {
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
try {
|
||||
super.decode(payload);
|
||||
JSONObject object = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
|
||||
JSONObject topObj = (JSONObject) object.get("top");
|
||||
this.topArticle = Article.fromJson(topObj);
|
||||
|
||||
@@ -133,7 +133,7 @@ public class CallStartMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setContent(callId);
|
||||
payload.setPushContent("音视频通话邀请");
|
||||
|
||||
@@ -175,6 +175,7 @@ public class CallStartMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
callId = payload.getContent();
|
||||
|
||||
try {
|
||||
|
||||
@@ -100,7 +100,7 @@ public class CardMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setContent(target);
|
||||
JSONObject objWrite = new JSONObject();
|
||||
objWrite.put("t", type);
|
||||
@@ -116,6 +116,7 @@ public class CardMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
target = payload.getContent();
|
||||
try {
|
||||
if (!StringUtil.isNullOrEmpty(payload.getBase64edData())) {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.wildfirechat.sdk.messagecontent;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
public class DeleteMessageContent extends MessageContent {
|
||||
private long messageId;
|
||||
private String operatorId;
|
||||
|
||||
//必须有个空的构造函数
|
||||
public DeleteMessageContent() {
|
||||
}
|
||||
|
||||
public long getMessageId() {
|
||||
return messageId;
|
||||
}
|
||||
|
||||
public String getOperatorId() {
|
||||
return operatorId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getContentType() {
|
||||
return ProtoConstants.ContentType.Delete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPersistFlag() {
|
||||
return ProtoConstants.PersistFlag.Not_Persist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
throw new RuntimeException("Delete message cannot encode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
operatorId = payload.getContent();
|
||||
messageId = Long.parseLong(new String(Base64.getDecoder().decode(payload.getBase64edData()), StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ public class FileMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent(name);
|
||||
payload.setContent(size + "");
|
||||
|
||||
@@ -51,7 +51,7 @@ public class FileMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decodeBase(payload);
|
||||
super.decode(payload);
|
||||
|
||||
if (payload.getSearchableContent().startsWith(FILE_NAME_PREFIX)) {
|
||||
name = payload.getSearchableContent().substring(payload.getSearchableContent().indexOf(FILE_NAME_PREFIX) + FILE_NAME_PREFIX.length());
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ImageMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent("[图片]");
|
||||
payload.setBase64edData(Base64.getEncoder().encodeToString(thumbnailBytes));
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ImageMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decodeBase(payload);
|
||||
super.decode(payload);
|
||||
thumbnailBytes = Base64.getDecoder().decode(payload.getBase64edData());
|
||||
}
|
||||
|
||||
|
||||
@@ -72,9 +72,7 @@ public class LinkMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
|
||||
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent(title);
|
||||
JSONObject objWrite = new JSONObject();
|
||||
objWrite.put("d", contentDigest);
|
||||
@@ -88,9 +86,8 @@ public class LinkMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
title = payload.getSearchableContent();
|
||||
|
||||
|
||||
try {
|
||||
if (!StringUtil.isNullOrEmpty(payload.getBase64edData())) {
|
||||
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
|
||||
|
||||
@@ -66,7 +66,7 @@ public class LocationMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent(title);
|
||||
payload.setBase64edData(Base64.getEncoder().encodeToString(this.thumbnailByte));
|
||||
|
||||
@@ -82,6 +82,7 @@ public class LocationMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
if (!StringUtil.isNullOrEmpty(payload.getBase64edData())) {
|
||||
this.thumbnailByte = Base64.getDecoder().decode(payload.getBase64edData());
|
||||
}
|
||||
|
||||
@@ -14,12 +14,18 @@ abstract public class MediaMessageContent extends MessageContent {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MessagePayload encodeBase() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setRemoteMediaUrl(remoteMediaUrl);
|
||||
payload.setMediaType(getMediaType());
|
||||
return payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
remoteMediaUrl = payload.getRemoteMediaUrl();
|
||||
}
|
||||
|
||||
protected abstract int getMediaType();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public abstract class MessageContent {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected MessagePayload encodeBase() {
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = new MessagePayload();
|
||||
payload.setType(getContentType());
|
||||
payload.setPersistFlag(getPersistFlag());
|
||||
@@ -32,13 +32,11 @@ public abstract class MessageContent {
|
||||
return payload;
|
||||
}
|
||||
|
||||
protected void decodeBase(MessagePayload payload) {
|
||||
protected void decode(MessagePayload payload) {
|
||||
this.mentionedType = payload.getMentionedType();
|
||||
this.mentionedTargets = payload.getMentionedTarget();
|
||||
this.extra = payload.getExtra();
|
||||
}
|
||||
abstract public int getContentType();
|
||||
abstract public int getPersistFlag();
|
||||
abstract public MessagePayload encode();
|
||||
abstract public void decode(MessagePayload payload);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MessageContentFactory {
|
||||
private static final Map<Integer, Class<MessageContent>> contentClassMap = new ConcurrentHashMap<>();
|
||||
private static final Map<Integer, Class<? extends MessageContent>> contentClassMap = new ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
registerAllMessageContent();
|
||||
@@ -36,7 +36,7 @@ public class MessageContentFactory {
|
||||
}
|
||||
|
||||
public static MessageContent decodeMessageContent(MessagePayload messagePayload) {
|
||||
Class<MessageContent> cls = contentClassMap.get(messagePayload.getType());
|
||||
Class<? extends MessageContent> cls = contentClassMap.get(messagePayload.getType());
|
||||
MessageContent messageContent;
|
||||
if(cls != null) {
|
||||
try {
|
||||
@@ -49,11 +49,15 @@ public class MessageContentFactory {
|
||||
} else {
|
||||
messageContent = new UnknownMessageContent();
|
||||
}
|
||||
messageContent.decodeBase(messagePayload);
|
||||
messageContent.decode(messagePayload);
|
||||
return messageContent;
|
||||
}
|
||||
|
||||
public static void registerCustomMessageContent(Class<? extends MessageContent> cls) throws Exception {
|
||||
MessageContent content = cls.newInstance();
|
||||
contentClassMap.put(content.getContentType(), cls);
|
||||
}
|
||||
|
||||
private static void registerAllMessageContent() {
|
||||
try {
|
||||
for (Class cls : ClassUtil.getAllAssignedClass(MessageContent.class)) {
|
||||
|
||||
+2
-1
@@ -43,7 +43,7 @@ public class MultiCallOngoingMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setContent(callId);
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("initiator", this.initiator);
|
||||
@@ -60,6 +60,7 @@ public class MultiCallOngoingMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
this.callId = payload.getContent();
|
||||
try {
|
||||
JSONObject object = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ public class NotDeliveredMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("mid", this.messageUid);
|
||||
obj.put("all", this.allFailure);
|
||||
@@ -74,7 +74,7 @@ public class NotDeliveredMessageContent extends MessageContent {
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
try {
|
||||
|
||||
super.decode(payload);
|
||||
JSONObject obj = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
|
||||
this.messageUid = (long) obj.get("mid");
|
||||
this.allFailure = (boolean) obj.get("all");
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package cn.wildfirechat.sdk.messagecontent;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import org.apache.http.util.TextUtils;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
public class RecallMessageContent extends MessageContent {
|
||||
private long messageId;
|
||||
private String operatorId;
|
||||
|
||||
|
||||
private String originalSender;
|
||||
|
||||
private int originalContentType;
|
||||
private String originalSearchableContent;
|
||||
private String originalContent;
|
||||
private String originalExtra;
|
||||
private byte[] originalBinaryContent;
|
||||
private int originalMediaType;
|
||||
private String originalMediaUrl;
|
||||
private long originalMessageTimestamp;
|
||||
|
||||
//必须有个空的构造函数
|
||||
public RecallMessageContent() {
|
||||
}
|
||||
|
||||
public long getMessageId() {
|
||||
return messageId;
|
||||
}
|
||||
|
||||
public String getOperatorId() {
|
||||
return operatorId;
|
||||
}
|
||||
|
||||
public String getOriginalSender() {
|
||||
return originalSender;
|
||||
}
|
||||
|
||||
public int getOriginalContentType() {
|
||||
return originalContentType;
|
||||
}
|
||||
|
||||
public String getOriginalSearchableContent() {
|
||||
return originalSearchableContent;
|
||||
}
|
||||
|
||||
public String getOriginalContent() {
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
public String getOriginalExtra() {
|
||||
return originalExtra;
|
||||
}
|
||||
|
||||
public long getOriginalMessageTimestamp() {
|
||||
return originalMessageTimestamp;
|
||||
}
|
||||
|
||||
public byte[] getOriginalBinaryContent() {
|
||||
return originalBinaryContent;
|
||||
}
|
||||
|
||||
public int getOriginalMediaType() {
|
||||
return originalMediaType;
|
||||
}
|
||||
|
||||
public String getOriginalMediaUrl() {
|
||||
return originalMediaUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContentType() {
|
||||
return ProtoConstants.ContentType.Recall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPersistFlag() {
|
||||
return ProtoConstants.PersistFlag.Persist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
throw new RuntimeException("Recall message cannot encode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
operatorId = payload.getContent();
|
||||
messageId = Long.parseLong(new String(Base64.getDecoder().decode(payload.getBase64edData()), StandardCharsets.UTF_8));
|
||||
if(!TextUtils.isEmpty(payload.getExtra())) {
|
||||
try {
|
||||
JSONObject dictionary = (JSONObject) new JSONParser().parse(payload.getExtra());
|
||||
originalSender = (String) dictionary.get("s");
|
||||
if (dictionary.containsKey("t")) {
|
||||
originalContentType = ((Number) dictionary.get("t")).intValue();
|
||||
}
|
||||
originalSearchableContent = (String) dictionary.get("sc");
|
||||
originalContent = (String) dictionary.get("c");
|
||||
originalExtra = (String) dictionary.get("e");
|
||||
if (dictionary.containsKey("ts")) {
|
||||
originalMessageTimestamp = ((Number) dictionary.get("ts")).longValue();
|
||||
}
|
||||
if (dictionary.containsKey("mt")) {
|
||||
originalMediaType = ((Number) dictionary.get("mt")).intValue();
|
||||
}
|
||||
originalMediaUrl = (String) dictionary.get("mu");
|
||||
if (dictionary.containsKey("mb")) {
|
||||
originalBinaryContent = Base64.getDecoder().decode((String) dictionary.get("mb"));
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -89,7 +89,7 @@ public class RichNotificationMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setPushContent(title);
|
||||
payload.setContent(desc);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
@@ -113,5 +113,6 @@ public class RichNotificationMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,11 +35,12 @@ public class SoundMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("duration", duration);
|
||||
payload.setContent(jsonObject.toJSONString());
|
||||
|
||||
@@ -34,7 +34,7 @@ public class StickerMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent("[动态表情]");
|
||||
JSONObject objWrite = new JSONObject();
|
||||
objWrite.put("x", width);
|
||||
@@ -47,8 +47,7 @@ public class StickerMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decodeBase(payload);
|
||||
|
||||
super.decode(payload);
|
||||
try {
|
||||
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
|
||||
width = (int) jsonObject.get("x");
|
||||
|
||||
+2
-1
@@ -38,13 +38,14 @@ public class StreamTextGeneratedMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
this.streamId = payload.getContent();
|
||||
this.text = payload.getSearchableContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent(text);
|
||||
payload.setContent(streamId);
|
||||
return payload;
|
||||
|
||||
+2
-1
@@ -38,13 +38,14 @@ public class StreamTextGeneratingMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
streamId = payload.getContent();
|
||||
text = payload.getSearchableContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent(text);
|
||||
payload.setContent(streamId);
|
||||
return payload;
|
||||
|
||||
@@ -56,7 +56,7 @@ public class TextMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent(text);
|
||||
if(quoteInfo != null) {
|
||||
payload.setBase64edData(Base64.getEncoder().encodeToString(quoteInfo.encode().toJSONString().getBytes(StandardCharsets.UTF_8)));
|
||||
@@ -66,6 +66,7 @@ public class TextMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decode(payload);
|
||||
text = payload.getSearchableContent();
|
||||
if(!TextUtils.isEmpty(payload.getBase64edData())) {
|
||||
String jsonStr = new String(Base64.getDecoder().decode(payload.getBase64edData()), StandardCharsets.UTF_8);
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ public class TipNotificationMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setContent(tip);
|
||||
|
||||
return payload;
|
||||
@@ -32,7 +32,7 @@ public class TipNotificationMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decodeBase(payload);
|
||||
super.decode(payload);
|
||||
tip = payload.getContent();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,14 +43,14 @@ public class TypingMessageContent extends MessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setContent(typingType + "");
|
||||
return payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decodeBase(payload);
|
||||
super.decode(payload);
|
||||
typingType = Integer.parseInt(payload.getContent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class VideoMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public MessagePayload encode() {
|
||||
MessagePayload payload = super.encodeBase();
|
||||
MessagePayload payload = super.encode();
|
||||
payload.setSearchableContent("[视频]");
|
||||
|
||||
payload.setBase64edData(Base64.getEncoder().encodeToString(thumbnailBytes));
|
||||
@@ -73,7 +73,7 @@ public class VideoMessageContent extends MediaMessageContent {
|
||||
|
||||
@Override
|
||||
public void decode(MessagePayload payload) {
|
||||
super.decodeBase(payload);
|
||||
super.decode(payload);
|
||||
thumbnailBytes = Base64.getDecoder().decode(payload.getBase64edData());
|
||||
try {
|
||||
JSONObject jsonObject = (JSONObject) new JSONParser().parse(payload.getContent());
|
||||
|
||||
@@ -38,11 +38,24 @@ public class AdminHttpUtils extends JsonUtils {
|
||||
private static CloseableHttpClient httpClient;
|
||||
|
||||
public static void init(String url, String secret) {
|
||||
adminUrl = url;
|
||||
adminSecret = secret;
|
||||
init(url, secret, 15000);
|
||||
}
|
||||
|
||||
public static void init(String url, String secret, int timeout) {
|
||||
adminUrl = url.trim();
|
||||
adminSecret = secret.trim();
|
||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
|
||||
cm.setValidateAfterInactivity(1000);
|
||||
int connectTimeout = 15000; // 连接超时时间
|
||||
int connectionRequestTimeout = 3000; // 从连接池获取连接的超时时间
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(connectTimeout)
|
||||
.setSocketTimeout(timeout)
|
||||
.setConnectionRequestTimeout(connectionRequestTimeout)
|
||||
.build();
|
||||
|
||||
httpClient = HttpClients.custom()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.setConnectionManager(cm)
|
||||
.evictExpiredConnections()
|
||||
.evictIdleConnections(60L, TimeUnit.SECONDS)
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
@@ -21,6 +22,8 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -34,13 +37,41 @@ public class ChannelHttpUtils extends JsonUtils {
|
||||
private String channelSecret;
|
||||
private final CloseableHttpClient httpClient;
|
||||
|
||||
private final int port;
|
||||
|
||||
private void checkPort() {
|
||||
if (port != 80 && port != 443) {
|
||||
if (port == 18080) {
|
||||
LOG.warn("您传入的频道API地址中的端口是18080,18080端口默认为管理API端口,频道API端口应该为IM服务的HTTP端口,默认为80,请确认是否使用错误!");
|
||||
} else {
|
||||
LOG.warn("您传入的频道API地址中的端口不是80/443,频道API的端口和客户端使用端口一样,都应该为IM服务的HTTP端口,默认为80,请确实是否正确?如果您定制化了IM服务端口或者使用其他端口反向代理IM服务的HTTP端口请忽略此提示。");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ChannelHttpUtils(String imurl, String channelId, String secret) {
|
||||
this.imurl = imurl;
|
||||
this.channelId = channelId;
|
||||
this.channelSecret = secret;
|
||||
this.imurl = imurl.trim();
|
||||
this.channelId = channelId.trim();
|
||||
this.channelSecret = secret.trim();
|
||||
try {
|
||||
URL url = new URL(this.imurl);
|
||||
this.port = url.getPort();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
checkPort();
|
||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
|
||||
cm.setValidateAfterInactivity(1000);
|
||||
int connectTimeout = 5000; // 连接超时时间
|
||||
int socketTimeout = 15000; // 请求超时时间
|
||||
int connectionRequestTimeout = 3000; // 从连接池获取连接的超时时间
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(connectTimeout)
|
||||
.setSocketTimeout(socketTimeout)
|
||||
.setConnectionRequestTimeout(connectionRequestTimeout)
|
||||
.build();
|
||||
httpClient = HttpClients.custom()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.setConnectionManager(cm)
|
||||
.evictExpiredConnections()
|
||||
.evictIdleConnections(60L, TimeUnit.SECONDS)
|
||||
@@ -108,6 +139,7 @@ public class ChannelHttpUtils extends JsonUtils {
|
||||
return fromJsonObject(content, clazz);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
checkPort();
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}finally{
|
||||
|
||||
@@ -3,17 +3,15 @@ package cn.wildfirechat.sdk.utilities;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import ikidou.reflect.TypeBuilder;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.slf4j.Logger;
|
||||
@@ -21,7 +19,8 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -35,13 +34,41 @@ public class RobotHttpUtils extends JsonUtils {
|
||||
private final String robotSecret;
|
||||
private final CloseableHttpClient httpClient;
|
||||
|
||||
private final int port;
|
||||
|
||||
private void checkPort() {
|
||||
if (port != 80 && port != 443) {
|
||||
if (port == 18080) {
|
||||
LOG.warn("您传入的机器人API地址中的端口是18080,18080端口默认为管理API端口,机器人API端口应该为IM服务的HTTP端口,默认为80,请确认是否使用错误!");
|
||||
} else {
|
||||
LOG.warn("您传入的机器人API地址中的端口不是80/443,机器人API的端口和客户端使用端口一样,都应该为IM服务的HTTP端口,默认为80,请确实是否正确?如果您定制化了IM服务端口或者使用其他端口反向代理IM服务的HTTP端口请忽略此提示。");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RobotHttpUtils(String url, String robotId, String robotSecret) {
|
||||
this.url = url;
|
||||
this.robotId = robotId;
|
||||
this.robotSecret = robotSecret;
|
||||
this.url = url.trim();
|
||||
this.robotId = robotId.trim();
|
||||
this.robotSecret = robotSecret.trim();
|
||||
try {
|
||||
URL u = new URL(this.url);
|
||||
this.port = u.getPort();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
checkPort();
|
||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
|
||||
cm.setValidateAfterInactivity(1000);
|
||||
int connectTimeout = 5000; // 连接超时时间
|
||||
int socketTimeout = 15000; // 请求超时时间
|
||||
int connectionRequestTimeout = 3000; // 从连接池获取连接的超时时间
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(connectTimeout)
|
||||
.setSocketTimeout(socketTimeout)
|
||||
.setConnectionRequestTimeout(connectionRequestTimeout)
|
||||
.build();
|
||||
httpClient = HttpClients.custom()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.setConnectionManager(cm)
|
||||
.evictExpiredConnections()
|
||||
.evictIdleConnections(60L, TimeUnit.SECONDS)
|
||||
@@ -51,7 +78,6 @@ public class RobotHttpUtils extends JsonUtils {
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
public <T> IMResult<T> httpJsonPost(String path, Object object, Class<T> clazz) throws Exception{
|
||||
if (isNullOrEmpty(url) || isNullOrEmpty(path)) {
|
||||
LOG.error("Not init IM SDK correctly. Do you forget init it?");
|
||||
@@ -111,6 +137,7 @@ public class RobotHttpUtils extends JsonUtils {
|
||||
return fromJsonObject(content, clazz);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
checkPort();
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}finally{
|
||||
|
||||
Reference in New Issue
Block a user