From 3ae8f8213ff9091e1674f90e1fcca3b98dd08056 Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Fri, 11 Feb 2022 11:39:25 +0000 Subject: [PATCH] [GROUP] Notifity group subscribers of new activity concerning the group --- components/Group/Group.php | 23 +++++++++++++++++ components/Notification/Notification.php | 32 +++++++++++++++++++++--- plugins/ActivityPub/ActivityPub.php | 8 +++++- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/components/Group/Group.php b/components/Group/Group.php index fcff9bb481..89bd8760fd 100644 --- a/components/Group/Group.php +++ b/components/Group/Group.php @@ -22,6 +22,8 @@ declare(strict_types = 1); namespace Component\Group; use App\Core\Event; +use App\Entity\Activity; +use Component\Notification\Notification; use function App\Core\I18n\_m; use App\Core\Modules\Component; use App\Core\Router\RouteLoader; @@ -46,6 +48,27 @@ class Group extends Component return Event::next; } + /** + * Enqueues a notification for an Actor (such as person or group) which means + * it shows up in their home feed and such. + * @param Actor $sender + * @param Activity $activity + * @param array $targets + * @param string|null $reason + * @return bool + */ + public function onNewNotificationWithTargets(Actor $sender, Activity $activity, array $targets = [], ?string $reason = null): bool + { + foreach($targets as $target) { + if ($target->isGroup()) { + // The Group announces to its subscribers + Notification::notify($target, $activity, $target->getSubscribers(), $reason); + } + } + + return Event::next; + } + /** * Add an to the profile card for groups, if the current actor can access them */ diff --git a/components/Notification/Notification.php b/components/Notification/Notification.php index 07b0bf74dc..58a462a6bc 100644 --- a/components/Notification/Notification.php +++ b/components/Notification/Notification.php @@ -23,6 +23,7 @@ namespace Component\Notification; use App\Core\DB\DB; use App\Core\Event; +use App\Util\Exception\ServerException; use function App\Core\I18n\_m; use App\Core\Log; use App\Core\Modules\Component; @@ -36,13 +37,24 @@ use Component\Notification\Controller\Feed; class Notification extends Component { + /** + * @param RouteLoader $m + * @return bool + */ public function onAddRoute(RouteLoader $m): bool { $m->connect('feed_notifications', '/feed/notifications', [Feed::class, 'notifications']); return Event::next; } - public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering) + /** + * @param int $actor_id + * @param LocalUser $user + * @param int $ordering + * @return bool + * @throws ServerException + */ + public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): bool { DB::persist(\App\Entity\Feed::create([ 'actor_id' => $actor_id, @@ -55,21 +67,33 @@ class Notification extends Component } /** - * Enqueues a notification for an Actor (user or group) which means + * Enqueues a notification for an Actor (such as person or group) which means * it shows up in their home feed and such. + * @param Actor $sender + * @param Activity $activity + * @param array $ids_already_known + * @param string|null $reason + * @return bool */ public function onNewNotification(Actor $sender, Activity $activity, array $ids_already_known = [], ?string $reason = null): bool { $targets = $activity->getNotificationTargets(ids_already_known: $ids_already_known, sender_id: $sender->getId()); - $this->notify($sender, $activity, $targets, $reason); + if (Event::handle('NewNotificationWithTargets', [$sender, $activity, $targets, $reason]) === Event::next) { + self::notify($sender, $activity, $targets, $reason); + } return Event::next; } /** * Bring given Activity to Targets's attention + * @param Actor $sender + * @param Activity $activity + * @param array $targets + * @param string|null $reason + * @return bool */ - public function notify(Actor $sender, Activity $activity, array $targets, ?string $reason = null): bool + public static function notify(Actor $sender, Activity $activity, array $targets, ?string $reason = null): bool { $remote_targets = []; foreach ($targets as $target) { diff --git a/plugins/ActivityPub/ActivityPub.php b/plugins/ActivityPub/ActivityPub.php index 1c438cacb6..951318e344 100644 --- a/plugins/ActivityPub/ActivityPub.php +++ b/plugins/ActivityPub/ActivityPub.php @@ -32,6 +32,7 @@ declare(strict_types = 1); namespace Plugin\ActivityPub; +use ActivityPhp\Type; use App\Core\DB\DB; use App\Core\Event; use App\Core\HTTPClient; @@ -269,7 +270,12 @@ class ActivityPub extends Plugin //$to_failed = []; foreach ($to_addr as $inbox => $dummy) { try { - $res = self::postman($sender, Model::toJson($activity), $inbox); + $data = Model::toJson($activity); + if ($sender->isGroup()) { + // When the sender is a group, we have to wrap it in an Announce activity + $data = Type::create('Announce', ['object' => $data])->toJson(); + } + $res = self::postman($sender, $data, $inbox); // accumulate errors for later use, if needed $status_code = $res->getStatusCode();