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 |
@@ -111,7 +111,7 @@ message.disable_remote_search false
|
||||
##如果要避免数据库中明文存储消息内容,请打开这个开关和message.disable_remote_search开关
|
||||
message.encrypt_message_content false
|
||||
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。0是不允许撤回;-1是无限制撤回。
|
||||
##Server API不受此限制,可以撤回任意时限内的消息
|
||||
##群组管理员或群主撤回群成员消息不受此限制,可以撤回任意时限内的消息。但管理员或群主撤回自己的消息还是需要准守此时间限制。
|
||||
##修改此参数需要同步修改客户端UI,客户端UI代码有判断撤回是否显示的逻辑。
|
||||
@@ -152,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
|
||||
|
||||
@@ -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`);
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.3</version>
|
||||
<version>1.3.6</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
|
||||
@@ -36,6 +36,7 @@ public class PushMessage {
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -163,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";
|
||||
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -39,6 +39,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
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;
|
||||
@@ -101,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) {
|
||||
@@ -170,9 +174,11 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,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) {
|
||||
@@ -239,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;
|
||||
@@ -256,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)) {
|
||||
|
||||
@@ -205,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<>();
|
||||
@@ -608,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"));
|
||||
@@ -620,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);
|
||||
@@ -900,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();
|
||||
|
||||
@@ -933,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;
|
||||
}
|
||||
@@ -1937,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;
|
||||
|
||||
@@ -2454,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;
|
||||
@@ -4458,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());
|
||||
}
|
||||
}
|
||||
@@ -4724,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;
|
||||
|
||||
@@ -242,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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -486,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);
|
||||
@@ -530,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())) {
|
||||
@@ -545,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())) {
|
||||
@@ -667,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;
|
||||
@@ -678,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);
|
||||
@@ -733,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);
|
||||
@@ -752,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 {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.3</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";
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.3</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年前的历史消息。
|
||||
@@ -106,7 +108,7 @@ message.disable_remote_search false
|
||||
##如果要避免数据库中明文存储消息内容,请打开这个开关和message.disable_remote_search开关
|
||||
message.encrypt_message_content false
|
||||
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。0是不允许撤回;-1是无限制撤回。
|
||||
##Server API不受此限制,可以撤回任意时限内的消息
|
||||
##群组管理员或群主撤回群成员消息不受此限制,可以撤回任意时限内的消息。但管理员或群主撤回自己的消息还是需要准守此时间限制。
|
||||
##修改此参数需要同步修改客户端UI,客户端UI代码有判断撤回是否显示的逻辑。
|
||||
@@ -147,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
|
||||
@@ -224,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不受影响。
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>1.3.3</version>
|
||||
<version>1.3.6</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
@@ -12,6 +12,30 @@
|
||||
|
||||
# 更新记录
|
||||
|
||||
--------------
|
||||
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. 转移群组时检查新群主是否在群中。
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.3</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);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
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.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.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