diff --git a/DOCS.md b/DOCS.md index 8a3166a56..148896336 100644 --- a/DOCS.md +++ b/DOCS.md @@ -1214,6 +1214,13 @@ Message.delete(messageId).deletedBy(userId).request(); // combine parameters Message.delete(messageId).hard(true).deletedBy(userId).request(); + +// delete for me only (message is only deleted for the specified user) +Message.delete(messageId).deleteForMe(userId).request(); + +// convenience methods +Message.hardDelete(messageId).request(); +Message.deleteForMe(messageId, userId).request(); ``` **Upload file or image** diff --git a/src/main/java/io/getstream/chat/java/models/Message.java b/src/main/java/io/getstream/chat/java/models/Message.java index 7b4f19ac3..3d10d71ea 100644 --- a/src/main/java/io/getstream/chat/java/models/Message.java +++ b/src/main/java/io/getstream/chat/java/models/Message.java @@ -810,6 +810,8 @@ public static class MessageDeleteRequest extends StreamRequest generateCall(Client client) { - return client.create(MessageService.class).delete(this.id, this.hard, this.deletedBy); + return client + .create(MessageService.class) + .delete(this.id, this.hard, this.deletedBy, this.deleteForMe); } } @@ -1477,6 +1488,29 @@ public static MessageDeleteRequest delete(@NotNull String id) { return new MessageDeleteRequest(id); } + /** + * Creates a hard delete request + * + * @param id the message id + * @return the created request + */ + @NotNull + public static MessageDeleteRequest hardDelete(@NotNull String id) { + return new MessageDeleteRequest(id).hard(true); + } + + /** + * Creates a delete for me request + * + * @param id the message id + * @param userId the user id for whom the message should be deleted + * @return the created request + */ + @NotNull + public static MessageDeleteRequest deleteForMe(@NotNull String id, @NotNull String userId) { + return new MessageDeleteRequest(id).deleteForMe(userId); + } + /** * Creates a search request * diff --git a/src/main/java/io/getstream/chat/java/services/MessageService.java b/src/main/java/io/getstream/chat/java/services/MessageService.java index e8550c23b..d2ea3acf8 100644 --- a/src/main/java/io/getstream/chat/java/services/MessageService.java +++ b/src/main/java/io/getstream/chat/java/services/MessageService.java @@ -93,7 +93,8 @@ Call deleteImage( Call delete( @NotNull @Path("id") String id, @Nullable @Query("hard") Boolean hard, - @Nullable @Query("deleted_by") String deletedBy); + @Nullable @Query("deleted_by") String deletedBy, + @Nullable @Query("delete_for_me") Boolean deleteForMe); @GET("messages/{id}") Call get( diff --git a/src/test/java/io/getstream/chat/java/MessageTest.java b/src/test/java/io/getstream/chat/java/MessageTest.java index bbf5726cb..6cadfc5e1 100644 --- a/src/test/java/io/getstream/chat/java/MessageTest.java +++ b/src/test/java/io/getstream/chat/java/MessageTest.java @@ -880,4 +880,96 @@ void whenUnblockingAMessage_thenIsUnblocked() { Assertions.assertDoesNotThrow(() -> Blocklist.delete(blocklistName).request()); } + + @DisplayName("Can delete message for me only") + @Test + void whenDeletingMessageForMe_thenIsDeletedForMe() { + String text = "This is a message to delete for me only"; + MessageRequestObject messageRequest = + MessageRequestObject.builder().text(text).userId(testUserRequestObject.getId()).build(); + Message message = + Assertions.assertDoesNotThrow( + () -> + Message.send(testChannel.getType(), testChannel.getId()) + .message(messageRequest) + .request()) + .getMessage(); + Assertions.assertNull(message.getDeletedAt()); + + // Test delete for me only + Message deletedMessage = + Assertions.assertDoesNotThrow( + () -> + Message.delete(message.getId()) + .deleteForMe(testUserRequestObject.getId()) + .request()) + .getMessage(); + + // Verify the delete request was successful + Assertions.assertNotNull(deletedMessage); + + // For delete for me, the message should still exist but be marked as deleted for the specific + // user + // The deletedAt might be null as this is a "soft delete for me" operation + System.out.println("Delete for me response - deletedAt: " + deletedMessage.getDeletedAt()); + + // Verify the message still exists (delete for me doesn't permanently delete) + Message retrievedMessage = + Assertions.assertDoesNotThrow(() -> Message.get(message.getId()).request()).getMessage(); + Assertions.assertNotNull(retrievedMessage); + Assertions.assertEquals(message.getId(), retrievedMessage.getId()); + } + + @DisplayName("Can use convenience method for delete for me") + @Test + void whenUsingDeleteForMeConvenienceMethod_thenIsDeletedForMe() { + String text = "This is a message to delete for me using convenience method"; + MessageRequestObject messageRequest = + MessageRequestObject.builder().text(text).userId(testUserRequestObject.getId()).build(); + Message message = + Assertions.assertDoesNotThrow( + () -> + Message.send(testChannel.getType(), testChannel.getId()) + .message(messageRequest) + .request()) + .getMessage(); + Assertions.assertNull(message.getDeletedAt()); + + // Test convenience method for delete for me + Message deletedMessage = + Assertions.assertDoesNotThrow( + () -> Message.deleteForMe(message.getId(), testUserRequestObject.getId()).request()) + .getMessage(); + + // Verify the delete request was successful + Assertions.assertNotNull(deletedMessage); + + // Verify the message still exists (delete for me doesn't permanently delete) + Message retrievedMessage = + Assertions.assertDoesNotThrow(() -> Message.get(message.getId()).request()).getMessage(); + Assertions.assertNotNull(retrievedMessage); + Assertions.assertEquals(message.getId(), retrievedMessage.getId()); + } + + @DisplayName("Can use convenience method for hard delete") + @Test + void whenUsingHardDeleteConvenienceMethod_thenIsHardDeleted() { + String text = "This is a message to hard delete using convenience method"; + MessageRequestObject messageRequest = + MessageRequestObject.builder().text(text).userId(testUserRequestObject.getId()).build(); + Message message = + Assertions.assertDoesNotThrow( + () -> + Message.send(testChannel.getType(), testChannel.getId()) + .message(messageRequest) + .request()) + .getMessage(); + Assertions.assertNull(message.getDeletedAt()); + + // Test convenience method for hard delete + Message deletedMessage = + Assertions.assertDoesNotThrow(() -> Message.hardDelete(message.getId()).request()) + .getMessage(); + Assertions.assertNotNull(deletedMessage.getDeletedAt()); + } }