mirror of
https://github.com/nextcloud/spreed.git
synced 2025-07-22 06:48:21 +00:00
feat: Initial implementation of reactions notifications in federated convos
Signed-off-by: skalidindi53 <s.teja2004@gmail.com>
This commit is contained in:
@ -560,4 +560,29 @@ class BackendNotifier {
|
||||
|
||||
return $server;
|
||||
}
|
||||
|
||||
public function sendReactionNotification(
|
||||
string $remoteServer,
|
||||
int $localAttendeeId,
|
||||
string $accessToken,
|
||||
string $localToken,
|
||||
array $reactionData
|
||||
): ?bool {
|
||||
$remote = $this->prepareRemoteUrl($remoteServer);
|
||||
|
||||
$notification = $this->cloudFederationFactory->getCloudFederationNotification();
|
||||
$notification->setMessage(
|
||||
FederationManager::NOTIFICATION_REACTION_ADDED,
|
||||
FederationManager::TALK_ROOM_RESOURCE,
|
||||
(string)$localAttendeeId,
|
||||
[
|
||||
'remoteServerUrl' => $this->getServerRemoteUrl(),
|
||||
'sharedSecret' => $accessToken,
|
||||
'remoteToken' => $localToken,
|
||||
'reactionData' => $reactionData,
|
||||
]
|
||||
);
|
||||
|
||||
return $this->sendUpdateToRemote($remote, $notification);
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ class FederationManager {
|
||||
public const NOTIFICATION_PARTICIPANT_MODIFIED = 'PARTICIPANT_MODIFIED';
|
||||
public const NOTIFICATION_ROOM_MODIFIED = 'ROOM_MODIFIED';
|
||||
public const NOTIFICATION_MESSAGE_POSTED = 'MESSAGE_POSTED';
|
||||
public const NOTIFICATION_REACTION_ADDED = 'talk-reaction-added';
|
||||
public const TOKEN_LENGTH = 64;
|
||||
|
||||
public function __construct(
|
||||
|
@ -37,6 +37,8 @@ class MessageSentListener implements IEventListener {
|
||||
protected MessageParser $messageParser,
|
||||
protected IFactory $l10nFactory,
|
||||
protected ChatManager $chatManager,
|
||||
protected IUserManager $userManager,
|
||||
protected IAppConfig $appConfig,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -57,6 +59,14 @@ class MessageSentListener implements IEventListener {
|
||||
$chatMessage = $this->messageParser->createMessage($event->getRoom(), null, $event->getComment(), $l);
|
||||
$this->messageParser->parseMessage($chatMessage);
|
||||
|
||||
$messageType = $chatMessage->getMessageType();
|
||||
|
||||
// Handle reaction events
|
||||
if ($messageType === ChatManager::VERB_REACTION) {
|
||||
$this->createReactionNotification($event->getRoom(), $event->getComment());
|
||||
return;
|
||||
}
|
||||
|
||||
$systemMessage = $chatMessage->getMessageType() === ChatManager::VERB_SYSTEM ? $chatMessage->getMessageRaw() : '';
|
||||
if ($systemMessage !== 'message_edited'
|
||||
&& $systemMessage !== 'message_deleted'
|
||||
@ -124,4 +134,84 @@ class MessageSentListener implements IEventListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function createReactionNotification(Room $chat, IComment $reaction): void {
|
||||
$originalCommentId = $reaction->getObjectId();
|
||||
$originalComment = $this->chatManager->getCommentById($originalCommentId);
|
||||
|
||||
if ($originalComment === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the original comment's author should be notified
|
||||
if ($originalComment->getActorType() === Attendee::ACTOR_USERS || $originalComment->getActorType() === Attendee::ACTOR_FEDERATED_USERS) {
|
||||
try {
|
||||
$participant = $this->participantService->getParticipant($chat, $originalComment->getActorId(), false);
|
||||
} catch (ParticipantNotFoundException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notificationLevel = $participant->getAttendee()->getNotificationLevel();
|
||||
if ($notificationLevel === Participant::NOTIFY_DEFAULT) {
|
||||
if ($chat->getType() === Room::TYPE_ONE_TO_ONE) {
|
||||
$notificationLevel = Participant::NOTIFY_ALWAYS;
|
||||
} else {
|
||||
$notificationLevel = $this->getDefaultGroupNotification();
|
||||
}
|
||||
}
|
||||
|
||||
if ($notificationLevel === Participant::NOTIFY_ALWAYS) {
|
||||
$this->sendReactionNotification(
|
||||
$participant,
|
||||
$chat,
|
||||
$reaction,
|
||||
$originalComment
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function sendReactionNotification(
|
||||
Participant $participant,
|
||||
Room $room,
|
||||
IComment $reaction,
|
||||
IComment $originalComment
|
||||
): void {
|
||||
$attendee = $participant->getAttendee();
|
||||
$cloudId = $this->cloudIdManager->resolveCloudId($attendee->getActorId());
|
||||
|
||||
$notificationData = [
|
||||
'remoteMessageId' => (int)$originalComment->getId(),
|
||||
'reaction' => $reaction->getMessage(),
|
||||
'reactorType' => $reaction->getActorType(),
|
||||
'reactorId' => $reaction->getActorId(),
|
||||
'reactorDisplayName' => $this->getDisplayName($reaction->getActorType(), $reaction->getActorId()),
|
||||
'creationDatetime' => $reaction->getCreationDateTime()->format(\DateTime::ATOM),
|
||||
];
|
||||
|
||||
// Send the notification using BackendNotifier
|
||||
$success = $this->backendNotifier->sendReactionNotification(
|
||||
$cloudId->getRemote(),
|
||||
$attendee->getId(),
|
||||
$attendee->getAccessToken(),
|
||||
$room->getToken(),
|
||||
$notificationData
|
||||
);
|
||||
|
||||
if ($success === null) {
|
||||
$this->participantService->removeAttendee($room, $participant, AAttendeeRemovedEvent::REASON_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
private function getDisplayName(string $actorType, string $actorId): string {
|
||||
if ($actorType === Attendee::ACTOR_USERS) {
|
||||
$user = $this->userManager->get($actorId);
|
||||
return $user ? $user->getDisplayName() : $actorId;
|
||||
} elseif ($actorType === Attendee::ACTOR_FEDERATED_USERS) {
|
||||
$cloudId = $this->cloudIdManager->resolveCloudId($actorId);
|
||||
return $cloudId->getDisplayName() ?? $actorId;
|
||||
}
|
||||
return $actorId;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -509,3 +509,44 @@ Feature: federation/chat
|
||||
| actorType | actorId | actorDisplayName | reaction |
|
||||
| users | participant1 | participant1-displayname | 🚀 |
|
||||
| federated_users | participant2@{$REMOTE_URL} | participant2-displayname | 🚀 |
|
||||
|
||||
# Scenario: Verifying Notifications for Local Participants
|
||||
|
||||
# Given the following "spreed" app config is set
|
||||
# | federation_enabled | yes |
|
||||
# And user "participant1" creates room "room" (v4)
|
||||
# | roomType | 2 |
|
||||
# | roomName | room |
|
||||
# And user "participant1" adds federated_user "participant3" to room "room" with 200 (v4)
|
||||
# And user "participant1" adds user "participant2" to room "room" with 200 (v4)
|
||||
# And user "participant3" has the following invitations (v1)
|
||||
# | remoteServerUrl | remoteToken | state | inviterCloudId | inviterDisplayName |
|
||||
# | LOCAL | room | 0 | participant1@http://localhost:8080 | participant1-displayname |
|
||||
# And user "participant3" accepts invite to room "room" of server "LOCAL" with 200 (v1)
|
||||
# | id | name | type | remoteServer | remoteToken |
|
||||
# | LOCAL::room | room | 2 | LOCAL | room |
|
||||
|
||||
# # Enable Notifications for Local User
|
||||
# And user "participant2" sets notifications to all for room "room" (v4)
|
||||
|
||||
# #fed user
|
||||
# #And user "participant3" sets notifications to all for room "room" (v4)
|
||||
# And user "participant3" sets notifications to all for room "LOCAL::room" (v4)
|
||||
|
||||
# # Sending a Message
|
||||
# When user "participant1" sends message "Message 1" to room "room" with 201
|
||||
|
||||
# And user "participant1" react with "🚀" on message "Message 1" to room "room" with 201
|
||||
# | actorType | actorId | actorDisplayName | reaction |
|
||||
# | users | participant1 | participant1-displayname | 🚀 |
|
||||
|
||||
# # Verification for Message Notification
|
||||
# Then user "participant2" has the following notifications
|
||||
# | app | object_type | object_id | subject | message |
|
||||
# | spreed | chat | room/Message 1 | participant1-displayname sent a message in conversation room | Message 1 |
|
||||
# | spreed | room | room | participant1-displayname invited you to a group conversation: room | |
|
||||
|
||||
# Then user "participant3" has the following notifications
|
||||
# | app | object_type | object_id | subject | message |
|
||||
# | spreed | chat | LOCAL::room/Message 1 | participant1-displayname sent a message in conversation room | Message 1 |
|
||||
# #| spreed | room | LOCAL::room | participant1-displayname invited you to a group conversation: room | |
|
Reference in New Issue
Block a user