Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfcd8fc276 | ||
|
|
457f417a52 | ||
|
|
b2536992b6 | ||
|
|
c7102d5dc3 | ||
|
|
fd0ee5c674 | ||
|
|
af85b08f94 |
@@ -0,0 +1,114 @@
|
|||||||
|
import java.io.*;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 此工具为验证IM服务管理密钥是否正确的工具。
|
||||||
|
* 通过手机号查询 Wildfire IM 用户信息,如果能够返回正确信息或者未找到表示密钥正确。
|
||||||
|
*
|
||||||
|
* 编译:放到IM服务运行服务器上,执行 javac VerifyAdminSecretTool.java 编译得到 VerifyAdminSecretTool.class,
|
||||||
|
* 用法:执行 java VerifyAdminSecretTool 按提示输入 IM 服务地址、管理员密钥、电话号码。
|
||||||
|
* 程序会调用 /admin/user/get_info 接口并打印返回的 JSON。
|
||||||
|
*/
|
||||||
|
public class VerifyAdminSecretTool {
|
||||||
|
|
||||||
|
private static final SecureRandom RANDOM = new SecureRandom();
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
|
||||||
|
System.out.print("请输入 IM 服务地址(如 http://192.168.1.100:18080): ");
|
||||||
|
String serverUrl = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
System.out.print("请输入管理员密钥(admin secret): ");
|
||||||
|
String secret = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
System.out.print("请输入电话号码: ");
|
||||||
|
String mobile = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
scanner.close();
|
||||||
|
|
||||||
|
if (serverUrl.isEmpty() || secret.isEmpty() || mobile.isEmpty()) {
|
||||||
|
System.err.println("错误:服务地址、密钥和电话号码均不能为空");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建请求 URL(去掉末尾可能的 /)
|
||||||
|
if (serverUrl.endsWith("/")) {
|
||||||
|
serverUrl = serverUrl.substring(0, serverUrl.length() - 1);
|
||||||
|
}
|
||||||
|
String urlStr = serverUrl + "/admin/user/get_info";
|
||||||
|
|
||||||
|
// 构建请求体
|
||||||
|
String jsonBody = "{\"mobile\":\"" + mobile + "\",\"includeDeleted\":false}";
|
||||||
|
|
||||||
|
// 生成认证签名
|
||||||
|
int nonce = RANDOM.nextInt(1000000) + 1;
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
String signStr = nonce + "|" + secret + "|" + timestamp;
|
||||||
|
String sign = sha1Hex(signStr);
|
||||||
|
|
||||||
|
// 发送 HTTP POST 请求
|
||||||
|
String response = doPost(urlStr, jsonBody, nonce, timestamp, sign);
|
||||||
|
|
||||||
|
// 输出结果
|
||||||
|
System.out.println("\n===== 返回结果 =====");
|
||||||
|
System.out.println(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doPost(String urlStr, String body, int nonce, long timestamp, String sign) throws Exception {
|
||||||
|
URL url = new URL(urlStr);
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
try {
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
||||||
|
conn.setRequestProperty("Connection", "Keep-Alive");
|
||||||
|
conn.setRequestProperty("nonce", String.valueOf(nonce));
|
||||||
|
conn.setRequestProperty("timestamp", String.valueOf(timestamp));
|
||||||
|
conn.setRequestProperty("sign", sign);
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
conn.setConnectTimeout(15000);
|
||||||
|
conn.setReadTimeout(15000);
|
||||||
|
|
||||||
|
// 写入请求体
|
||||||
|
try (OutputStream os = conn.getOutputStream()) {
|
||||||
|
os.write(body.getBytes(StandardCharsets.UTF_8));
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
int responseCode = conn.getResponseCode();
|
||||||
|
|
||||||
|
// 读取响应
|
||||||
|
InputStream is = (responseCode >= 200 && responseCode < 300)
|
||||||
|
? conn.getInputStream()
|
||||||
|
: conn.getErrorStream();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
} finally {
|
||||||
|
conn.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String sha1Hex(String input) throws NoSuchAlgorithmException {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||||
|
byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte b : digest) {
|
||||||
|
sb.append(String.format("%02x", b & 0xff));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -180,6 +180,9 @@ robot.mention_external_robot true
|
|||||||
## 比如允许获取name和email就是5(1+4),允许获取name和mobile和company和type就是531(1+2+16+512),允许全部是1023(1+2+...+512)
|
## 比如允许获取name和email就是5(1+4),允许获取name和mobile和company和type就是531(1+2+16+512),允许全部是1023(1+2+...+512)
|
||||||
#robot.get_user_info_mask 1023
|
#robot.get_user_info_mask 1023
|
||||||
|
|
||||||
|
## 机器人应用authToken允许任意host。当为false时,机器人Web应用的host必须和机器人的callback host一致,这样能够增加安全性。
|
||||||
|
#robot.application_allow_any_host true
|
||||||
|
|
||||||
## 频道回调信息是否带上用户clientId和平台类型。
|
## 频道回调信息是否带上用户clientId和平台类型。
|
||||||
channel.callback_with_client_info false
|
channel.callback_with_client_info false
|
||||||
|
|
||||||
@@ -193,6 +196,9 @@ channel.callback_with_target_info false
|
|||||||
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
||||||
channel.new_callback_feature true
|
channel.new_callback_feature true
|
||||||
|
|
||||||
|
## 频道应用authToken允许任意host。当为false时,频道Web应用的host必须和频道的callback host一致,这样能够增加安全性。
|
||||||
|
#channel.application_allow_any_host true
|
||||||
|
|
||||||
##禁止搜索用户
|
##禁止搜索用户
|
||||||
friend.disable_search false
|
friend.disable_search false
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
<artifactId>wildfirechat-parent</artifactId>
|
<artifactId>wildfirechat-parent</artifactId>
|
||||||
<groupId>cn.wildfirechat</groupId>
|
<groupId>cn.wildfirechat</groupId>
|
||||||
<version>1.4.7</version>
|
<version>1.4.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>moquette-broker</artifactId>
|
<artifactId>moquette-broker</artifactId>
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ public class UploadFileAction extends Action {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getToken(int type) {
|
public static String getToken(int type, String key) {
|
||||||
String signKey = KEY + "|" + (System.currentTimeMillis()) + "|" + type;
|
String signKey = KEY + "|" + (System.currentTimeMillis()) + "|" + type + "|" + key;
|
||||||
try {
|
try {
|
||||||
return DES.encryptDES(signKey);
|
return DES.encryptDES(signKey);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -55,14 +55,17 @@ public class UploadFileAction extends Action {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int validateToken(String token) throws InvalidateTokenExecption {
|
public static int validateToken(String token, String[] fileNames) throws InvalidateTokenExecption {
|
||||||
try {
|
try {
|
||||||
String signKey = DES.decryptDES(token);
|
String signKey = DES.decryptDES(token);
|
||||||
String[] parts = signKey.split("\\|");
|
String[] parts = signKey.split("\\|");
|
||||||
if(parts.length == 3) {
|
if(parts.length >= 3) {
|
||||||
if(parts[0].equals(KEY)) {
|
if(parts[0].equals(KEY)) {
|
||||||
long timestamp = Long.parseLong(parts[1]);
|
long timestamp = Long.parseLong(parts[1]);
|
||||||
if(Math.abs(System.currentTimeMillis() - timestamp) < 2 * 60 * 60 * 1000) {
|
if(Math.abs(System.currentTimeMillis() - timestamp) < 2 * 60 * 60 * 1000) {
|
||||||
|
if(parts.length == 4) {
|
||||||
|
fileNames[0] = parts[3];
|
||||||
|
}
|
||||||
return Integer.parseInt(parts[2]);
|
return Integer.parseInt(parts[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,11 +156,14 @@ public class UploadFileAction extends Action {
|
|||||||
try {
|
try {
|
||||||
int[] bucket = new int[1];
|
int[] bucket = new int[1];
|
||||||
bucket[0] = -1;
|
bucket[0] = -1;
|
||||||
|
String[] fileNames = new String[1];
|
||||||
|
fileNames[0] = null;
|
||||||
|
|
||||||
while (decoder.hasNext()) {
|
while (decoder.hasNext()) {
|
||||||
InterfaceHttpData data = decoder.next();
|
InterfaceHttpData data = decoder.next();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
try {
|
try {
|
||||||
if(!writeFileUploadData(data, response, requestId, isKeepAlive, bucket)) {
|
if(!writeFileUploadData(data, response, requestId, isKeepAlive, bucket, fileNames)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -173,12 +179,15 @@ public class UploadFileAction extends Action {
|
|||||||
/**
|
/**
|
||||||
* writeFileUploadData
|
* writeFileUploadData
|
||||||
*/
|
*/
|
||||||
private boolean writeFileUploadData(InterfaceHttpData data, Response response, String requestId, boolean isKeepAlive, int[] bucket) {
|
private boolean writeFileUploadData(InterfaceHttpData data, Response response, String requestId, boolean isKeepAlive, int[] bucket, String[] fileNames) {
|
||||||
try {
|
try {
|
||||||
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
|
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
|
||||||
FileUpload fileUpload = (FileUpload) data;
|
FileUpload fileUpload = (FileUpload) data;
|
||||||
|
|
||||||
String remoteFileName = fileUpload.getFilename();
|
String remoteFileName = fileUpload.getFilename();
|
||||||
|
if(fileNames[0] != null) {
|
||||||
|
remoteFileName = fileNames[0];
|
||||||
|
}
|
||||||
long remoteFileSize = fileUpload.length();
|
long remoteFileSize = fileUpload.length();
|
||||||
|
|
||||||
if(bucket[0] == -1) {
|
if(bucket[0] == -1) {
|
||||||
@@ -323,7 +332,7 @@ public class UploadFileAction extends Action {
|
|||||||
String token = attribute.getValue();
|
String token = attribute.getValue();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bucket[0] = validateToken(token);
|
bucket[0] = validateToken(token, fileNames);
|
||||||
} catch (InvalidateTokenExecption e) {
|
} catch (InvalidateTokenExecption e) {
|
||||||
logger.error("无效的token!", e);
|
logger.error("无效的token!", e);
|
||||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||||
|
|||||||
@@ -186,12 +186,13 @@ public final class BrokerConstants {
|
|||||||
public static final String ROBOT_Callback_With_Target_Info = "robot.callback_with_target_info";
|
public static final String ROBOT_Callback_With_Target_Info = "robot.callback_with_target_info";
|
||||||
public static final String ROBOT_Mention_External_Robot = "robot.mention_external_robot";
|
public static final String ROBOT_Mention_External_Robot = "robot.mention_external_robot";
|
||||||
public static final String ROBOT_Get_User_Info_Mask = "robot.get_user_info_mask";
|
public static final String ROBOT_Get_User_Info_Mask = "robot.get_user_info_mask";
|
||||||
|
public static final String ROBOT_App_Allow_Any_Host = "robot.application_allow_any_host";
|
||||||
|
|
||||||
public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_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_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_Callback_With_Target_Info = "channel.callback_with_target_info";
|
||||||
public static final String CHANNEL_New_Callback_Feature = "channel.new_callback_feature";
|
public static final String CHANNEL_New_Callback_Feature = "channel.new_callback_feature";
|
||||||
|
public static final String CHANNEL_App_Allow_Any_Host = "channel.application_allow_any_host";
|
||||||
|
|
||||||
public static final String FRIEND_Disable_Search = "friend.disable_search";
|
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_NickName_Search = "friend.disable_nick_name_search";
|
||||||
|
|||||||
@@ -18,16 +18,28 @@ import io.moquette.server.config.MediaServerConfig;
|
|||||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
import static io.moquette.server.config.MediaServerConfig.FILE_STROAGE_REMOTE_SERVER_URL;
|
import static io.moquette.server.config.MediaServerConfig.FILE_STROAGE_REMOTE_SERVER_URL;
|
||||||
|
|
||||||
@Handler("GMUT")
|
@Handler("GMUT")
|
||||||
public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTokenRequest> {
|
public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTokenRequest> {
|
||||||
@Override
|
@Override
|
||||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.GetUploadTokenRequest request, Qos1PublishHandler.IMCallback callback) {
|
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.GetUploadTokenRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||||
|
String fileKey = request.getMediaPath();
|
||||||
|
if(fileKey.contains("/")) {
|
||||||
|
fileKey = fileKey.substring(fileKey.lastIndexOf("/")+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String encodedUserId = Base64.getEncoder().encodeToString(fromUser.getBytes(StandardCharsets.UTF_8)).replace("+", "-2B").replace("/", "-2F").replace("=", "-3D");
|
||||||
|
if(!fileKey.startsWith(fromUser) && !fileKey.startsWith(encodedUserId)) {
|
||||||
|
LOG.error("GetMediaUploadTokenHandler error: {}, {}", fromUser, request.getMediaPath());
|
||||||
|
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
int type = request.getMediaType();
|
int type = request.getMediaType();
|
||||||
|
|
||||||
String token;
|
String token;
|
||||||
|
|
||||||
WFCMessage.GetUploadTokenResult.Builder resultBuilder = WFCMessage.GetUploadTokenResult.newBuilder();
|
WFCMessage.GetUploadTokenResult.Builder resultBuilder = WFCMessage.GetUploadTokenResult.newBuilder();
|
||||||
if (MediaServerConfig.USER_QINIU) {
|
if (MediaServerConfig.USER_QINIU) {
|
||||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||||
@@ -93,12 +105,12 @@ public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTo
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
token = auth.uploadToken(bucketName);
|
token = auth.uploadToken(bucketName, request.getMediaPath());
|
||||||
resultBuilder.setDomain(bucketDomain)
|
resultBuilder.setDomain(bucketDomain)
|
||||||
.setServer(MediaServerConfig.QINIU_SERVER_URL);
|
.setServer(MediaServerConfig.QINIU_SERVER_URL);
|
||||||
resultBuilder.setPort(80);
|
resultBuilder.setPort(80);
|
||||||
} else {
|
} else {
|
||||||
token = UploadFileAction.getToken(type);
|
token = UploadFileAction.getToken(type, request.getMediaPath());
|
||||||
if(StringUtil.isNullOrEmpty(MediaServerConfig.FILE_STROAGE_REMOTE_SERVER_URL)) {
|
if(StringUtil.isNullOrEmpty(MediaServerConfig.FILE_STROAGE_REMOTE_SERVER_URL)) {
|
||||||
resultBuilder.setDomain("http://" + MediaServerConfig.SERVER_IP + ":" + MediaServerConfig.HTTP_SERVER_PORT);
|
resultBuilder.setDomain("http://" + MediaServerConfig.SERVER_IP + ":" + MediaServerConfig.HTTP_SERVER_PORT);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class GetQiniuUploadTokenHandler extends IMHandler<Byte> {
|
|||||||
.setServer(MediaServerConfig.QINIU_SERVER_URL);
|
.setServer(MediaServerConfig.QINIU_SERVER_URL);
|
||||||
resultBuilder.setPort(80);
|
resultBuilder.setPort(80);
|
||||||
} else {
|
} else {
|
||||||
token = UploadFileAction.getToken(type);
|
token = UploadFileAction.getToken(type, null);
|
||||||
resultBuilder.setDomain("http://" + MediaServerConfig.SERVER_IP + ":" + MediaServerConfig.HTTP_SERVER_PORT)
|
resultBuilder.setDomain("http://" + MediaServerConfig.SERVER_IP + ":" + MediaServerConfig.HTTP_SERVER_PORT)
|
||||||
.setServer(MediaServerConfig.SERVER_IP);
|
.setServer(MediaServerConfig.SERVER_IP);
|
||||||
resultBuilder.setPort(MediaServerConfig.HTTP_SERVER_PORT);
|
resultBuilder.setPort(MediaServerConfig.HTTP_SERVER_PORT);
|
||||||
|
|||||||
@@ -4297,9 +4297,13 @@ public class DatabaseStore {
|
|||||||
String sql = "select _cid, _name" +
|
String sql = "select _cid, _name" +
|
||||||
", _portrait" +
|
", _portrait" +
|
||||||
", _owner" +
|
", _owner" +
|
||||||
|
", _secret" +
|
||||||
", _status" +
|
", _status" +
|
||||||
", _desc" +
|
", _desc" +
|
||||||
", _extra" +
|
", _extra" +
|
||||||
|
", _callback" +
|
||||||
|
", _automatic" +
|
||||||
|
", _menu" +
|
||||||
", _dt from t_channel";
|
", _dt from t_channel";
|
||||||
if(!withDeleted) {
|
if(!withDeleted) {
|
||||||
sql += " where _status <> 64 ";
|
sql += " where _status <> 64 ";
|
||||||
@@ -4334,6 +4338,10 @@ public class DatabaseStore {
|
|||||||
value = (value == null ? "" : value);
|
value = (value == null ? "" : value);
|
||||||
builder.setOwner(value);
|
builder.setOwner(value);
|
||||||
|
|
||||||
|
value = rs.getString(index++);
|
||||||
|
value = (value == null ? "" : value);
|
||||||
|
builder.setSecret(value);
|
||||||
|
|
||||||
int status = rs.getInt(index++);
|
int status = rs.getInt(index++);
|
||||||
builder.setStatus(status);
|
builder.setStatus(status);
|
||||||
|
|
||||||
@@ -4345,6 +4353,32 @@ public class DatabaseStore {
|
|||||||
value = (value == null ? "" : value);
|
value = (value == null ? "" : value);
|
||||||
builder.setExtra(value);
|
builder.setExtra(value);
|
||||||
|
|
||||||
|
value = rs.getString(index++);
|
||||||
|
value = (value == null ? "" : value);
|
||||||
|
builder.setCallback(value);
|
||||||
|
|
||||||
|
int intValue = rs.getInt(index++);
|
||||||
|
builder.setAutomatic(intValue);
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] bytes = null;
|
||||||
|
Blob blob = rs.getBlob(index++);
|
||||||
|
if (blob != null) {
|
||||||
|
bytes = toByteArray(blob.getBinaryStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes != null) {
|
||||||
|
WFCMessage.ChannelMenuList menuButtonList = WFCMessage.ChannelMenuList.parseFrom(bytes);
|
||||||
|
if (menuButtonList.getMenuCount() > 0) {
|
||||||
|
for (int i = 0; i < menuButtonList.getMenuCount(); i++) {
|
||||||
|
builder.addMenu(menuButtonList.getMenu(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
long longValue = rs.getLong(index++);
|
long longValue = rs.getLong(index++);
|
||||||
builder.setUpdateDt(longValue);
|
builder.setUpdateDt(longValue);
|
||||||
|
|
||||||
|
|||||||
@@ -224,11 +224,13 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
private boolean mRobotCallbackWithTargetInfo = false;
|
private boolean mRobotCallbackWithTargetInfo = false;
|
||||||
private boolean mRobotMentionExternalRobot = false;
|
private boolean mRobotMentionExternalRobot = false;
|
||||||
private int mRobotGetUserInfoMask = 0;
|
private int mRobotGetUserInfoMask = 0;
|
||||||
|
private boolean mRobotAppAllowAnyHost = false;
|
||||||
|
|
||||||
private boolean mChannelCallbackWithClientInfo = false;
|
private boolean mChannelCallbackWithClientInfo = false;
|
||||||
private boolean mChannelCallbackWithSenderInfo = false;
|
private boolean mChannelCallbackWithSenderInfo = false;
|
||||||
private boolean mChannelCallbackWithTargetInfo = false;
|
private boolean mChannelCallbackWithTargetInfo = false;
|
||||||
private boolean mChannelNewCallbackFeature = true;
|
private boolean mChannelNewCallbackFeature = true;
|
||||||
|
private boolean mChannelAppAllowAnyHost = false;
|
||||||
|
|
||||||
private Set<Integer> mUserHideProperties = new HashSet<>();
|
private Set<Integer> mUserHideProperties = new HashSet<>();
|
||||||
|
|
||||||
@@ -689,6 +691,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
try {
|
try {
|
||||||
mRobotGetUserInfoMask = Integer.parseInt(server.getConfig().getProperty(BrokerConstants.ROBOT_Get_User_Info_Mask, "0"));
|
mRobotGetUserInfoMask = Integer.parseInt(server.getConfig().getProperty(BrokerConstants.ROBOT_Get_User_Info_Mask, "0"));
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
|
try {
|
||||||
|
mRobotAppAllowAnyHost = "true".equalsIgnoreCase(server.getConfig().getProperty(BrokerConstants.ROBOT_App_Allow_Any_Host, "false"));
|
||||||
|
} catch (Exception e) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
|
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
|
||||||
@@ -699,10 +704,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
try {
|
try {
|
||||||
mChannelCallbackWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Target_Info, "false"));
|
mChannelCallbackWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Target_Info, "false"));
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mChannelNewCallbackFeature = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_New_Callback_Feature, "true"));
|
mChannelNewCallbackFeature = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_New_Callback_Feature, "true"));
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
|
try {
|
||||||
|
mChannelAppAllowAnyHost = "true".equalsIgnoreCase(server.getConfig().getProperty(BrokerConstants.CHANNEL_App_Allow_Any_Host, "false"));
|
||||||
|
} catch (Exception e) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url);
|
mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url);
|
||||||
@@ -4216,12 +4223,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
String secret = null;
|
String secret = null;
|
||||||
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
||||||
WFCMessage.Robot robotData = getRobot(applicationId);
|
WFCMessage.Robot robotData = getRobot(applicationId);
|
||||||
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
if(robotData != null && (mRobotAppAllowAnyHost || !StringUtil.isNullOrEmpty(robotData.getCallback())) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(robotData.getCallback());
|
URL url = new URL(robotData.getCallback());
|
||||||
if(url.getHost() == null) {
|
if(url.getHost() == null) {
|
||||||
LOG.error("get application auth code error, application callback is invalid url");
|
LOG.error("get application auth code error, application callback is invalid url");
|
||||||
} else if(url.getHost().equals(host)) {
|
} else if(mRobotAppAllowAnyHost || url.getHost().equals(host)) {
|
||||||
secret = robotData.getSecret();
|
secret = robotData.getSecret();
|
||||||
} else {
|
} else {
|
||||||
LOG.error("get application auth code error, request host is not the same host with callback host");
|
LOG.error("get application auth code error, request host is not the same host with callback host");
|
||||||
@@ -4242,12 +4249,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
||||||
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
|
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
|
||||||
if(channelData != null && !StringUtil.isNullOrEmpty(channelData.getCallback()) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
if(channelData != null && (mChannelAppAllowAnyHost || !StringUtil.isNullOrEmpty(channelData.getCallback())) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(channelData.getCallback());
|
URL url = new URL(channelData.getCallback());
|
||||||
if(url.getHost() == null) {
|
if(url.getHost() == null) {
|
||||||
LOG.error("get application auth code error, application callback is invalid url");
|
LOG.error("get application auth code error, application callback is invalid url");
|
||||||
} else if(url.getHost().equals(host)) {
|
} else if(mChannelAppAllowAnyHost || url.getHost().equals(host)) {
|
||||||
secret = channelData.getSecret();
|
secret = channelData.getSecret();
|
||||||
} else {
|
} else {
|
||||||
LOG.error("get application auth code error, request host is not the same host with callback host");
|
LOG.error("get application auth code error, request host is not the same host with callback host");
|
||||||
@@ -4285,12 +4292,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
String secret = null;
|
String secret = null;
|
||||||
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
||||||
WFCMessage.Robot robotData = getRobot(applicationId);
|
WFCMessage.Robot robotData = getRobot(applicationId);
|
||||||
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
if(robotData != null && (mRobotAppAllowAnyHost || !StringUtil.isNullOrEmpty(robotData.getCallback())) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||||
secret = robotData.getSecret();
|
secret = robotData.getSecret();
|
||||||
}
|
}
|
||||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
||||||
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
|
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
|
||||||
if(channelData != null && !StringUtil.isNullOrEmpty(channelData.getCallback()) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
if(channelData != null && (mChannelAppAllowAnyHost || !StringUtil.isNullOrEmpty(channelData.getCallback())) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
||||||
secret = channelData.getSecret();
|
secret = channelData.getSecret();
|
||||||
}
|
}
|
||||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Admin) {
|
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Admin) {
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>wildfirechat-parent</artifactId>
|
<artifactId>wildfirechat-parent</artifactId>
|
||||||
<groupId>cn.wildfirechat</groupId>
|
<groupId>cn.wildfirechat</groupId>
|
||||||
<version>1.4.7</version>
|
<version>1.4.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public interface APIPath {
|
|||||||
String User_Online_Count = "/admin/user/online_count";
|
String User_Online_Count = "/admin/user/online_count";
|
||||||
String User_Online_List = "/admin/user/online_list";
|
String User_Online_List = "/admin/user/online_list";
|
||||||
String User_Session_List = "/admin/user/session_list";
|
String User_Session_List = "/admin/user/session_list";
|
||||||
|
String User_Unread_count = "/admin/user/unread_count";
|
||||||
String User_Application_Get_UserInfo = "/admin/user/app_get_user_info";
|
String User_Application_Get_UserInfo = "/admin/user/app_get_user_info";
|
||||||
|
|
||||||
String Friend_Update_Status = "/admin/friend/status";
|
String Friend_Update_Status = "/admin/friend/status";
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package cn.wildfirechat.pojos;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OutputUserUnreadCount {
|
||||||
|
public int unreceivedMessageCount;
|
||||||
|
public int uploadedUnreadCount;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -107,6 +107,8 @@ public class ProtoConstants {
|
|||||||
int StreamingText_Generationg = 14;
|
int StreamingText_Generationg = 14;
|
||||||
int StreamingText_Generated = 15;
|
int StreamingText_Generated = 15;
|
||||||
int Not_Delivered = 16;
|
int Not_Delivered = 16;
|
||||||
|
int Meeting_Minutes = 25;
|
||||||
|
int Transcription = 26;
|
||||||
int Ptt_Voice = 23;
|
int Ptt_Voice = 23;
|
||||||
int Enter_Channel_Chat = 71;
|
int Enter_Channel_Chat = 71;
|
||||||
int Leave_Channel_Chat = 72;
|
int Leave_Channel_Chat = 72;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<!--<relativePath>../pom.xml</relativePath>-->
|
<!--<relativePath>../pom.xml</relativePath>-->
|
||||||
<artifactId>wildfirechat-parent</artifactId>
|
<artifactId>wildfirechat-parent</artifactId>
|
||||||
<groupId>cn.wildfirechat</groupId>
|
<groupId>cn.wildfirechat</groupId>
|
||||||
<version>1.4.7</version>
|
<version>1.4.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>distribution</artifactId>
|
<artifactId>distribution</artifactId>
|
||||||
|
|||||||
@@ -177,6 +177,9 @@ robot.mention_external_robot true
|
|||||||
## 比如允许获取name和email就是5(1+4),允许获取name和mobile和company和type就是531(1+2+16+512),允许全部是1023(1+2+...+512)
|
## 比如允许获取name和email就是5(1+4),允许获取name和mobile和company和type就是531(1+2+16+512),允许全部是1023(1+2+...+512)
|
||||||
#robot.get_user_info_mask 1023
|
#robot.get_user_info_mask 1023
|
||||||
|
|
||||||
|
## 机器人应用authToken允许任意host。当为false时,机器人Web应用的host必须和机器人的callback host一致,这样能够增加安全性。
|
||||||
|
#robot.application_allow_any_host true
|
||||||
|
|
||||||
## 频道回调信息是否带上用户clientId和平台类型。
|
## 频道回调信息是否带上用户clientId和平台类型。
|
||||||
channel.callback_with_client_info false
|
channel.callback_with_client_info false
|
||||||
|
|
||||||
@@ -190,6 +193,9 @@ channel.callback_with_target_info false
|
|||||||
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
||||||
channel.new_callback_feature true
|
channel.new_callback_feature true
|
||||||
|
|
||||||
|
## 频道应用authToken允许任意host。当为false时,频道Web应用的host必须和频道的callback host一致,这样能够增加安全性。
|
||||||
|
#channel.application_allow_any_host true
|
||||||
|
|
||||||
##禁止搜索用户
|
##禁止搜索用户
|
||||||
friend.disable_search false
|
friend.disable_search false
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<artifactId>wildfirechat-parent</artifactId>
|
<artifactId>wildfirechat-parent</artifactId>
|
||||||
|
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.4.7</version>
|
<version>1.4.8</version>
|
||||||
<name>Wildfire Chat</name>
|
<name>Wildfire Chat</name>
|
||||||
<description>Wildfire Chat Server</description>
|
<description>Wildfire Chat Server</description>
|
||||||
<inceptionYear>2019</inceptionYear>
|
<inceptionYear>2019</inceptionYear>
|
||||||
|
|||||||
@@ -13,6 +13,13 @@
|
|||||||
|
|
||||||
# 更新记录
|
# 更新记录
|
||||||
--------------
|
--------------
|
||||||
|
Release note 1.4.8:
|
||||||
|
1. 添加配置支持机器人和频道应用不校验host。
|
||||||
|
2. 解决server api获取频道列表缺少字段。
|
||||||
|
3. 优化文件上传认证的问题。
|
||||||
|
4. 同步专业版IM服务SDK添加获取未读数接口。
|
||||||
|
|
||||||
|
|
||||||
Release note 1.4.7:
|
Release note 1.4.7:
|
||||||
1. 添加获取所有机器人的Server API接口。
|
1. 添加获取所有机器人的Server API接口。
|
||||||
2. 添加获取某个电话号码的用户列表的Server API接口。
|
2. 添加获取某个电话号码的用户列表的Server API接口。
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>wildfirechat-parent</artifactId>
|
<artifactId>wildfirechat-parent</artifactId>
|
||||||
<groupId>cn.wildfirechat</groupId>
|
<groupId>cn.wildfirechat</groupId>
|
||||||
<version>1.4.7</version>
|
<version>1.4.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -485,6 +485,15 @@ public class Main {
|
|||||||
|
|
||||||
// 商业版专属功能
|
// 商业版专属功能
|
||||||
if (commercialServer) {
|
if (commercialServer) {
|
||||||
|
// 获取用户的未读情况
|
||||||
|
IMResult<OutputUserUnreadCount> userUnreadCountIMResult = UserAdmin.getUserUnreadCount("user1");
|
||||||
|
if (userUnreadCountIMResult != null && userUnreadCountIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||||
|
System.out.println("get user unread count success");
|
||||||
|
} else {
|
||||||
|
System.out.println("get user unread count failure");
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
// 获取在线用户总数
|
// 获取在线用户总数
|
||||||
IMResult<GetOnlineUserCountResult> getOnlineUserCountResultIMResult = UserAdmin.getOnlineUserCount();
|
IMResult<GetOnlineUserCountResult> getOnlineUserCountResultIMResult = UserAdmin.getOnlineUserCount();
|
||||||
if (getOnlineUserCountResultIMResult != null && getOnlineUserCountResultIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
if (getOnlineUserCountResultIMResult != null && getOnlineUserCountResultIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||||
|
|||||||
@@ -414,4 +414,15 @@ public class UserAdmin {
|
|||||||
InputUserId inputUserId = new InputUserId(userId);
|
InputUserId inputUserId = new InputUserId(userId);
|
||||||
return AdminHttpUtils.httpJsonPost(APIPath.User_Session_List, inputUserId, GetUserSessionResult.class);
|
return AdminHttpUtils.httpJsonPost(APIPath.User_Session_List, inputUserId, GetUserSessionResult.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户的未读数,只有专业版IM服务支持,未读数不是很准确,只能表示一个大概。
|
||||||
|
* @param userId
|
||||||
|
* @return 用户的未读数,包括未接收消息和客户端上报的未读数。
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static IMResult<OutputUserUnreadCount> getUserUnreadCount(String userId) throws Exception {
|
||||||
|
InputUserId inputUserId = new InputUserId(userId);
|
||||||
|
return AdminHttpUtils.httpJsonPost(APIPath.User_Unread_count, inputUserId, OutputUserUnreadCount.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会议纪要消息内容类
|
||||||
|
* <p>
|
||||||
|
* 表示会议纪要类型的消息内容,包含纪要文本、会议标题和会议ID。
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class MeetingMinutesMessageContent extends MessageContent {
|
||||||
|
private String text;
|
||||||
|
private String title;
|
||||||
|
private String meetingId;
|
||||||
|
|
||||||
|
//必须有个空的构造函数
|
||||||
|
public MeetingMinutesMessageContent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MeetingMinutesMessageContent(String text, String title, String meetingId) {
|
||||||
|
this.text = text;
|
||||||
|
this.title = title;
|
||||||
|
this.meetingId = meetingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMeetingId() {
|
||||||
|
return meetingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMeetingId(String meetingId) {
|
||||||
|
this.meetingId = meetingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentType() {
|
||||||
|
return ProtoConstants.ContentType.Meeting_Minutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPersistFlag() {
|
||||||
|
return ProtoConstants.PersistFlag.Persist_And_Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessagePayload encode() {
|
||||||
|
MessagePayload payload = super.encode();
|
||||||
|
payload.setContent(text);
|
||||||
|
payload.setSearchableContent(title);
|
||||||
|
if (!TextUtils.isEmpty(meetingId)) {
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("meetingId", meetingId);
|
||||||
|
payload.setBase64edData(Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8)));
|
||||||
|
}
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(MessagePayload payload) {
|
||||||
|
super.decode(payload);
|
||||||
|
text = payload.getContent();
|
||||||
|
title = payload.getSearchableContent();
|
||||||
|
if (!TextUtils.isEmpty(payload.getBase64edData())) {
|
||||||
|
String jsonStr = new String(Base64.getDecoder().decode(payload.getBase64edData()), StandardCharsets.UTF_8);
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = (JSONObject) new JSONParser().parse(jsonStr);
|
||||||
|
meetingId = (String) jsonObject.get("meetingId");
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,8 @@ public class MessageContentFactory {
|
|||||||
private static final Map<Integer, Class<? extends MessageContent>> contentClassMap = new ConcurrentHashMap<>();
|
private static final Map<Integer, Class<? extends MessageContent>> contentClassMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private static List<Class> buildinMessageContents = Arrays.asList(
|
private static List<Class> buildinMessageContents = Arrays.asList(
|
||||||
|
MeetingMinutesMessageContent.class,
|
||||||
|
TranscriptionMessageContent.class,
|
||||||
ArticlesMessageContent.class,
|
ArticlesMessageContent.class,
|
||||||
StreamTextGeneratedMessageContent.class,
|
StreamTextGeneratedMessageContent.class,
|
||||||
CallStartMessageContent.class,
|
CallStartMessageContent.class,
|
||||||
|
|||||||
+144
@@ -0,0 +1,144 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换消息内容类(透传消息)
|
||||||
|
* <p>
|
||||||
|
* 表示转换类型的透传消息,包含id、会议id、用户id、时间戳、时长和内容。
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class TranscriptionMessageContent extends MessageContent {
|
||||||
|
private long transcriptionId;
|
||||||
|
private String meetingId;
|
||||||
|
private String userId;
|
||||||
|
private long timestamp;
|
||||||
|
private long duration;
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
//必须有个空的构造函数
|
||||||
|
public TranscriptionMessageContent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranscriptionMessageContent(long transcriptionId, String meetingId, String userId, long timestamp, long duration, String content) {
|
||||||
|
this.transcriptionId = transcriptionId;
|
||||||
|
this.meetingId = meetingId;
|
||||||
|
this.userId = userId;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.duration = duration;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTranscriptionId() {
|
||||||
|
return transcriptionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTranscriptionId(long transcriptionId) {
|
||||||
|
this.transcriptionId = transcriptionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMeetingId() {
|
||||||
|
return meetingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMeetingId(String meetingId) {
|
||||||
|
this.meetingId = meetingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(String userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDuration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuration(long duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentType() {
|
||||||
|
return ProtoConstants.ContentType.Transcription;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPersistFlag() {
|
||||||
|
return ProtoConstants.PersistFlag.Transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessagePayload encode() {
|
||||||
|
MessagePayload payload = super.encode();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
if (transcriptionId > 0) {
|
||||||
|
jsonObject.put("id", transcriptionId);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(meetingId)) {
|
||||||
|
jsonObject.put("meetingId", meetingId);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(userId)) {
|
||||||
|
jsonObject.put("userId", userId);
|
||||||
|
}
|
||||||
|
if (timestamp > 0) {
|
||||||
|
jsonObject.put("timestamp", timestamp);
|
||||||
|
}
|
||||||
|
if (duration > 0) {
|
||||||
|
jsonObject.put("duration", duration);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(content)) {
|
||||||
|
jsonObject.put("content", content);
|
||||||
|
}
|
||||||
|
payload.setContent(jsonObject.toJSONString());
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(MessagePayload payload) {
|
||||||
|
super.decode(payload);
|
||||||
|
if (!TextUtils.isEmpty(payload.getContent())) {
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = (JSONObject) new JSONParser().parse(payload.getContent());
|
||||||
|
transcriptionId = ((Number) jsonObject.get("id")).longValue();
|
||||||
|
meetingId = (String) jsonObject.get("meetingId");
|
||||||
|
userId = (String) jsonObject.get("userId");
|
||||||
|
Object ts = jsonObject.get("timestamp");
|
||||||
|
if (ts != null) {
|
||||||
|
timestamp = ((Number) ts).longValue();
|
||||||
|
}
|
||||||
|
Object dur = jsonObject.get("duration");
|
||||||
|
if (dur != null) {
|
||||||
|
duration = ((Number) dur).longValue();
|
||||||
|
}
|
||||||
|
content = (String) jsonObject.get("content");
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user