Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30cd56aae2 | ||
|
|
6fbecfb0fb | ||
|
|
d2cb8427bb | ||
|
|
826bad2d66 | ||
|
|
aaccec00e9 | ||
|
|
3c1c5ce6d3 | ||
|
|
b0fe1636a7 | ||
|
|
014cd3844d | ||
|
|
6cc00950f0 | ||
|
|
2918c06a01 | ||
|
|
c3b9b9fccf | ||
|
|
8c88d5a13f | ||
|
|
967526f5ec | ||
|
|
109078abca | ||
|
|
79a58e99aa | ||
|
|
a394444c86 | ||
|
|
dece1d7a1c |
@@ -57,10 +57,13 @@ token.key testim
|
||||
##token.expire_time 2592000000
|
||||
|
||||
##首次登录,是否接收之前的历史消息。
|
||||
##0 不接收历史消息,只接收5分钟以内的消息,由于服务器没有保存已经收取记录,所以如果有超过5分钟之前未收取的消息也不会收取下拉;
|
||||
##0 不接收历史消息,只接收${message.compensate_time_limit}毫秒以内的消息,由于服务器没有保存已经收取记录,所以如果有超过${message.compensate_time_limit}毫秒之前未收取的消息也不会收取下拉;
|
||||
##1接收,会接收 message.max_queue 配置的条数的历史消息
|
||||
message.roaming 0
|
||||
|
||||
## 消息补偿时限,当${message.roaming}为0时,会同步时限以内且小于${message.max_queue}的消息,默认时限为5分钟。当${message.roaming}为1时,会接收 message.max_queue 配置的条数的历史消息。
|
||||
message.compensate_time_limit 300000
|
||||
|
||||
##是否开启拉取远程历史消息。如果为1,客户端在会话内如果本地消息读取完了,可以下拉继续加载在服务器上的该会话的消息;如果为0则不能。
|
||||
message.remote_history_message 0
|
||||
|
||||
@@ -109,6 +112,15 @@ message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
|
||||
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
|
||||
message.no_forward_admin_message false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上用户clientId和平台类型。
|
||||
message.forward_with_client_info false
|
||||
|
||||
## 机器人回调信息是否带上用户clientId和平台类型。
|
||||
robot.callback_with_client_info false
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
##禁止搜索用户
|
||||
friend.disable_search false
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table `t_channel` add column `_menu` BLOB DEFAULT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_channel` add column `_menu` BLOB DEFAULT NULL;
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.90</version>
|
||||
<version>0.92</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
|
||||
@@ -131,6 +131,7 @@ public final class BrokerConstants {
|
||||
public static final String SERVER_CLIENT_SUPPORT_KICKOFF_EVENT = "server.client_support_kickoff_event";
|
||||
|
||||
public static final String MESSAGE_ROAMING = "message.roaming";
|
||||
public static final String MESSAGE_Compensate_Time_Limit = "message.compensate_time_limit";
|
||||
public static final String MESSAGE_Remote_History_Message = "message.remote_history_message";
|
||||
public static final String MESSAGE_Remote_Chatroom_History_Message = "message.chatroom_remote_history_message";
|
||||
|
||||
@@ -142,6 +143,10 @@ public final class BrokerConstants {
|
||||
|
||||
public static final String MESSAGE_NO_Forward_Admin_Message = "message.no_forward_admin_message";
|
||||
|
||||
public static final String MESSAGE_Forward_With_Client_Info = "message.forward_with_client_info";
|
||||
public static final String ROBOT_Callback_With_Client_Info = "robot.callback_with_client_info";
|
||||
public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_info";
|
||||
|
||||
public static final String FRIEND_Disable_Search = "friend.disable_search";
|
||||
public static final String FRIEND_Disable_NickName_Search = "friend.disable_nick_name_search";
|
||||
public static final String FRIEND_Disable_Friend_Request = "friend.disable_friend_request";
|
||||
|
||||
@@ -21,6 +21,9 @@ import win.liyufan.im.IMTopic;
|
||||
public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.CreateGroupRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
if(request.getGroup().getGroupInfo().getType() < 0 || request.getGroup().getGroupInfo().getType() > 2) {
|
||||
return ErrorCode.ERROR_CODE_INVALID_DATA;
|
||||
}
|
||||
|
||||
if (!StringUtil.isNullOrEmpty(request.getGroup().getGroupInfo().getTargetId())) {
|
||||
WFCMessage.GroupInfo existGroupInfo = m_messagesStore.getGroupInfo(request.getGroup().getGroupInfo().getTargetId());
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.pojos.OutputClient;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import io.moquette.BrokerConstants;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
@@ -171,12 +173,20 @@ 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)) {
|
||||
publisher.forwardMessage(message, mForwardUrl);
|
||||
publisher.forwardMessage(message, mForwardUrl, outputClient);
|
||||
}
|
||||
|
||||
if(!StringUtil.isNullOrEmpty(mMentionForwardUrl) && message.hasContent() && message.getContent().getMentionedType() != 0 && !(isAdmin && mNoForwardAdminMessage)) {
|
||||
publisher.forwardMessage(message, mMentionForwardUrl);
|
||||
publisher.forwardMessage(message, mMentionForwardUrl, outputClient);
|
||||
}
|
||||
|
||||
if (!isAdmin) {
|
||||
|
||||
@@ -2972,7 +2972,8 @@ public class DatabaseStore {
|
||||
", `_secret`" +
|
||||
", `_callback`" +
|
||||
", `_automatic`" +
|
||||
", `_dt`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
|
||||
", `_menu`" +
|
||||
", `_dt`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
|
||||
" ON DUPLICATE KEY UPDATE `_name`=?" +
|
||||
", `_portrait`=?" +
|
||||
", `_owner`=?" +
|
||||
@@ -2982,12 +2983,20 @@ public class DatabaseStore {
|
||||
", `_secret`=?" +
|
||||
", `_callback`=?" +
|
||||
", `_automatic`=?" +
|
||||
", `_menu`=?" +
|
||||
", `_dt`=?";
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
WFCMessage.ChannelMenuList.Builder builder = WFCMessage.ChannelMenuList.newBuilder();
|
||||
if (!channelInfo.getMenuList().isEmpty()) {
|
||||
for (WFCMessage.ChannelMenu menuBtn:channelInfo.getMenuList()) {
|
||||
builder.addMenu(menuBtn);
|
||||
}
|
||||
}
|
||||
byte[] menuBytes = builder.build().toByteArray();
|
||||
|
||||
int index = 1;
|
||||
statement.setString(index++, channelInfo.getTargetId());
|
||||
statement.setString(index++, channelInfo.getName());
|
||||
statement.setString(index++, channelInfo.getPortrait());
|
||||
@@ -2998,6 +3007,7 @@ public class DatabaseStore {
|
||||
statement.setString(index++, channelInfo.getSecret());
|
||||
statement.setString(index++, channelInfo.getCallback());
|
||||
statement.setInt(index++, channelInfo.getAutomatic());
|
||||
statement.setBytes(index++, menuBytes);
|
||||
statement.setLong(index++, channelInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : channelInfo.getUpdateDt());
|
||||
|
||||
statement.setString(index++, channelInfo.getName());
|
||||
@@ -3009,6 +3019,7 @@ public class DatabaseStore {
|
||||
statement.setString(index++, channelInfo.getSecret());
|
||||
statement.setString(index++, channelInfo.getCallback());
|
||||
statement.setInt(index++, channelInfo.getAutomatic());
|
||||
statement.setBytes(index++, menuBytes);
|
||||
statement.setLong(index++, channelInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : channelInfo.getUpdateDt());
|
||||
|
||||
int count = statement.executeUpdate();
|
||||
@@ -3061,6 +3072,7 @@ public class DatabaseStore {
|
||||
", `_secret`" +
|
||||
", `_callback`" +
|
||||
", `_automatic`" +
|
||||
", `_menu`" +
|
||||
", `_dt` from t_channel where `_cid` = ?";
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
@@ -3111,6 +3123,21 @@ public class DatabaseStore {
|
||||
intValue = rs.getInt(index++);
|
||||
builder.setAutomatic(intValue);
|
||||
|
||||
try {
|
||||
byte[] bytes = null;
|
||||
Blob blob = rs.getBlob(index++);
|
||||
if (blob != null) {
|
||||
bytes = toByteArray(blob.getBinaryStream());
|
||||
}
|
||||
|
||||
WFCMessage.ChannelMenuList menuButtonList = WFCMessage.ChannelMenuList.parseFrom(bytes);
|
||||
if (menuButtonList.getMenuCount() > 0) {
|
||||
builder.addAllMenu(menuButtonList.getMenuList());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
long longValue = rs.getLong(index++);
|
||||
builder.setUpdateDt(longValue);
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private static final String CHANNEL_LISTENERS = "channel_listeners";
|
||||
|
||||
private static boolean IS_MESSAGE_ROAMING = true;
|
||||
private static long msgCompensateTimeLimit = 300000;
|
||||
|
||||
private static boolean IS_MESSAGE_REMOTE_HISTORY_MESSAGE = true;
|
||||
private static boolean IS_CHATROOM_MESSAGE_REMOTE_HISTORY_MESSAGE = true;
|
||||
@@ -167,6 +168,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private int mSyncDataPartSize = 0;
|
||||
private boolean keepDisplayNameWhenDestroyUser = true;
|
||||
|
||||
private boolean mForwardMessageWithClientInfo = false;
|
||||
private boolean mRobotCallbackWithClientInfo = false;
|
||||
private boolean mChannelCallbackWithClientInfo = false;
|
||||
|
||||
private Set<Integer> mUserHideProperties = new HashSet<>();
|
||||
|
||||
MemoryMessagesStore(Server server, DatabaseStore databaseStore) {
|
||||
@@ -174,6 +179,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
this.databaseStore = databaseStore;
|
||||
|
||||
IS_MESSAGE_ROAMING = "1".equals(m_Server.getConfig().getProperty(MESSAGE_ROAMING));
|
||||
try {
|
||||
msgCompensateTimeLimit = Long.parseLong(m_Server.getConfig().getProperty(MESSAGE_Compensate_Time_Limit, "300000"));
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
}
|
||||
IS_MESSAGE_REMOTE_HISTORY_MESSAGE = "1".equals(m_Server.getConfig().getProperty(MESSAGE_Remote_History_Message));
|
||||
IS_CHATROOM_MESSAGE_REMOTE_HISTORY_MESSAGE = "1".equals(m_Server.getConfig().getProperty(MESSAGE_Remote_Chatroom_History_Message, "1"));
|
||||
Constants.MAX_MESSAGE_QUEUE = Integer.parseInt(m_Server.getConfig().getProperty(MESSAGE_Max_Queue));
|
||||
@@ -446,6 +456,23 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
mForwardMessageWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void printMissConfigLog(String config, String defaultValue) {
|
||||
@@ -718,7 +745,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
}
|
||||
|
||||
if (noRoaming && (System.currentTimeMillis() - bundle.getMessage().getServerTimestamp() > 5 * 60 * 1000)) {
|
||||
if (noRoaming && (System.currentTimeMillis() - bundle.getMessage().getServerTimestamp() > msgCompensateTimeLimit)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1279,11 +1306,31 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ArrayList<String> existMemberIds = new ArrayList<>();
|
||||
for (WFCMessage.GroupMember member : members) {
|
||||
if (member.getType() != GroupMemberType_Removed) {
|
||||
existMemberIds.add(member.getMemberId());
|
||||
}
|
||||
}
|
||||
|
||||
long updateDt = System.currentTimeMillis();
|
||||
|
||||
List<WFCMessage.GroupMember> tmp = new ArrayList<>();
|
||||
ArrayList<String> newInviteUsers = new ArrayList<>();
|
||||
int newMemberCount = 0;
|
||||
for (WFCMessage.GroupMember member : memberList) {
|
||||
if (existMemberIds.contains(member.getMemberId()) && member.getType() != GroupMemberType_Removed) {
|
||||
if(!isAdmin)
|
||||
continue;
|
||||
} else {
|
||||
newMemberCount++;
|
||||
}
|
||||
|
||||
WFCMessage.GroupMember.Builder builder = member.toBuilder();
|
||||
builder.setUpdateDt(updateDt).setCreateDt(updateDt);
|
||||
if (member.getMemberId().equals(groupInfo.getOwner())) {
|
||||
@@ -1303,29 +1350,23 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
member = builder.build();
|
||||
tmp.add(member);
|
||||
newInviteUsers.add(member.getMemberId());
|
||||
updateDt++;
|
||||
}
|
||||
memberList = tmp;
|
||||
|
||||
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
|
||||
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
|
||||
if (members == null || members.size() == 0) {
|
||||
members = loadGroupMemberFromDB(hzInstance, groupId);
|
||||
}
|
||||
|
||||
if (maxCount != Integer.MAX_VALUE) {
|
||||
int existCount = 0;
|
||||
for (WFCMessage.GroupMember member : members) {
|
||||
if (member.getType() != GroupMemberType_Removed) {
|
||||
existCount++;
|
||||
}
|
||||
if (memberList.size() == 0) {
|
||||
if (!isAdmin) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_IN_GROUP;
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
if (existCount + newInviteUsers.size() > maxCount) {
|
||||
} else {
|
||||
if (existMemberIds.size() + newMemberCount > maxCount) {
|
||||
return ErrorCode.ERROR_CODE_GROUP_EXCEED_MAX_MEMBER_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
databaseStore.persistGroupMember(groupId, memberList, true);
|
||||
databaseStore.updateGroupMemberCountDt(groupId);
|
||||
|
||||
@@ -3847,9 +3888,15 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
} else if(modifyType == Modify_Channel_Menu) {
|
||||
OutputGetChannelInfo.OutputMenuList outputMenuButtons = new Gson().fromJson(value, OutputGetChannelInfo.OutputMenuList.class);
|
||||
if (!outputMenuButtons.isEmpty()) {
|
||||
for (OutputGetChannelInfo.OutputMenu outputMenuButton : outputMenuButtons) {
|
||||
newInfoBuilder.addMenu(outputMenuButton.toPbInfo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
newInfoBuilder.setUpdateDt(System.currentTimeMillis());
|
||||
mIMap.put(channelId, newInfoBuilder.build());
|
||||
callbackChannelInfoUpdateEvent(operator, channelId, Channel_Event_Update);
|
||||
@@ -4066,6 +4113,20 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return mGroupVisibleQuitKickoffNotification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForwardMessageWithClientInfo() {
|
||||
return mForwardMessageWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotCallbackWithClientInfo() {
|
||||
return mRobotCallbackWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithClientInfo() {
|
||||
return mChannelCallbackWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getClientForbiddenSendTypes() {
|
||||
|
||||
@@ -369,9 +369,6 @@ public class Server {
|
||||
private String getServerIp(IConfig config) {
|
||||
String serverIp = config.getProperty(BrokerConstants.SERVER_IP_PROPERTY_NAME);
|
||||
if (serverIp == null || serverIp.equals("0.0.0.0")) {
|
||||
String warning = "警告:无效配置,server.ip不能为空,需要配置服务的公网IP地址或者域名才能在公网使用!!!\nIM服务将使用本地地址,只能在局域网内使用!";
|
||||
System.out.println(warning);
|
||||
LOG.error(warning);
|
||||
serverIp = Utility.getLocalAddress().getHostAddress();
|
||||
}
|
||||
return serverIp;
|
||||
|
||||
@@ -233,6 +233,10 @@ public interface IMessagesStore {
|
||||
boolean isAllowRobotCustomGroupNotification();
|
||||
int getVisibleQuitKickoffNotification();
|
||||
|
||||
boolean isForwardMessageWithClientInfo();
|
||||
boolean isRobotCallbackWithClientInfo();
|
||||
boolean isChannelCallbackWithClientInfo();
|
||||
|
||||
List<Integer> getClientForbiddenSendTypes();
|
||||
List<Integer> getBlackListExceptionTypes();
|
||||
List<Integer> getGroupMuteExceptionTypes();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package io.moquette.spi.impl;
|
||||
|
||||
import cn.wildfirechat.pojos.OutputClient;
|
||||
import cn.wildfirechat.pojos.OutputMessageData;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
@@ -175,10 +176,19 @@ public class MessagesPublisher {
|
||||
if (message == null) {
|
||||
message = m_messagesStore.getMessage(messageId);
|
||||
}
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isRobotCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
|
||||
Session session = m_sessionsStore.getSession(exceptClientId);
|
||||
if(session != null && session.getUsername().equals(sender)) {
|
||||
outputClient = new OutputClient(session.getPlatform(), exceptClientId);
|
||||
}
|
||||
}
|
||||
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
OutputClient finalOutputClient = outputClient;
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(OutputMessageData.fromProtoMessage(finalMsg), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(OutputMessageData.fromProtoMessage(finalMsg, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -594,10 +604,19 @@ public class MessagesPublisher {
|
||||
public void publish2Receivers(WFCMessage.Message message, Set<String> receivers, String exceptClientId, int pullType) {
|
||||
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
|
||||
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
|
||||
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback()) && channelInfo.getAutomatic() == 1 && !message.getFromUser().equals(channelInfo.getOwner())) {
|
||||
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;
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(OutputMessageData.fromProtoMessage(message, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -647,10 +666,10 @@ public class MessagesPublisher {
|
||||
|
||||
}
|
||||
|
||||
public void forwardMessage(final WFCMessage.Message message, String forwardUrl) {
|
||||
public void forwardMessage(final WFCMessage.Message message, String forwardUrl, OutputClient outputClient) {
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
|
||||
HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message, outputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -682,7 +701,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) {
|
||||
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
|
||||
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback()) || channelInfo.getAutomatic() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public class DBUtil {
|
||||
if (embedDB != null && embedDB.equals("1")) {
|
||||
IsEmbedDB = true;
|
||||
LOG.info("Use h2 database");
|
||||
String warning = "您正在使用内置h2数据库,建议仅在开发验证或者用户数小于100人时才使用此数据库,其它情况建议使用MySQL。";
|
||||
String warning = "您正在使用h2数据库,建议仅在开发验证或者用户数小于100人时才使用此数据库。正式上线时建议切换到MySQL数据库。";
|
||||
System.out.println(warning);
|
||||
LOG.warn(warning);
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.90</version>
|
||||
<version>0.92</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -57,6 +57,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_ConvRead = "/admin/message/conv_read";
|
||||
String Msg_Delivery = "/admin/message/delivery";
|
||||
|
||||
String Create_Group = "/admin/group/create";
|
||||
String Group_Dismiss = "/admin/group/del";
|
||||
|
||||
@@ -29,6 +29,7 @@ public enum ErrorCode {
|
||||
|
||||
//Group error
|
||||
ERROR_CODE_GROUP_ALREADY_EXIST(11, "group already exist"),
|
||||
ERROR_CODE_ALREADY_IN_GROUP(12, "member already in group"),
|
||||
|
||||
//user error
|
||||
ERROR_CODE_FRIEND_ALREADY_REQUEST(16, "already send request"),
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
public class ArticleContent {
|
||||
public static class Article {
|
||||
public String id;
|
||||
public String cover;
|
||||
public String title;
|
||||
public String url;
|
||||
public boolean rr;
|
||||
|
||||
public Article() {
|
||||
}
|
||||
|
||||
public Article(String id, String cover, String title, String url, boolean rr) {
|
||||
this.id = id;
|
||||
this.cover = cover;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.rr = rr;
|
||||
}
|
||||
}
|
||||
public Article top;
|
||||
public List<Article> subArticles;
|
||||
|
||||
public ArticleContent() {
|
||||
}
|
||||
|
||||
public ArticleContent(String id, String cover, String title, String url, boolean rr) {
|
||||
this.top = new Article(id, cover, title, url, rr);
|
||||
}
|
||||
|
||||
public ArticleContent addSubArticle(String id, String cover, String title, String url, boolean rr) {
|
||||
if (subArticles == null)
|
||||
subArticles = new ArrayList<>();
|
||||
subArticles.add(new Article(id, cover, title, url, rr));
|
||||
return this;
|
||||
}
|
||||
|
||||
public MessagePayload toPayload() {
|
||||
MessagePayload payload = new MessagePayload();
|
||||
payload.setType(13);
|
||||
payload.setSearchableContent(top.title);
|
||||
payload.setBase64edData(Base64.getEncoder().encodeToString(new Gson().toJson(this).getBytes(StandardCharsets.UTF_8)));
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,5 @@ package cn.wildfirechat.pojos;
|
||||
public class ConferenceJoinEvent {
|
||||
public String userId;
|
||||
public String roomId;
|
||||
public boolean screenSharing;
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@ package cn.wildfirechat.pojos;
|
||||
public class ConferenceLeaveEvent {
|
||||
public String userId;
|
||||
public String roomId;
|
||||
public boolean screenSharing;
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ public class ConferencePublishEvent {
|
||||
public String userId;
|
||||
public boolean video;
|
||||
public String roomId;
|
||||
public boolean screenSharing;
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@ package cn.wildfirechat.pojos;
|
||||
public class ConferenceUnpublishEvent {
|
||||
public String userId;
|
||||
public String roomId;
|
||||
public boolean screenSharing;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,15 @@ public class Conversation {
|
||||
private String target;
|
||||
private int line;
|
||||
|
||||
public Conversation() {
|
||||
}
|
||||
|
||||
public Conversation(int type, String target, int line) {
|
||||
this.type = type;
|
||||
this.target = target;
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ public class ForwardDeviceMessageData {
|
||||
private int type;
|
||||
private byte[] data;
|
||||
|
||||
public ForwardDeviceMessageData() {
|
||||
}
|
||||
|
||||
public ForwardDeviceMessageData(String deviceId, int type, byte[] data) {
|
||||
this.deviceId = deviceId;
|
||||
this.type = type;
|
||||
|
||||
@@ -31,6 +31,9 @@ public class GroupNotificationBinaryContent {
|
||||
//value2(member or something)
|
||||
private String m;
|
||||
|
||||
public GroupNotificationBinaryContent() {
|
||||
}
|
||||
|
||||
public GroupNotificationBinaryContent(String g, String o, String n, String m) {
|
||||
this.g = g;
|
||||
this.o = o;
|
||||
|
||||
@@ -13,6 +13,9 @@ public class InputChatroomMute {
|
||||
private String chatroomId;
|
||||
private int status;
|
||||
|
||||
public InputChatroomMute() {
|
||||
}
|
||||
|
||||
public InputChatroomMute(String chatroomId, int status) {
|
||||
this.chatroomId = chatroomId;
|
||||
this.status = status;
|
||||
|
||||
@@ -67,16 +67,18 @@ public class InputCreateGroup extends InputGroupBase {
|
||||
}
|
||||
|
||||
groupBuilder.setGroupInfo(groupInfoBuilder);
|
||||
for (PojoGroupMember pojoGroupMember : group.getMembers()) {
|
||||
WFCMessage.GroupMember.Builder groupMemberBuilder = WFCMessage.GroupMember.newBuilder().setMemberId(pojoGroupMember.getMember_id());
|
||||
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getAlias())) {
|
||||
groupMemberBuilder.setAlias(pojoGroupMember.getAlias());
|
||||
if(group.getMembers() != null) {
|
||||
for (PojoGroupMember pojoGroupMember : group.getMembers()) {
|
||||
WFCMessage.GroupMember.Builder groupMemberBuilder = WFCMessage.GroupMember.newBuilder().setMemberId(pojoGroupMember.getMember_id());
|
||||
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getAlias())) {
|
||||
groupMemberBuilder.setAlias(pojoGroupMember.getAlias());
|
||||
}
|
||||
groupMemberBuilder.setType(pojoGroupMember.getType());
|
||||
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getExtra())) {
|
||||
groupMemberBuilder.setExtra(pojoGroupMember.extra);
|
||||
}
|
||||
groupBuilder.addMembers(groupMemberBuilder);
|
||||
}
|
||||
groupMemberBuilder.setType(pojoGroupMember.getType());
|
||||
if(!StringUtil.isNullOrEmpty(pojoGroupMember.getExtra())) {
|
||||
groupMemberBuilder.setExtra(pojoGroupMember.extra);
|
||||
}
|
||||
groupBuilder.addMembers(groupMemberBuilder);
|
||||
}
|
||||
|
||||
WFCMessage.CreateGroupRequest.Builder createGroupReqBuilder = WFCMessage.CreateGroupRequest.newBuilder();
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class InputGetConvReadTime {
|
||||
private String userId;
|
||||
private int conversationType;
|
||||
private String target;
|
||||
private int line;
|
||||
|
||||
public InputGetConvReadTime() {
|
||||
}
|
||||
|
||||
public InputGetConvReadTime(String userId, int conversationType, String target, int line) {
|
||||
this.userId = userId;
|
||||
this.conversationType = conversationType;
|
||||
this.target = target;
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public int getConversationType() {
|
||||
return conversationType;
|
||||
}
|
||||
|
||||
public void setConversationType(int conversationType) {
|
||||
this.conversationType = conversationType;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public void setLine(int line) {
|
||||
this.line = line;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,9 @@ public class InputGetToken {
|
||||
private String clientId;
|
||||
private Integer platform;
|
||||
|
||||
public InputGetToken() {
|
||||
}
|
||||
|
||||
public InputGetToken(String userId, String clientId, int platform) {
|
||||
this.userId = userId;
|
||||
this.clientId = clientId;
|
||||
|
||||
@@ -13,6 +13,9 @@ public class InputGetUserInfo {
|
||||
private String name;
|
||||
private String mobile;
|
||||
|
||||
public InputGetUserInfo() {
|
||||
}
|
||||
|
||||
public InputGetUserInfo(String userId, String name, String mobile) {
|
||||
this.userId = userId;
|
||||
this.name = name;
|
||||
|
||||
@@ -13,6 +13,9 @@ public class InputOutputUserBlockStatus {
|
||||
private String userId;
|
||||
private int status;
|
||||
|
||||
public InputOutputUserBlockStatus() {
|
||||
}
|
||||
|
||||
public InputOutputUserBlockStatus(String userId, int status) {
|
||||
this.userId = userId;
|
||||
this.status = status;
|
||||
|
||||
@@ -11,6 +11,13 @@ package cn.wildfirechat.pojos;
|
||||
public class InputUserId {
|
||||
private String userId;
|
||||
|
||||
public InputUserId() {
|
||||
}
|
||||
|
||||
public InputUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OutputClient {
|
||||
private int platform;
|
||||
private String clientId;
|
||||
|
||||
public OutputClient() {
|
||||
}
|
||||
|
||||
public OutputClient(int platform, String clientId) {
|
||||
this.platform = platform;
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public int getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(int platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ public class OutputCreateDevice {
|
||||
private String token;
|
||||
private String secret;
|
||||
|
||||
public OutputCreateDevice() {
|
||||
}
|
||||
|
||||
public OutputCreateDevice(String userId, String token, String secret) {
|
||||
this.deviceId = userId;
|
||||
this.token = token;
|
||||
|
||||
@@ -12,6 +12,9 @@ public class OutputCreateRobot {
|
||||
private String userId;
|
||||
private String secret;
|
||||
|
||||
public OutputCreateRobot() {
|
||||
}
|
||||
|
||||
public OutputCreateRobot(String userId, String secret) {
|
||||
this.userId = userId;
|
||||
this.secret = secret;
|
||||
|
||||
@@ -12,6 +12,9 @@ public class OutputCreateUser {
|
||||
private String userId;
|
||||
private String name;
|
||||
|
||||
public OutputCreateUser() {
|
||||
}
|
||||
|
||||
public OutputCreateUser(String userId, String name) {
|
||||
this.userId = userId;
|
||||
this.name = name;
|
||||
|
||||
@@ -20,6 +20,9 @@ public class OutputDevice {
|
||||
private List<String> owners;
|
||||
private String extra;
|
||||
|
||||
public OutputDevice() {
|
||||
}
|
||||
|
||||
public OutputDevice(String deviceId, String token, String secret) {
|
||||
this.deviceId = deviceId;
|
||||
this.token = token;
|
||||
|
||||
@@ -10,8 +10,69 @@ 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 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> {
|
||||
|
||||
}
|
||||
|
||||
private String channelId;
|
||||
private String name;
|
||||
private String desc;
|
||||
@@ -24,7 +85,7 @@ public class OutputGetChannelInfo {
|
||||
private String callback;
|
||||
private int automatic;
|
||||
private String secret;
|
||||
|
||||
public List<OutputMenu> menus;
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
@@ -136,6 +197,13 @@ public class OutputGetChannelInfo {
|
||||
out.status = channelInfo.getStatus();;
|
||||
out.updateDt = channelInfo.getUpdateDt();
|
||||
out.secret = channelInfo.getSecret();
|
||||
if (channelInfo.getMenuCount() > 0) {
|
||||
out.menus = new ArrayList<>();
|
||||
for (WFCMessage.ChannelMenu channelMenuMenu : channelInfo.getMenuList()) {
|
||||
out.menus.add(OutputMenu.fromPbInfo(channelMenuMenu));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ public class OutputLoginData {
|
||||
private String userId;
|
||||
private String token;
|
||||
|
||||
public OutputLoginData() {
|
||||
}
|
||||
|
||||
public OutputLoginData(String userId, String token) {
|
||||
this.userId = userId;
|
||||
this.token = token;
|
||||
|
||||
@@ -20,6 +20,7 @@ public class OutputMessageData {
|
||||
private MessagePayload payload;
|
||||
private List<String> toUsers;
|
||||
private long timestamp;
|
||||
private OutputClient client;
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
@@ -69,7 +70,19 @@ public class OutputMessageData {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public OutputClient getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(OutputClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public static OutputMessageData fromProtoMessage(WFCMessage.Message protoMessage) {
|
||||
return fromProtoMessage(protoMessage, null);
|
||||
}
|
||||
|
||||
public static OutputMessageData fromProtoMessage(WFCMessage.Message protoMessage, OutputClient fromClient) {
|
||||
OutputMessageData data = new OutputMessageData();
|
||||
data.messageId = protoMessage.getMessageId();
|
||||
data.sender = protoMessage.getFromUser();
|
||||
@@ -80,6 +93,7 @@ public class OutputMessageData {
|
||||
data.payload = MessagePayload.fromProtoMessageContent(protoMessage.getContent());
|
||||
data.timestamp = protoMessage.getServerTimestamp();
|
||||
data.toUsers = protoMessage.getToList();
|
||||
data.client = fromClient;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ public class OutputNotifyChannelSubscribeStatus {
|
||||
private String channelId;
|
||||
private int status;
|
||||
|
||||
public OutputNotifyChannelSubscribeStatus() {
|
||||
}
|
||||
|
||||
public OutputNotifyChannelSubscribeStatus(String userId, String channelId, boolean subscirbed) {
|
||||
this.userId = userId;
|
||||
this.channelId = channelId;
|
||||
|
||||
@@ -16,6 +16,9 @@ public class OutputRouteData { ;
|
||||
private int shortPort;
|
||||
private String secret;
|
||||
|
||||
public OutputRouteData() {
|
||||
}
|
||||
|
||||
public OutputRouteData(List<String> serverIPs, int longPort, int shortPort, String secret) {
|
||||
this.serverIPs = serverIPs;
|
||||
this.longPort = longPort;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class OutputTimestamp {
|
||||
private long timestamp;
|
||||
|
||||
public OutputTimestamp() {
|
||||
}
|
||||
|
||||
public OutputTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -173,6 +173,7 @@ public class ProtoConstants {
|
||||
int Modify_Channel_Secret = 4;
|
||||
int Modify_Channel_Callback = 5;
|
||||
int Modify_Channel_OnlyCallback = 6;
|
||||
int Modify_Channel_Menu = 7;
|
||||
}
|
||||
|
||||
//Channel -> status
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.90</version>
|
||||
<version>0.92</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>distribution</artifactId>
|
||||
@@ -51,7 +51,7 @@
|
||||
<!--指定"git.properties"文件的存放路径(相对于${project.basedir}的一个路径);-->
|
||||
<generateGitPropertiesFilename>src/main/resources/git.properties</generateGitPropertiesFilename>
|
||||
<!--".git"文件夹未找到时,构建是否失败;若设置true,则构建失败;若设置false,则跳过执行该目标;默认值:true;-->
|
||||
<failOnNoGitDirectory>true</failOnNoGitDirectory>
|
||||
<failOnNoGitDirectory>false</failOnNoGitDirectory>
|
||||
|
||||
<!--git描述配置,可选;由JGit提供实现;-->
|
||||
<gitDescribe>
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
<directory>../broker/config/i18n/</directory>
|
||||
<outputDirectory>/config/i18n</outputDirectory>
|
||||
</fileSet>
|
||||
|
||||
<fileSet>
|
||||
<directory>src/main/resources/</directory>
|
||||
<outputDirectory>config/</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
@@ -40,32 +45,7 @@
|
||||
</file>
|
||||
|
||||
<file>
|
||||
<source>src/main/resources/log4j2.xml</source>
|
||||
<outputDirectory>config/</outputDirectory>
|
||||
<destName>log4j2.xml</destName>
|
||||
</file>
|
||||
|
||||
<file>
|
||||
<source>src/main/resources/wildfirechat.conf</source>
|
||||
<outputDirectory>config/</outputDirectory>
|
||||
</file>
|
||||
|
||||
<file>
|
||||
<source>src/main/resources/hazelcast.xml</source>
|
||||
<outputDirectory>config/</outputDirectory>
|
||||
</file>
|
||||
<file>
|
||||
<source>src/main/resources/c3p0-config.xml</source>
|
||||
<outputDirectory>config/</outputDirectory>
|
||||
</file>
|
||||
|
||||
<file>
|
||||
<source>src/main/resources/README.txt</source>
|
||||
</file>
|
||||
|
||||
<file>
|
||||
<source>src/main/resources/git.properties</source>
|
||||
<outputDirectory>config/</outputDirectory>
|
||||
<source>src/main/files/README.txt</source>
|
||||
</file>
|
||||
|
||||
<file>
|
||||
|
||||
@@ -13,7 +13,8 @@ server.ip 0.0.0.0
|
||||
##原生客户端长链接端口。如果使用4层的反向代理或者类似组件,需要设置长链接保持时间为10分钟。不支持7层代理。
|
||||
port 1883
|
||||
|
||||
##客户端短链接端口,客户端固定使用80端口,不要修改此端口。
|
||||
##客户端短链接端口,客户端固定使用80端口不能修改。
|
||||
##如果是国企事业单位等因为政策原因无法使用80端口,可以联系野火解决。
|
||||
http_port 80
|
||||
|
||||
#管理端口
|
||||
@@ -52,10 +53,13 @@ token.key testim
|
||||
##token.expire_time 2592000000
|
||||
|
||||
##首次登录,是否接收之前的历史消息。
|
||||
##0 不接收历史消息,只接收5分钟以内的消息,由于服务器没有保存已经收取记录,所以如果有超过5分钟之前未收取的消息也不会收取下拉;
|
||||
##0 不接收历史消息,只接收${message.compensate_time_limit}毫秒以内的消息,由于服务器没有保存已经收取记录,所以如果有超过${message.compensate_time_limit}毫秒之前未收取的消息也不会收取下拉;
|
||||
##1接收,会接收 message.max_queue 配置的条数的历史消息
|
||||
message.roaming 0
|
||||
|
||||
## 消息补偿时限,当${message.roaming}为0时,会同步时限以内且小于${message.max_queue}的消息,默认时限为5分钟。当${message.roaming}为1时,会接收 message.max_queue 配置的条数的历史消息。
|
||||
message.compensate_time_limit 300000
|
||||
|
||||
##是否开启拉取远程历史消息。如果为1,客户端在会话内如果本地消息读取完了,可以下拉继续加载在服务器上的该会话的消息;如果为0则不能。
|
||||
message.remote_history_message 0
|
||||
|
||||
@@ -104,6 +108,15 @@ message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
|
||||
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
|
||||
message.no_forward_admin_message false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上用户clientId和平台类型。
|
||||
message.forward_with_client_info false
|
||||
|
||||
## 机器人回调信息是否带上用户clientId和平台类型。
|
||||
robot.callback_with_client_info false
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
##禁止搜索用户
|
||||
friend.disable_search false
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>0.90</version>
|
||||
<version>0.92</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.90</version>
|
||||
<version>0.92</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -8,13 +8,11 @@ import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
import cn.wildfirechat.sdk.utilities.RobotHttpUtils;
|
||||
import com.google.gson.Gson;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.wildfirechat.pojos.MyInfoType.Modify_DisplayName;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ChannelState.*;
|
||||
@@ -750,6 +748,20 @@ public class Main {
|
||||
} else {
|
||||
System.out.println("failure");
|
||||
}
|
||||
|
||||
IMResult<OutputTimestamp> timestampResult = MessageAdmin.getConversationReadTimestamp("57gqmws2k", new Conversation(0, "admin", 0));
|
||||
if(timestampResult != null && timestampResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("Get conversation read time success");
|
||||
} else {
|
||||
System.out.println("Get conversation read time failure");
|
||||
}
|
||||
|
||||
timestampResult = MessageAdmin.getMessageDelivery("57gqmws2k");
|
||||
if(timestampResult != null && timestampResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("Get message delivery success");
|
||||
} else {
|
||||
System.out.println("Get message delivery failure");
|
||||
}
|
||||
}
|
||||
|
||||
List<String> multicastReceivers = Arrays.asList("user2", "user3", "user4");
|
||||
@@ -813,8 +825,8 @@ public class Main {
|
||||
|
||||
IMResult<OutputGetChannelInfo> resultGetChannel = GeneralAdmin.getChannelInfo(inputCreateChannel.getTargetId());
|
||||
if(resultGetChannel != null && resultGetChannel.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS
|
||||
&& resultGetChannel.getResult().getName().equals(channelName)
|
||||
&& resultGetChannel.getResult().getOwner().equals(channelOwner)) {
|
||||
&& resultGetChannel.getResult().getName().equals(channelName)
|
||||
&& resultGetChannel.getResult().getOwner().equals(channelOwner)) {
|
||||
System.out.println("success");
|
||||
} else {
|
||||
System.out.println("get channel failure");
|
||||
@@ -1342,7 +1354,11 @@ public class Main {
|
||||
inputCreateChannel.setName("testChannel");
|
||||
inputCreateChannel.setOwner("userId1");
|
||||
String secret = "channelsecret";
|
||||
String channelId = "channelId123";
|
||||
inputCreateChannel.setSecret(secret);
|
||||
inputCreateChannel.setTargetId(channelId);
|
||||
inputCreateChannel.setAuto(1);
|
||||
inputCreateChannel.setCallback("http://192.168.1.81:8088/wf/channelId123");
|
||||
inputCreateChannel.setState(Channel_State_Mask_FullInfo | Channel_State_Mask_Unsubscribed_User_Access | Channel_State_Mask_Active_Subscribe | Channel_State_Mask_Message_Unsubscribed);
|
||||
IMResult<OutputCreateChannel> resultCreateChannel = GeneralAdmin.createChannel(inputCreateChannel);
|
||||
if (resultCreateChannel != null && resultCreateChannel.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
@@ -1354,7 +1370,7 @@ public class Main {
|
||||
|
||||
|
||||
//2. 初始化api,注意端口是80,不是18080
|
||||
ChannelServiceApi channelServiceApi = new ChannelServiceApi(IMUrl, resultCreateChannel.getResult().getTargetId(), secret);
|
||||
ChannelServiceApi channelServiceApi = new ChannelServiceApi(IMUrl, channelId, secret);
|
||||
|
||||
|
||||
//3. 测试channel api功能
|
||||
@@ -1410,7 +1426,20 @@ public class Main {
|
||||
payload.setType(1);
|
||||
payload.setSearchableContent("hello world");
|
||||
|
||||
IMResult<SendMessageResult> resultSendMessage = channelServiceApi.sendMessage(0, null,payload);
|
||||
IMResult<SendMessageResult> resultSendMessage = channelServiceApi.sendMessage(0, null, payload);
|
||||
if (resultSendMessage != null && resultSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("send message to all the subscriber success");
|
||||
} else {
|
||||
System.out.println("send message to all the subscriber failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
ArticleContent articleContent = new ArticleContent("article1", "https://media.wfcoss.cn/channel-assets/20220816/2dd76540daa9444dae44e942aa1c2bbc.png", "这是一个测试文章", "https://mp.weixin.qq.com/s/W6tanLbALd3qqZM8r3MTgA", true);
|
||||
articleContent.addSubArticle("article2", "https://media.wfcoss.cn/channel-assets/20220816/2dd76540daa9444dae44e942aa1c2bbc.png", "这是第二个测试文章", "https://mp.weixin.qq.com/s/W6tanLbALd3qqZM8r3MTgA", false);
|
||||
articleContent.addSubArticle("article3", "https://media.wfcoss.cn/channel-assets/20220816/2dd76540daa9444dae44e942aa1c2bbc.png", "这是第三个测试文章", "https://mp.weixin.qq.com/s/W6tanLbALd3qqZM8r3MTgA", false);
|
||||
payload = articleContent.toPayload();
|
||||
|
||||
resultSendMessage = channelServiceApi.sendMessage(0, null, payload);
|
||||
if (resultSendMessage != null && resultSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("send message to all the subscriber success");
|
||||
} else {
|
||||
@@ -1436,6 +1465,41 @@ public class Main {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
List<OutputGetChannelInfo.OutputMenu> menus = new ArrayList<>();
|
||||
OutputGetChannelInfo.OutputMenu menu1 = new OutputGetChannelInfo.OutputMenu();
|
||||
menu1.menuId = UUID.randomUUID().toString();
|
||||
menu1.type = "view";
|
||||
menu1.name = "一级菜单1";
|
||||
menu1.key = "key1";
|
||||
menu1.url = "http://www.baidu.com";
|
||||
menus.add(menu1);
|
||||
|
||||
OutputGetChannelInfo.OutputMenu menu2 = new OutputGetChannelInfo.OutputMenu();
|
||||
menu2.menuId = UUID.randomUUID().toString();
|
||||
menu2.type = "view";
|
||||
menu2.name = "一级菜单2";
|
||||
menu2.key = "key2";
|
||||
menu2.url = "http://www.sohu.com";
|
||||
menu2.subMenus = new ArrayList<>();
|
||||
menus.add(menu2);
|
||||
|
||||
OutputGetChannelInfo.OutputMenu menu21 = new OutputGetChannelInfo.OutputMenu();
|
||||
menu21.menuId = UUID.randomUUID().toString();
|
||||
menu21.type = "click";
|
||||
menu21.name = "二级菜单21";
|
||||
menu21.key = "key21";
|
||||
menu21.url = "http://www.sohu.com";
|
||||
menu2.subMenus.add(menu21);
|
||||
|
||||
String menuStr = new Gson().toJson(menus);
|
||||
voidIMResult = channelServiceApi.modifyChannelInfo(ProtoConstants.ModifyChannelInfoType.Modify_Channel_Menu, menuStr);
|
||||
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("modify channel menu success");
|
||||
} else {
|
||||
System.out.println("modify channel menu failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<OutputGetChannelInfo> outputGetChannelInfoIMResult = channelServiceApi.getChannelInfo();
|
||||
if (outputGetChannelInfoIMResult != null && outputGetChannelInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get channel info success");
|
||||
|
||||
@@ -19,6 +19,9 @@ public class MessageAdmin {
|
||||
messageData.setConv(conversation);
|
||||
messageData.setPayload(payload);
|
||||
messageData.setToUsers(toUsers);
|
||||
if (payload.getType() == 1 && (payload.getSearchableContent() == null || payload.getSearchableContent().isEmpty())) {
|
||||
System.out.println("Payload错误,Payload格式应该跟客户端消息encode出来的Payload对齐,这样客户端才能正确识别。比如文本消息,文本需要放到searchableContent属性。请与客户端同事确认Payload的格式,或则去 https://gitee.com/wfchat/android-chat/tree/master/client/src/main/java/cn/wildfirechat/message 找到消息encode的实现方法!");
|
||||
}
|
||||
return AdminHttpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
|
||||
}
|
||||
|
||||
@@ -103,4 +106,16 @@ public class MessageAdmin {
|
||||
messageData.setPayload(payload);
|
||||
return AdminHttpUtils.httpJsonPost(path, messageData, MultiMessageResult.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputTimestamp> getConversationReadTimestamp(String userId, Conversation conversation) throws Exception {
|
||||
String path = APIPath.Msg_ConvRead;
|
||||
InputGetConvReadTime input = new InputGetConvReadTime(userId, conversation.getType(), conversation.getTarget(), conversation.getLine());
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputTimestamp.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputTimestamp> getMessageDelivery(String userId) throws Exception {
|
||||
String path = APIPath.Msg_Delivery;
|
||||
InputUserId input = new InputUserId(userId);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputTimestamp.class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user