Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfcd8fc276 | ||
|
|
457f417a52 | ||
|
|
b2536992b6 | ||
|
|
c7102d5dc3 | ||
|
|
fd0ee5c674 | ||
|
|
af85b08f94 | ||
|
|
de89b44b21 | ||
|
|
44b18a66c0 | ||
|
|
42281c3ad3 |
@@ -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)
|
||||
#robot.get_user_info_mask 1023
|
||||
|
||||
## 机器人应用authToken允许任意host。当为false时,机器人Web应用的host必须和机器人的callback host一致,这样能够增加安全性。
|
||||
#robot.application_allow_any_host true
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
@@ -193,6 +196,9 @@ channel.callback_with_target_info false
|
||||
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
||||
channel.new_callback_feature true
|
||||
|
||||
## 频道应用authToken允许任意host。当为false时,频道Web应用的host必须和频道的callback host一致,这样能够增加安全性。
|
||||
#channel.application_allow_any_host true
|
||||
|
||||
##禁止搜索用户
|
||||
friend.disable_search false
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.6</version>
|
||||
<version>1.4.8</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
|
||||
@@ -44,8 +44,8 @@ public class UploadFileAction extends Action {
|
||||
|
||||
}
|
||||
|
||||
public static String getToken(int type) {
|
||||
String signKey = KEY + "|" + (System.currentTimeMillis()) + "|" + type;
|
||||
public static String getToken(int type, String key) {
|
||||
String signKey = KEY + "|" + (System.currentTimeMillis()) + "|" + type + "|" + key;
|
||||
try {
|
||||
return DES.encryptDES(signKey);
|
||||
} catch (Exception e) {
|
||||
@@ -55,14 +55,17 @@ public class UploadFileAction extends Action {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int validateToken(String token) throws InvalidateTokenExecption {
|
||||
public static int validateToken(String token, String[] fileNames) throws InvalidateTokenExecption {
|
||||
try {
|
||||
String signKey = DES.decryptDES(token);
|
||||
String[] parts = signKey.split("\\|");
|
||||
if(parts.length == 3) {
|
||||
if(parts.length >= 3) {
|
||||
if(parts[0].equals(KEY)) {
|
||||
long timestamp = Long.parseLong(parts[1]);
|
||||
if(Math.abs(System.currentTimeMillis() - timestamp) < 2 * 60 * 60 * 1000) {
|
||||
if(parts.length == 4) {
|
||||
fileNames[0] = parts[3];
|
||||
}
|
||||
return Integer.parseInt(parts[2]);
|
||||
}
|
||||
}
|
||||
@@ -153,11 +156,14 @@ public class UploadFileAction extends Action {
|
||||
try {
|
||||
int[] bucket = new int[1];
|
||||
bucket[0] = -1;
|
||||
String[] fileNames = new String[1];
|
||||
fileNames[0] = null;
|
||||
|
||||
while (decoder.hasNext()) {
|
||||
InterfaceHttpData data = decoder.next();
|
||||
if (data != null) {
|
||||
try {
|
||||
if(!writeFileUploadData(data, response, requestId, isKeepAlive, bucket)) {
|
||||
if(!writeFileUploadData(data, response, requestId, isKeepAlive, bucket, fileNames)) {
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
@@ -173,12 +179,15 @@ public class UploadFileAction extends Action {
|
||||
/**
|
||||
* 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 {
|
||||
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
|
||||
FileUpload fileUpload = (FileUpload) data;
|
||||
|
||||
String remoteFileName = fileUpload.getFilename();
|
||||
if(fileNames[0] != null) {
|
||||
remoteFileName = fileNames[0];
|
||||
}
|
||||
long remoteFileSize = fileUpload.length();
|
||||
|
||||
if(bucket[0] == -1) {
|
||||
@@ -323,7 +332,7 @@ public class UploadFileAction extends Action {
|
||||
String token = attribute.getValue();
|
||||
|
||||
try {
|
||||
bucket[0] = validateToken(token);
|
||||
bucket[0] = validateToken(token, fileNames);
|
||||
} catch (InvalidateTokenExecption e) {
|
||||
logger.error("无效的token!", e);
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputSubscribeChannelBatch;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
|
||||
@Route(APIPath.Batch_Subscribe_Channel)
|
||||
@HttpMethod("POST")
|
||||
public class ChannelSubscriberBatchAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputSubscribeChannelBatch input = getRequestBody(request.getNettyRequest(), InputSubscribeChannelBatch.class);
|
||||
if (input != null && !StringUtil.isNullOrEmpty(input.getChannelId()) && input.getUserIds() != null && !input.getUserIds().isEmpty() ) {
|
||||
ErrorCode errorCode = messagesStore.batchListenChannel(input.getChannelId(), input.getUserIds(), input.getSubscribe()>0);
|
||||
sendResponse(response, errorCode, null);
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.PojoGroupInfo;
|
||||
import cn.wildfirechat.pojos.PojoGroupInfoList;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.Group_Batch_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetBatchGroupInfoAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
List<String> inputGetGroup = getRequestBody(request.getNettyRequest(), ArrayList.class);
|
||||
if (inputGetGroup != null && !inputGetGroup.isEmpty()) {
|
||||
List<WFCMessage.UserRequest> requests = new ArrayList<>();
|
||||
for (String s : inputGetGroup) {
|
||||
requests.add(WFCMessage.UserRequest.newBuilder().setUid(s).build());
|
||||
}
|
||||
List<WFCMessage.GroupInfo> groupInfoDataList = messagesStore.getGroupInfos(requests);
|
||||
PojoGroupInfoList pojoGroupInfoList = new PojoGroupInfoList();
|
||||
pojoGroupInfoList.groupInfoList = new ArrayList<>();
|
||||
|
||||
for (WFCMessage.GroupInfo groupInfo : groupInfoDataList) {
|
||||
pojoGroupInfoList.groupInfoList.add(PojoGroupInfo.fromProto(groupInfo));
|
||||
}
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok(pojoGroupInfoList);
|
||||
response.setContent(gson.toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputCountOffset;
|
||||
import cn.wildfirechat.pojos.OutputChannelInfoList;
|
||||
import cn.wildfirechat.pojos.OutputGetChannelInfo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.List_Channel_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetChannelListAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputCountOffset inputCreateChannel = getRequestBody(request.getNettyRequest(), InputCountOffset.class);
|
||||
if (inputCreateChannel != null
|
||||
&& inputCreateChannel.count > 0 && inputCreateChannel.offset >= 0) {
|
||||
int count = messagesStore.getChannelTotalCount(false);
|
||||
List<WFCMessage.ChannelInfo> list = messagesStore.getChannelInfoList(inputCreateChannel.count, inputCreateChannel.offset, false);
|
||||
OutputChannelInfoList outputChannelInfoList = new OutputChannelInfoList();
|
||||
outputChannelInfoList.total = count;
|
||||
outputChannelInfoList.list = new ArrayList<>();
|
||||
for (WFCMessage.ChannelInfo channelData : list) {
|
||||
outputChannelInfoList.list.add(OutputGetChannelInfo.fromPbInfo(channelData));
|
||||
}
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SUCCESS, outputChannelInfoList);
|
||||
} else {
|
||||
sendResponse(response, ErrorCode.INVALID_PARAMETER, null);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -46,25 +46,7 @@ public class GetGroupInfoAction extends AdminAction {
|
||||
if (groupInfo == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
|
||||
pojoGroupInfo.setExtra(groupInfo.getExtra());
|
||||
pojoGroupInfo.setName(groupInfo.getName());
|
||||
pojoGroupInfo.setOwner(groupInfo.getOwner());
|
||||
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
|
||||
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
|
||||
pojoGroupInfo.setType(groupInfo.getType());
|
||||
pojoGroupInfo.setMember_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setMute(groupInfo.getMute());
|
||||
pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
|
||||
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
|
||||
pojoGroupInfo.setSearchable(groupInfo.getSearchable());
|
||||
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
|
||||
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
|
||||
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
|
||||
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
|
||||
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
|
||||
result = RestResult.ok(pojoGroupInfo);
|
||||
result = RestResult.ok(PojoGroupInfo.fromProto(groupInfo));
|
||||
}
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputStringCountOffset;
|
||||
import cn.wildfirechat.pojos.InputSubscribeChannel;
|
||||
import cn.wildfirechat.pojos.OutputBooleanValue;
|
||||
import cn.wildfirechat.pojos.PojoTotalList;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.List_Channel_Subscriber)
|
||||
@HttpMethod("POST")
|
||||
public class ListChannelSubscriberAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputStringCountOffset inputSubscribeChannel = getRequestBody(request.getNettyRequest(), InputStringCountOffset.class);
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (inputSubscribeChannel != null
|
||||
&& !StringUtil.isNullOrEmpty(inputSubscribeChannel.target)
|
||||
&& inputSubscribeChannel.count > 0) {
|
||||
int count = messagesStore.getChannelListenerCount(inputSubscribeChannel.target);
|
||||
List<String> list = messagesStore.getChannelListenerList(inputSubscribeChannel.target, inputSubscribeChannel.count, inputSubscribeChannel.offset);
|
||||
RestResult result = RestResult.ok(new PojoTotalList(count, list));
|
||||
response.setContent(gson.toJson(result));
|
||||
} else {
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputChatroomMute;
|
||||
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.Chatroom_MuteAll)
|
||||
@HttpMethod("POST")
|
||||
public class SetChatroomMuteAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputChatroomMute input = getRequestBody(request.getNettyRequest(), InputChatroomMute.class);
|
||||
if (input != null
|
||||
&& !StringUtil.isNullOrEmpty(input.getChatroomId())) {
|
||||
|
||||
ErrorCode code = messagesStore.setChatroomState(input.getChatroomId(), input.getStatus());
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
response.setContent(gson.toJson(RestResult.resultOf(code)));
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SUCCESS, null);
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.UserSettingPojo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.User_Get_Setting)
|
||||
@HttpMethod("POST")
|
||||
public class UserSettingGetAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
UserSettingPojo input = getRequestBody(request.getNettyRequest(), UserSettingPojo.class);
|
||||
if (input != null && (!StringUtil.isNullOrEmpty(input.getUserId()))) {
|
||||
WFCMessage.UserSettingEntry entry = messagesStore.getUserSetting(input.getUserId(), input.getScope(), input.getKey());
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result;
|
||||
if (entry == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
input.setValue(entry.getValue());
|
||||
result = RestResult.ok(input);
|
||||
}
|
||||
response.setContent(gson.toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.UserSettingPojo;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import static win.liyufan.im.IMTopic.PutUserSettingTopic;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingMyChannels;
|
||||
|
||||
@Route(APIPath.User_Put_Setting)
|
||||
@HttpMethod("POST")
|
||||
public class UserSettingPutAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
UserSettingPojo userSettingPojo = getRequestBody(request.getNettyRequest(), UserSettingPojo.class);
|
||||
if (userSettingPojo != null && !StringUtil.isNullOrEmpty(userSettingPojo.getUserId())) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(userSettingPojo.getScope()).setKey(userSettingPojo.getKey()).setValue(userSettingPojo.getValue()).build();
|
||||
sendApiMessage(response, userSettingPojo.getUserId(), PutUserSettingTopic, modifyUserSettingReq.toByteArray(), result -> {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
return new Result(errorCode);
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -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_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_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_Sender_Info = "channel.callback_with_sender_info";
|
||||
public static final String CHANNEL_Callback_With_Target_Info = "channel.callback_with_target_info";
|
||||
public static final String CHANNEL_New_Callback_Feature = "channel.new_callback_feature";
|
||||
|
||||
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_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.netty.buffer.ByteBuf;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import static io.moquette.server.config.MediaServerConfig.FILE_STROAGE_REMOTE_SERVER_URL;
|
||||
|
||||
@Handler("GMUT")
|
||||
public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTokenRequest> {
|
||||
@Override
|
||||
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();
|
||||
|
||||
String token;
|
||||
|
||||
WFCMessage.GetUploadTokenResult.Builder resultBuilder = WFCMessage.GetUploadTokenResult.newBuilder();
|
||||
if (MediaServerConfig.USER_QINIU) {
|
||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||
@@ -93,12 +105,12 @@ public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTo
|
||||
break;
|
||||
}
|
||||
|
||||
token = auth.uploadToken(bucketName);
|
||||
token = auth.uploadToken(bucketName, request.getMediaPath());
|
||||
resultBuilder.setDomain(bucketDomain)
|
||||
.setServer(MediaServerConfig.QINIU_SERVER_URL);
|
||||
resultBuilder.setPort(80);
|
||||
} else {
|
||||
token = UploadFileAction.getToken(type);
|
||||
token = UploadFileAction.getToken(type, request.getMediaPath());
|
||||
if(StringUtil.isNullOrEmpty(MediaServerConfig.FILE_STROAGE_REMOTE_SERVER_URL)) {
|
||||
resultBuilder.setDomain("http://" + MediaServerConfig.SERVER_IP + ":" + MediaServerConfig.HTTP_SERVER_PORT);
|
||||
} else {
|
||||
|
||||
@@ -104,7 +104,7 @@ public class GetQiniuUploadTokenHandler extends IMHandler<Byte> {
|
||||
.setServer(MediaServerConfig.QINIU_SERVER_URL);
|
||||
resultBuilder.setPort(80);
|
||||
} else {
|
||||
token = UploadFileAction.getToken(type);
|
||||
token = UploadFileAction.getToken(type, null);
|
||||
resultBuilder.setDomain("http://" + MediaServerConfig.SERVER_IP + ":" + MediaServerConfig.HTTP_SERVER_PORT)
|
||||
.setServer(MediaServerConfig.SERVER_IP);
|
||||
resultBuilder.setPort(MediaServerConfig.HTTP_SERVER_PORT);
|
||||
|
||||
@@ -3917,7 +3917,6 @@ public class DatabaseStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
void persistChannelListener(final String groupId, final List<String> memberList) {
|
||||
mScheduler.execute(()->{
|
||||
Connection connection = null;
|
||||
@@ -4182,6 +4181,313 @@ public class DatabaseStore {
|
||||
}
|
||||
}
|
||||
|
||||
void batchInsertChannelListener(String channelId, List<String> listeners, boolean listen) throws SQLException {
|
||||
LOG.info("updateChannelListener {}", channelId);
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
int size = 0;
|
||||
String sql = listen
|
||||
? "insert into t_channel_listener (_cid, _mid, _dt) values(?, ?, ?)"
|
||||
: "delete from t_channel_listener where _cid=? and _mid=?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
for (String listener : listeners) {
|
||||
int index = 1;
|
||||
statement.setString(index++, channelId);
|
||||
statement.setString(index++, listener);
|
||||
if (listen) {
|
||||
statement.setLong(index++, System.currentTimeMillis());
|
||||
}
|
||||
statement.addBatch();
|
||||
if(++size%100 == 0) {
|
||||
statement.executeBatch();
|
||||
statement.clearBatch();
|
||||
}
|
||||
}
|
||||
if(size%100 != 0) {
|
||||
statement.executeBatch();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
throw e;
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> findMissingMids(String cid, List<String> midList, boolean contain) {
|
||||
if (midList == null || midList.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
String tempTable = "temp_check_mids_" + System.currentTimeMillis();
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = DBUtil.getConnection();
|
||||
|
||||
// Step 1: 创建临时表
|
||||
try (Statement st = conn.createStatement()) {
|
||||
st.execute("CREATE TEMPORARY TABLE " + tempTable +
|
||||
" (_mid VARCHAR(64) NOT NULL PRIMARY KEY)");
|
||||
}
|
||||
|
||||
// Step 2: 批量插入
|
||||
String insertSql = "INSERT IGNORE INTO " + tempTable + " (_mid) VALUES (?)";
|
||||
try (PreparedStatement ps = conn.prepareStatement(insertSql)) {
|
||||
int count = 0;
|
||||
for (String mid : midList) {
|
||||
ps.setString(1, mid);
|
||||
ps.addBatch();
|
||||
if (++count % 1000 == 0) {
|
||||
ps.executeBatch();
|
||||
ps.clearBatch();
|
||||
}
|
||||
}
|
||||
if (count % 1000 != 0) {
|
||||
ps.executeBatch();
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: 查询
|
||||
String querySql = "SELECT t._mid FROM " + tempTable + " t " +
|
||||
"WHERE " + (contain ? "" : " NOT ") + " EXISTS (" +
|
||||
" SELECT 1 FROM t_channel_listener c " +
|
||||
" WHERE c._cid = ? AND c._mid = t._mid" +
|
||||
")";
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
try (PreparedStatement ps = conn.prepareStatement(querySql)) {
|
||||
ps.setString(1, cid);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
result.add(rs.getString(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("查询缺失mid失败", e);
|
||||
} finally {
|
||||
// 显式清理临时表
|
||||
if (conn != null) {
|
||||
try (Statement st = conn.createStatement()) {
|
||||
st.execute("DROP TEMPORARY TABLE IF EXISTS " + tempTable);
|
||||
} catch (SQLException ignored) {
|
||||
// 清理失败不影响主流程
|
||||
} finally {
|
||||
try { conn.close(); } catch (SQLException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<WFCMessage.ChannelInfo> getChannelInfoList(int count, int offset, boolean withDeleted) {
|
||||
List<WFCMessage.ChannelInfo> out = new ArrayList<>();
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _cid, _name" +
|
||||
", _portrait" +
|
||||
", _owner" +
|
||||
", _secret" +
|
||||
", _status" +
|
||||
", _desc" +
|
||||
", _extra" +
|
||||
", _callback" +
|
||||
", _automatic" +
|
||||
", _menu" +
|
||||
", _dt from t_channel";
|
||||
if(!withDeleted) {
|
||||
sql += " where _status <> 64 ";
|
||||
}
|
||||
sql += " order by _dt desc ";
|
||||
|
||||
sql += " limit " + count;
|
||||
|
||||
if (offset > 0) {
|
||||
sql += " offset " + offset;
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
WFCMessage.ChannelInfo.Builder builder = WFCMessage.ChannelInfo.newBuilder();
|
||||
int index = 1;
|
||||
|
||||
String value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setTargetId(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setName(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setPortrait(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setOwner(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setSecret(value);
|
||||
|
||||
int status = rs.getInt(index++);
|
||||
builder.setStatus(status);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setDesc(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : 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++);
|
||||
builder.setUpdateDt(longValue);
|
||||
|
||||
out.add(builder.build());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
int getChannelTotalCount(boolean withDeleted) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select count(*) from t_channel";
|
||||
if(!withDeleted) {
|
||||
sql += " where _status <> 64";
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getChannelListenerCount(String channelId) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select count(*) from t_channel_listener where _cid = ?";
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setString(index++, channelId);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public List<String> getChannelListenerList(String channelId, int count, int offset) {
|
||||
List<String> out = new ArrayList<>();
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _mid from t_channel_listener where _cid = ?";
|
||||
|
||||
if(count > 0) {
|
||||
sql += " limit " + count;
|
||||
}
|
||||
|
||||
if(offset > 0) {
|
||||
sql += " offset " + offset;
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setString(index++, channelId);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
String value = rs.getString(1);
|
||||
if (!StringUtil.isNullOrEmpty(value)) {
|
||||
out.add(value);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getSensitiveWord() {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
|
||||
@@ -48,6 +48,7 @@ import win.liyufan.im.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -78,6 +79,7 @@ import static io.moquette.BrokerConstants.*;
|
||||
import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE;
|
||||
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
|
||||
import static cn.wildfirechat.pojos.MyInfoType.*;
|
||||
import static win.liyufan.im.IMTopic.PutUserSettingTopic;
|
||||
import static win.liyufan.im.UserSettingScope.*;
|
||||
|
||||
public class MemoryMessagesStore implements IMessagesStore {
|
||||
@@ -222,11 +224,13 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private boolean mRobotCallbackWithTargetInfo = false;
|
||||
private boolean mRobotMentionExternalRobot = false;
|
||||
private int mRobotGetUserInfoMask = 0;
|
||||
private boolean mRobotAppAllowAnyHost = false;
|
||||
|
||||
private boolean mChannelCallbackWithClientInfo = false;
|
||||
private boolean mChannelCallbackWithSenderInfo = false;
|
||||
private boolean mChannelCallbackWithTargetInfo = false;
|
||||
private boolean mChannelNewCallbackFeature = true;
|
||||
private boolean mChannelAppAllowAnyHost = false;
|
||||
|
||||
private Set<Integer> mUserHideProperties = new HashSet<>();
|
||||
|
||||
@@ -687,6 +691,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
try {
|
||||
mRobotGetUserInfoMask = Integer.parseInt(server.getConfig().getProperty(BrokerConstants.ROBOT_Get_User_Info_Mask, "0"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotAppAllowAnyHost = "true".equalsIgnoreCase(server.getConfig().getProperty(BrokerConstants.ROBOT_App_Allow_Any_Host, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
|
||||
@@ -697,10 +704,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
try {
|
||||
mChannelCallbackWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Target_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mChannelNewCallbackFeature = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_New_Callback_Feature, "true"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mChannelAppAllowAnyHost = "true".equalsIgnoreCase(server.getConfig().getProperty(BrokerConstants.CHANNEL_App_Allow_Any_Host, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url);
|
||||
@@ -1341,6 +1350,20 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode setChatroomState(String chatroomId, int status) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.ChatroomInfo> chatroomInfoMap = hzInstance.getMap(CHATROOMS);
|
||||
WFCMessage.ChatroomInfo info = chatroomInfoMap.get(chatroomId);
|
||||
|
||||
if (info == null) {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
info = info.toBuilder().setState(status).build();
|
||||
chatroomInfoMap.set(chatroomId, info);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long insertChatroomMessages(String target, int line, long messageId) {
|
||||
// messageId是全局的,messageSeq是跟个人相关的,理论上messageId的增长数度远远大于seq。
|
||||
@@ -2325,6 +2348,19 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
|
||||
ArrayList<WFCMessage.GroupInfo> out = new ArrayList<>();
|
||||
for (WFCMessage.UserRequest request : requests) {
|
||||
WFCMessage.GroupInfo groupInfo = mIMap.get(request.getUid());
|
||||
out.add(groupInfo);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WFCMessage.GroupInfo getGroupInfo(String groupId) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
@@ -4187,12 +4223,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
String secret = null;
|
||||
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
||||
WFCMessage.Robot robotData = getRobot(applicationId);
|
||||
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||
if(robotData != null && (mRobotAppAllowAnyHost || !StringUtil.isNullOrEmpty(robotData.getCallback())) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||
try {
|
||||
URL url = new URL(robotData.getCallback());
|
||||
if(url.getHost() == null) {
|
||||
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();
|
||||
} else {
|
||||
LOG.error("get application auth code error, request host is not the same host with callback host");
|
||||
@@ -4213,12 +4249,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
||||
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 {
|
||||
URL url = new URL(channelData.getCallback());
|
||||
if(url.getHost() == null) {
|
||||
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();
|
||||
} else {
|
||||
LOG.error("get application auth code error, request host is not the same host with callback host");
|
||||
@@ -4256,12 +4292,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
String secret = null;
|
||||
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
|
||||
WFCMessage.Robot robotData = getRobot(applicationId);
|
||||
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||
if(robotData != null && (mRobotAppAllowAnyHost || !StringUtil.isNullOrEmpty(robotData.getCallback())) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
|
||||
secret = robotData.getSecret();
|
||||
}
|
||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
|
||||
if(channelData != null && !StringUtil.isNullOrEmpty(channelData.getCallback()) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
||||
if(channelData != null && (mChannelAppAllowAnyHost || !StringUtil.isNullOrEmpty(channelData.getCallback())) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
|
||||
secret = channelData.getSecret();
|
||||
}
|
||||
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Admin) {
|
||||
@@ -4925,6 +4961,56 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return getChannelListener(channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.ChannelInfo> getChannelInfoList(int count, int offset, boolean withDeleted) {
|
||||
return databaseStore.getChannelInfoList(count, offset, withDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannelTotalCount(boolean withDeleted) {
|
||||
return databaseStore.getChannelTotalCount(withDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode batchListenChannel(String channelId, List<String> userIds, boolean listen) {
|
||||
IMap<String, WFCMessage.ChannelInfo> mIMap = m_Server.getHazelcastInstance().getMap(CHANNELS);
|
||||
WFCMessage.ChannelInfo channelData = mIMap.get(channelId);
|
||||
if(channelData == null || (channelData.getStatus() & Channel_State_Mask_Deleted) > 0) {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
List<String> missedIds = databaseStore.findMissingMids(channelId, userIds, !listen);
|
||||
|
||||
try {
|
||||
databaseStore.batchInsertChannelListener(channelId, missedIds, listen);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
new Thread(() -> {
|
||||
for (String missedId : missedIds) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingListenedChannels).setKey(channelId).setValue(listen? "1" : "0").build();
|
||||
m_Server.onApiMessage(missedId, null, modifyUserSettingReq.toByteArray(), 0, missedId, PutUserSettingTopic, ProtoConstants.RequestSourceType.Request_From_User);
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannelListenerCount(String channelId) {
|
||||
return databaseStore.getChannelListenerCount(channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getChannelListenerList(String channelId, int count, int offset) {
|
||||
return databaseStore.getChannelListenerList(channelId, count, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOnlineUserCount() {
|
||||
return m_Server.getProcessor().getConnectionDescriptors().getActiveConnectionsNo();
|
||||
|
||||
@@ -113,6 +113,7 @@ public interface IMessagesStore {
|
||||
ErrorCode modifyGroupMemberAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin);
|
||||
ErrorCode modifyGroupMemberExtra(String operator, String groupId, String extra, String memberId, boolean isAdmin);
|
||||
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests, String fromUser, boolean isAdmin);
|
||||
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests);
|
||||
WFCMessage.GroupInfo getGroupInfo(String groupId);
|
||||
Set<String> getUserGroupIds(String userId);
|
||||
Set<String> getUserGroupIds(String userId, List<Integer> types);
|
||||
@@ -170,6 +171,7 @@ public interface IMessagesStore {
|
||||
int getChatroomMemberCount(String chatroomId);
|
||||
Collection<String> getChatroomMemberClient(String userId);
|
||||
boolean checkUserClientInChatroom(String user, String clientId, String chatroomId);
|
||||
ErrorCode setChatroomState(String chatroomId, int status);
|
||||
|
||||
long insertChatroomMessages(String target, int line, long messageId);
|
||||
Collection<UserClientEntry> getChatroomMembers(String chatroomId);
|
||||
@@ -232,6 +234,12 @@ public interface IMessagesStore {
|
||||
boolean canSendMessageInChannel(String user, String channelId);
|
||||
boolean checkUserInChannel(String user, String channelId);
|
||||
Collection<String> getChannelSubscriber(String channelId);
|
||||
List<WFCMessage.ChannelInfo> getChannelInfoList(int count, int offset, boolean withDeleted);
|
||||
int getChannelTotalCount(boolean withDeleted);
|
||||
ErrorCode batchListenChannel(String channelId, List<String> userIds, boolean listen);
|
||||
int getChannelListenerCount(String channelId);
|
||||
List<String> getChannelListenerList(String channelId, int count, int offset);
|
||||
|
||||
|
||||
int getOnlineUserCount();
|
||||
GetOnlineUserResult getOnlineUsers(int offset, int count);
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.6</version>
|
||||
<version>1.4.8</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ public interface APIPath {
|
||||
String User_Online_Count = "/admin/user/online_count";
|
||||
String User_Online_List = "/admin/user/online_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 Friend_Update_Status = "/admin/friend/status";
|
||||
@@ -120,8 +121,11 @@ public interface APIPath {
|
||||
String Create_Channel = "/admin/channel/create";
|
||||
String Destroy_Channel = "/admin/channel/destroy";
|
||||
String Get_Channel_Info = "/admin/channel/get";
|
||||
String List_Channel_Info = "/admin/channel/list";
|
||||
String Subscribe_Channel = "/admin/channel/subscribe";
|
||||
String Batch_Subscribe_Channel = "/admin/channel/batch_subscribe";
|
||||
String Check_User_Subscribe_Channel = "/admin/channel/is_subscribed";
|
||||
String List_Channel_Subscriber = "/admin/channel/list_subscriber";
|
||||
String Get_System_Setting = "/admin/system/get_setting";
|
||||
String Put_System_Setting = "/admin/system/put_setting";
|
||||
String GET_CUSTOMER = "/admin/customer";
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class InputStringCountOffset {
|
||||
public String target;
|
||||
public int count;
|
||||
public int offset;
|
||||
|
||||
public InputStringCountOffset() {
|
||||
}
|
||||
|
||||
public InputStringCountOffset(String target, int count, int offset) {
|
||||
this.target = target;
|
||||
this.count = count;
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InputSubscribeChannelBatch {
|
||||
private String channelId;
|
||||
private List<String> userIds;
|
||||
private int subscribe; //1,订阅;0,取消订阅
|
||||
|
||||
public InputSubscribeChannelBatch() {
|
||||
}
|
||||
|
||||
public InputSubscribeChannelBatch(String channelId, List<String> userIds, int subscribe) {
|
||||
this.channelId = channelId;
|
||||
this.userIds = userIds;
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(String channelId) {
|
||||
this.channelId = channelId;
|
||||
}
|
||||
|
||||
public List<String> getUserIds() {
|
||||
return userIds;
|
||||
}
|
||||
|
||||
public void setUserIds(List<String> userIds) {
|
||||
this.userIds = userIds;
|
||||
}
|
||||
|
||||
public int getSubscribe() {
|
||||
return subscribe;
|
||||
}
|
||||
|
||||
public void setSubscribe(int subscribe) {
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OutputChannelInfoList {
|
||||
public List<OutputGetChannelInfo> list;
|
||||
public int total;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
/**
|
||||
* 群组信息类
|
||||
* <p>
|
||||
@@ -175,4 +177,26 @@ public class PojoGroupInfo {
|
||||
public void setMember_update_dt(long member_update_dt) {
|
||||
this.member_update_dt = member_update_dt;
|
||||
}
|
||||
|
||||
static public PojoGroupInfo fromProto(WFCMessage.GroupInfo groupInfo) {
|
||||
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
|
||||
pojoGroupInfo.setExtra(groupInfo.getExtra());
|
||||
pojoGroupInfo.setName(groupInfo.getName());
|
||||
pojoGroupInfo.setOwner(groupInfo.getOwner());
|
||||
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
|
||||
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
|
||||
pojoGroupInfo.setType(groupInfo.getType());
|
||||
pojoGroupInfo.setMember_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setMute(groupInfo.getMute());
|
||||
pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
|
||||
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
|
||||
pojoGroupInfo.setSearchable(groupInfo.getSearchable());
|
||||
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
|
||||
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
|
||||
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
|
||||
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
|
||||
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
|
||||
return pojoGroupInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PojoTotalList {
|
||||
public int total;
|
||||
public List<String> list;
|
||||
|
||||
public PojoTotalList() {
|
||||
}
|
||||
|
||||
public PojoTotalList(int total, List<String> list) {
|
||||
this.total = total;
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,8 @@ public class ProtoConstants {
|
||||
int StreamingText_Generationg = 14;
|
||||
int StreamingText_Generated = 15;
|
||||
int Not_Delivered = 16;
|
||||
int Meeting_Minutes = 25;
|
||||
int Transcription = 26;
|
||||
int Ptt_Voice = 23;
|
||||
int Enter_Channel_Chat = 71;
|
||||
int Leave_Channel_Chat = 72;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.6</version>
|
||||
<version>1.4.8</version>
|
||||
</parent>
|
||||
|
||||
<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)
|
||||
#robot.get_user_info_mask 1023
|
||||
|
||||
## 机器人应用authToken允许任意host。当为false时,机器人Web应用的host必须和机器人的callback host一致,这样能够增加安全性。
|
||||
#robot.application_allow_any_host true
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
@@ -190,6 +193,9 @@ channel.callback_with_target_info false
|
||||
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
||||
channel.new_callback_feature true
|
||||
|
||||
## 频道应用authToken允许任意host。当为false时,频道Web应用的host必须和频道的callback host一致,这样能够增加安全性。
|
||||
#channel.application_allow_any_host true
|
||||
|
||||
##禁止搜索用户
|
||||
friend.disable_search false
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>1.4.6</version>
|
||||
<version>1.4.8</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
@@ -12,6 +12,22 @@
|
||||
11. *** 1.3.8版本添加了server api发送消息的限制,限制消息体最大内容不能超过64KB,如果升级请注意业务系统发送消息大小。***
|
||||
|
||||
# 更新记录
|
||||
--------------
|
||||
Release note 1.4.8:
|
||||
1. 添加配置支持机器人和频道应用不校验host。
|
||||
2. 解决server api获取频道列表缺少字段。
|
||||
3. 优化文件上传认证的问题。
|
||||
4. 同步专业版IM服务SDK添加获取未读数接口。
|
||||
|
||||
|
||||
Release note 1.4.7:
|
||||
1. 添加获取所有机器人的Server API接口。
|
||||
2. 添加获取某个电话号码的用户列表的Server API接口。
|
||||
3. 机器人发送消息distribute为false时不重新分发。
|
||||
4. 解决机器人和频道API请求错误时result不为空的问题。
|
||||
5. 机器人添加根据邮箱获取用户信息和批量获取用户信息的接口。
|
||||
6. 添加批量订阅/取消订阅的频道接口,添加批量获取订阅用户的接口。
|
||||
|
||||
--------------
|
||||
Release note 1.4.6:
|
||||
1. 添加网盘存储类型。
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.6</version>
|
||||
<version>1.4.8</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -2,9 +2,12 @@ package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.pojos.mesh.PojoStringList;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 频道管理类
|
||||
* <p>
|
||||
@@ -53,6 +56,21 @@ public class ChannelAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, inputChannelId, OutputGetChannelInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道信息列表
|
||||
* @param count 数量
|
||||
* @param offset offset
|
||||
* @return 频道信息列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputChannelInfoList> getChannelInfoList(int count, int offset) throws Exception {
|
||||
String path = APIPath.List_Channel_Info;
|
||||
InputCountOffset inputCountOffset = new InputCountOffset();
|
||||
inputCountOffset.count = count;
|
||||
inputCountOffset.offset = offset;
|
||||
return AdminHttpUtils.httpJsonPost(path, inputCountOffset, OutputChannelInfoList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅频道
|
||||
* @param channelId 频道ID
|
||||
@@ -66,6 +84,19 @@ public class ChannelAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量用户订阅频道
|
||||
* @param channelId 频道ID
|
||||
* @param userIds 用户ID列表
|
||||
* @return 订阅结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> batchSubscribeChannel(String channelId, List<String> userIds) throws Exception {
|
||||
String path = APIPath.Batch_Subscribe_Channel;
|
||||
InputSubscribeChannelBatch input = new InputSubscribeChannelBatch(channelId, userIds, 1);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订阅频道
|
||||
* @param channelId 频道ID
|
||||
@@ -79,6 +110,19 @@ public class ChannelAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量用户取消订阅频道
|
||||
* @param channelId 频道ID
|
||||
* @param userIds 用户ID列表
|
||||
* @return 取消订阅结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> batchUnsubscribeChannel(String channelId, List<String> userIds) throws Exception {
|
||||
String path = APIPath.Batch_Subscribe_Channel;
|
||||
InputSubscribeChannelBatch input = new InputSubscribeChannelBatch(channelId, userIds, 0);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否订阅了频道
|
||||
* @param userId 用户ID
|
||||
@@ -91,4 +135,18 @@ public class ChannelAdmin {
|
||||
InputSubscribeChannel input = new InputSubscribeChannel(channelId, userId, 0);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputBooleanValue.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道订阅用户列表
|
||||
* @param channelId 频道ID
|
||||
* @param count
|
||||
* @param offset
|
||||
* @return 订阅用户id列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoTotalList> getChannelSubscribers(String channelId, int count, int offset) throws Exception {
|
||||
String path = APIPath.List_Channel_Subscriber;
|
||||
InputStringCountOffset input = new InputStringCountOffset(channelId, count, offset);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, PojoTotalList.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ public class Main {
|
||||
System.out.println("get user info success");
|
||||
} else {
|
||||
System.out.println("get user info by mobile failure");
|
||||
System.exit(-1);
|
||||
// System.exit(-1);
|
||||
}
|
||||
} else {
|
||||
System.out.println("get user info by mobile failure");
|
||||
@@ -485,6 +485,15 @@ public class Main {
|
||||
|
||||
// 商业版专属功能
|
||||
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();
|
||||
if (getOnlineUserCountResultIMResult != null && getOnlineUserCountResultIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
@@ -1022,7 +1031,7 @@ public class Main {
|
||||
|
||||
//验证群组已被解散
|
||||
resultGetGroupInfo = GroupAdmin.getGroupInfo(groupInfo.getTarget_id());
|
||||
if (resultGetGroupInfo != null && resultGetGroupInfo.getErrorCode() == ErrorCode.ERROR_CODE_NOT_EXIST) {
|
||||
if (resultGetGroupInfo != null && (resultGetGroupInfo.getErrorCode() == ErrorCode.ERROR_CODE_NOT_EXIST || resultGetGroupInfo.result.isDeleted())) {
|
||||
System.out.println("group dismissed verified");
|
||||
} else {
|
||||
System.out.println("group dismiss verify failure");
|
||||
@@ -1187,14 +1196,15 @@ public class Main {
|
||||
System.out.println("failure");
|
||||
}
|
||||
|
||||
//测试删除多播消息
|
||||
IMResult<Void> deleteMultiCastResult = MessageAdmin.deleteMultiCastMessage("user1", resultMulticastMessage.result.getMessageUid(), multicastReceivers);
|
||||
if (deleteMultiCastResult != null && deleteMultiCastResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("delete multicast message success");
|
||||
} else {
|
||||
System.out.println("delete multicast message failure");
|
||||
if (commercialServer) {
|
||||
//测试删除多播消息
|
||||
IMResult<Void> deleteMultiCastResult = MessageAdmin.deleteMultiCastMessage("user1", resultMulticastMessage.result.getMessageUid(), multicastReceivers);
|
||||
if (deleteMultiCastResult != null && deleteMultiCastResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("delete multicast message success");
|
||||
} else {
|
||||
System.out.println("delete multicast message failure");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//***********************************************
|
||||
@@ -1591,6 +1601,40 @@ public class Main {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<OutputChannelInfoList> channelInfoListIMResult = ChannelAdmin.getChannelInfoList(10, 0);
|
||||
if(channelInfoListIMResult != null && channelInfoListIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get channel list success");
|
||||
} else {
|
||||
System.out.println("get channel list failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
voidIMResult = ChannelAdmin.batchSubscribeChannel(inputCreateChannel.getTargetId(), Arrays.asList("user1", "user2", "user3"));
|
||||
if(voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("batch subscribe channel success");
|
||||
} else {
|
||||
System.out.println("batch subscribe channel failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
|
||||
IMResult<PojoTotalList> totalListIMResult = ChannelAdmin.getChannelSubscribers(inputCreateChannel.getTargetId(), 10, 1);
|
||||
if(totalListIMResult != null && totalListIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("get channel subscribe list success");
|
||||
} else {
|
||||
System.out.println("get channel subscribe list failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
voidIMResult = ChannelAdmin.batchUnsubscribeChannel(inputCreateChannel.getTargetId(), Arrays.asList("user1", "user2", "user3"));
|
||||
if(voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("batch unsubscribe channel success");
|
||||
} else {
|
||||
System.out.println("batch unsubscribe channel failure");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
|
||||
voidIMResult = ChannelAdmin.destroyChannel(inputCreateChannel.getTargetId());
|
||||
if(voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("success");
|
||||
@@ -1659,7 +1703,7 @@ public class Main {
|
||||
|
||||
|
||||
//测试用户设置功能
|
||||
IMResult<Void> setUserSettingResult = GeneralAdmin.setUserSetting("user1", 1, "test_key", "test_value");
|
||||
IMResult<Void> setUserSettingResult = GeneralAdmin.setUserSetting("user1", 3003, "test_key", "test_value");
|
||||
if (setUserSettingResult != null && setUserSettingResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("set user setting success");
|
||||
} else {
|
||||
@@ -1667,7 +1711,7 @@ public class Main {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
IMResult<UserSettingPojo> getUserSettingResult = GeneralAdmin.getUserSetting("user1", 1, "test_key");
|
||||
IMResult<UserSettingPojo> getUserSettingResult = GeneralAdmin.getUserSetting("user1", 3003, "test_key");
|
||||
if (getUserSettingResult != null && getUserSettingResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && "test_value".equals(getUserSettingResult.getResult().getValue())) {
|
||||
System.out.println("get user setting success");
|
||||
} else {
|
||||
@@ -2691,13 +2735,15 @@ public class Main {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
//测试重新发布消息
|
||||
IMResult<Void> republishResult = channelServiceApi.republishMessage(resultSendMessage.getResult().getMessageUid(), Arrays.asList("userId2", "userId3"));
|
||||
if (republishResult != null && republishResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("republish message success");
|
||||
} else {
|
||||
System.out.println("republish message failure");
|
||||
System.exit(-1);
|
||||
if(commercialServer) {
|
||||
//测试重新发布消息
|
||||
IMResult<Void> republishResult = channelServiceApi.republishMessage(resultSendMessage.getResult().getMessageUid(), Arrays.asList("userId2", "userId3"));
|
||||
if (republishResult != null && republishResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("republish message success");
|
||||
} else {
|
||||
System.out.println("republish message 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);
|
||||
|
||||
@@ -414,4 +414,15 @@ public class UserAdmin {
|
||||
InputUserId inputUserId = new InputUserId(userId);
|
||||
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 List<Class> buildinMessageContents = Arrays.asList(
|
||||
MeetingMinutesMessageContent.class,
|
||||
TranscriptionMessageContent.class,
|
||||
ArticlesMessageContent.class,
|
||||
StreamTextGeneratedMessageContent.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