From 5f93fa2ec605435e48731a16d53a877ffed79616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E4=B8=9C=E6=B5=B7?= <296322762@qq.com> Date: Thu, 21 Dec 2023 16:05:45 +0800 Subject: [PATCH] Add chatroom directed message function --- .../im/server/api/message/MessageIT.java | 75 +++++++++++++++++++ .../im/server/api/message/MessageApi.java | 49 +++++++++++- .../api/message/send/message/MessageSend.java | 50 +++++++++++++ .../send/message/MessageSendRequest.java | 19 +++++ 4 files changed, 192 insertions(+), 1 deletion(-) diff --git a/im-sdk-core/src/integration-test/java/com/easemob/im/server/api/message/MessageIT.java b/im-sdk-core/src/integration-test/java/com/easemob/im/server/api/message/MessageIT.java index fba9c7103..aad33c249 100644 --- a/im-sdk-core/src/integration-test/java/com/easemob/im/server/api/message/MessageIT.java +++ b/im-sdk-core/src/integration-test/java/com/easemob/im/server/api/message/MessageIT.java @@ -985,4 +985,79 @@ void testGroupMessageSendMsgTextSyncDevice() { () -> this.service.group().destroyGroup(groupId).block(Utilities.IT_TIMEOUT)); } + @Test + void testDirectionalChatroomMessageSendText() { + String randomFromUsername = Utilities.randomUserName(); + String randomPassword = Utilities.randomPassword(); + + String randomToUsername = Utilities.randomUserName(); + assertDoesNotThrow(() -> this.service.user().create(randomFromUsername, randomPassword) + .block(Utilities.IT_TIMEOUT)); + assertDoesNotThrow(() -> this.service.user().create(randomToUsername, randomPassword) + .block(Utilities.IT_TIMEOUT)); + + List<String> members = new ArrayList<>(); + members.add(randomToUsername); + String roomId = assertDoesNotThrow(() -> this.service.room() + .createRoom("chat room", "room description", randomFromUsername, members, 200) + .block(Utilities.IT_TIMEOUT)); + + Set<String> roomIds = new HashSet<>(); + roomIds.add(roomId); + + assertDoesNotThrow(() -> { + EMSentMessageIds sentMessageIds = this.service.message().sendMsg() + .fromUser(randomFromUsername) + .toRooms(roomIds) + .text(msg -> msg.text("hello")) + .toRoomUsers(new HashSet<String>() { + { + add(randomToUsername); + } + }) + .extension(exts -> exts.add(EMKeyValue.of("timeout", 1))) + .chatroomMsgLevel(ChatroomMsgLevel.NORMAL) + .syncDevice(true) + .send() + .block(Utilities.IT_TIMEOUT); + + assertEquals(roomId, sentMessageIds.getMessageIdsByEntityId().keySet().iterator().next()); + }); + + assertDoesNotThrow(() -> { + Set<String> toChatRooms = new HashSet<>(); + toChatRooms.add(roomId); + + Set<String> toRoomUsers = new HashSet<>(); + toRoomUsers.add(randomToUsername); + + EMImageMessage imageMessage = + new EMImageMessage().uri(URI.create("http://example/image.png")) + .secret("secret") + .displayName("image.png"); + + Set<EMKeyValue> exts = new HashSet<>(); + exts.add(EMKeyValue.of("key", "value")); + exts.add(EMKeyValue.of("key1", 10)); + exts.add(EMKeyValue.of("key2", new HashMap<String, String>() { + { + put("mkey1", "mvalue1"); + put("mkey2", "mvalue2"); + } + })); + + EMSentMessageIds messageIds = service.message() + .sendMsg(randomFromUsername, toChatRooms, imageMessage, toRoomUsers, exts, true, + ChatroomMsgLevel.HIGH).block(); + assertEquals(roomId, messageIds.getMessageIdsByEntityId().keySet().iterator().next()); + }); + + assertDoesNotThrow( + () -> this.service.room().destroyRoom(roomId).block(Utilities.IT_TIMEOUT)); + assertDoesNotThrow( + () -> this.service.user().delete(randomFromUsername).block(Utilities.IT_TIMEOUT)); + assertDoesNotThrow( + () -> this.service.user().delete(randomToUsername).block(Utilities.IT_TIMEOUT)); + } + } diff --git a/im-sdk-core/src/main/java/com/easemob/im/server/api/message/MessageApi.java b/im-sdk-core/src/main/java/com/easemob/im/server/api/message/MessageApi.java index 5931aa9c9..5c0216aa6 100644 --- a/im-sdk-core/src/main/java/com/easemob/im/server/api/message/MessageApi.java +++ b/im-sdk-core/src/main/java/com/easemob/im/server/api/message/MessageApi.java @@ -586,7 +586,7 @@ public Mono<EMSentMessageIds> sendMsg(String from, String toType, Set<String> to * }</pre> * * @param from 发送者用户名 - * @param toGroups 消息接收方所属的群组 ID。目前每次只能传 1 个群组。 + * @param toGroups 消息接收方所属的群组 ID。目前每次只能传 1 个群组 ID。 * @param message 要发送的消息 * @param toGroupUsers 接收消息的群成员的用户 ID 数组。每次最多可传 20 个用户 ID。 * @param extensions 要发送的扩展,可以为空 @@ -601,6 +601,53 @@ public Mono<EMSentMessageIds> sendMsg(String from, Set<String> toGroups, syncDevice); } + /** + * 指定聊天室用户发送消息,你可以向聊天室中指定的一个或多个成员发送消息,但单次仅支持指定一个聊天室。 + * 对于定向消息,只有作为接收方的指定成员才能看到消息,其他聊天室成员则看不到该消息。 + * + * <p> + * API使用示例: + * <pre> {@code + * EMService service; + * + * 例如,向指定聊天室用户发送一条带有扩展字段的文本消息 + * Set<String> toRooms = new HashSet<>(); + * toRooms.add("toRoomId"); + * + * Set<String> toRoomUsers = new HashSet<>(); + * toRoomUsers.add("toUserName"); + * + * EMTextMessage textMessage = new EMTextMessage().text("hello"); + * + * Set<EMKeyValue> exts = new HashSet<>(); + * exts.add(EMKeyValue.of("key", "value")); + * + * try { + * EMSentMessageIds messageIds = service.message().sendMsg("fromUserName", toRooms, textMessage, toRoomUsers, exts, true, ChatroomMsgLevel.NORMAL).block(); + * } catch (EMException e) { + * e.getErrorCode(); + * e.getMessage(); + * } + * + * }</pre> + * + * @param from 发送者用户名 + * @param toRooms 消息接收方所属的聊天室 ID。目前每次只能传 1 个聊天室 ID。 + * @param message 要发送的消息 + * @param toRoomUsers 接收消息的聊天室成员的用户 ID 数组。每次最多可传 20 个用户 ID。 + * @param extensions 要发送的扩展,可以为空 + * @param syncDevice 消息发送成功后,是否将消息同步到发送方,true:是同步给发送方,false:是不同给发送方 + * @param chatroomMsgLevel 聊天室消息优先级: LOW-低优先级,NORMAL-普通优先级,HIGH-高优先级 + * @return 发消息响应或错误 + * @see <a href="http://docs-im-beta.easemob.com/document/server-side/message_chatroom.html#%E5%8F%91%E9%80%81%E5%AE%9A%E5%90%91%E6%B6%88%E6%81%AF">发送定向消息</a> + */ + public Mono<EMSentMessageIds> sendMsg(String from, Set<String> toRooms, + EMMessage message, Set<String> toRoomUsers, Set<EMKeyValue> extensions, + Boolean syncDevice, ChatroomMsgLevel chatroomMsgLevel) { + return this.messageSend.send(from, checkTos(toRooms), message, checkTos(toRoomUsers), extensions, + syncDevice, chatroomMsgLevel); + } + /** * 发送消息(只投递在线消息),不返回消息 ID。将在后续版本中移除。 * <p> diff --git a/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSend.java b/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSend.java index 1d4da658b..ec4e6a815 100644 --- a/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSend.java +++ b/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSend.java @@ -271,6 +271,34 @@ public Mono<EMSentMessageIds> send(String from, Set<String> tos, EMMessage messa }); } + public Mono<EMSentMessageIds> send(String from, Set<String> tos, EMMessage message, Set<String> toRoomUsers, + Set<EMKeyValue> extensions, Boolean syncDevice, ChatroomMsgLevel chatroomMsgLevel) { + return this.context.getHttpClient() + .flatMap(httpClient -> httpClient.post() + .uri("/messages/chatrooms/users") + .send(Mono.create(sink -> { + sink.success(context.getCodec() + .encode(new MessageSendRequest(from, tos, message, toRoomUsers, + MessageSendRequest.parseExtensions(extensions), + syncDevice, chatroomMsgLevel))); + })) + .responseSingle((rsp, buf) -> { + return buf.switchIfEmpty( + Mono.error(new EMUnknownException("response is null"))) + .flatMap(byteBuf -> { + ErrorMapper mapper = new DefaultErrorMapper(); + mapper.statusCode(rsp); + mapper.checkError(byteBuf); + return Mono.just(byteBuf); + }); + })) + .map(byteBuf -> { + SendMessageResponse sendMessageResponse = context.getCodec() + .decode(byteBuf, SendMessageResponse.class); + return sendMessageResponse.toEMSentMessages(); + }); + } + public class RouteSpec { private String from; @@ -389,6 +417,8 @@ public class SendSpec { private Set<String> toGroupUsers; + private Set<String> toRoomUsers; + private Set<EMKeyValue> extensions; private String routeType; @@ -452,6 +482,17 @@ public class SendSpec { this.syncDevice = syncDevice; } + SendSpec(String from, String toType, Set<String> tos, EMMessage message, Set<String> toRoomUsers, + Boolean syncDevice, ChatroomMsgLevel chatroomMsgLevel) { + this.from = from; + this.toType = toType; + this.tos = tos; + this.message = message; + this.toRoomUsers = toRoomUsers; + this.syncDevice = syncDevice; + this.chatroomMsgLevel = chatroomMsgLevel; + } + public MessageSend.SendSpec extension(Consumer<Set<EMKeyValue>> customizer) { if (this.extensions == null) { this.extensions = new HashSet<>(); @@ -480,6 +521,11 @@ public MessageSend.SendSpec toGroupUsers(Set<String> toGroupUsers) { return this; } + public MessageSend.SendSpec toRoomUsers(Set<String> toRoomUsers) { + this.toRoomUsers = toRoomUsers; + return this; + } + public Mono<EMSentMessageIds> send() { if (CHAT_ROOMS.equalsIgnoreCase(this.toType)) { if (StringUtils.isNotEmpty(routeType) && syncDevice != null) { @@ -491,6 +537,10 @@ public Mono<EMSentMessageIds> send() { .send(this.from, this.toType, this.tos, this.message, this.extensions, this.routeType, this.chatroomMsgLevel); } else if (syncDevice != null) { + if (toRoomUsers != null) { + return MessageSend.this.send(this.from, this.tos, this.message, + this.toRoomUsers, this.extensions, this.syncDevice, this.chatroomMsgLevel); + } return MessageSend.this .send(this.from, this.toType, this.tos, this.message, this.extensions, this.syncDevice, this.chatroomMsgLevel); diff --git a/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSendRequest.java b/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSendRequest.java index c86a4cc5a..0157bef4c 100644 --- a/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSendRequest.java +++ b/im-sdk-core/src/main/java/com/easemob/im/server/api/message/send/message/MessageSendRequest.java @@ -188,6 +188,25 @@ public MessageSendRequest(@JsonProperty("from") String from, this.syncDevice = syncDevice; } + @JsonCreator + public MessageSendRequest(@JsonProperty("from") String from, + @JsonProperty("to") Set<String> toSet, + @JsonProperty("msg") EMMessage message, + @JsonProperty("users") Set<String> toRoomUsers, + @JsonProperty("ext") Map<String, Object> extensions, + @JsonProperty("sync_device") Boolean syncDevice, + @JsonProperty("chatroom_msg_level") ChatroomMsgLevel chatroomMsgLevel) { + this.from = from; + this.tos = toSet; + this.toGroupUsers = toRoomUsers; + Message send = Message.of(message); + this.msgType = send.type; + this.body = send; + this.extensions = extensions; + this.syncDevice = syncDevice; + this.chatroomMsgLevel = chatroomMsgLevel.getLevel(); + } + public static Map<String, Object> parseExtensions(Set<EMKeyValue> extensions) { if (extensions == null || extensions.isEmpty()) { return null;