summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2023-04-11 08:22:23 -0100
committerGitHub <noreply@github.com>2023-04-11 08:22:23 -0100
commit8d44442a33d4be1854ba26cfd987fcf07d04f457 (patch)
treeb7ef7589de2a322862b4f64944be50fba767e1db /lib
parent59ba1b287371f77c98155103ef81fc288e7e7f62 (diff)
parente65ab66352039c7af35ffd133f210f6dd4ac5fc2 (diff)
Merge pull request #1725 from nextcloud/fix/noid/notification-on-mention
notification on mention
Diffstat (limited to 'lib')
-rw-r--r--lib/Interfaces/Object/FollowInterface.php3
-rw-r--r--lib/Interfaces/Object/MentionInterface.php41
-rw-r--r--lib/Interfaces/Object/NoteInterface.php54
-rw-r--r--lib/Model/ActivityPub/Object/Mention.php58
-rw-r--r--lib/Model/ActivityPub/Stream.php9
5 files changed, 162 insertions, 3 deletions
diff --git a/lib/Interfaces/Object/FollowInterface.php b/lib/Interfaces/Object/FollowInterface.php
index 648f0c8e..f831acd7 100644
--- a/lib/Interfaces/Object/FollowInterface.php
+++ b/lib/Interfaces/Object/FollowInterface.php
@@ -185,8 +185,7 @@ class FollowInterface extends AbstractActivityPubInterface implements IActivityP
*/
private function generateNotification(Follow $follow): void {
/** @var SocialAppNotificationInterface $notificationInterface */
- $notificationInterface =
- AP::$activityPub->getInterfaceFromType(SocialAppNotification::TYPE);
+ $notificationInterface = AP::$activityPub->getInterfaceFromType(SocialAppNotification::TYPE);
try {
$follower = $this->cacheActorService->getFromId($follow->getActorId());
diff --git a/lib/Interfaces/Object/MentionInterface.php b/lib/Interfaces/Object/MentionInterface.php
new file mode 100644
index 00000000..5f116eb5
--- /dev/null
+++ b/lib/Interfaces/Object/MentionInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * Nextcloud - Social Support
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Social\Interfaces\Object;
+
+use OCA\Social\Interfaces\Activity\AbstractActivityPubInterface;
+use OCA\Social\Interfaces\IActivityPubInterface;
+use OCA\Social\Tools\Traits\TArrayTools;
+
+class MentionInterface extends AbstractActivityPubInterface implements IActivityPubInterface {
+ use TArrayTools;
+
+ public function __construct() {
+ }
+}
diff --git a/lib/Interfaces/Object/NoteInterface.php b/lib/Interfaces/Object/NoteInterface.php
index 646c729f..161a79b6 100644
--- a/lib/Interfaces/Object/NoteInterface.php
+++ b/lib/Interfaces/Object/NoteInterface.php
@@ -31,25 +31,40 @@ declare(strict_types=1);
namespace OCA\Social\Interfaces\Object;
+use OCA\Social\AP;
+use OCA\Social\Db\CacheActorsRequest;
use OCA\Social\Db\StreamRequest;
+use OCA\Social\Exceptions\CacheActorDoesNotExistException;
use OCA\Social\Exceptions\InvalidOriginException;
use OCA\Social\Exceptions\ItemAlreadyExistsException;
use OCA\Social\Exceptions\ItemNotFoundException;
use OCA\Social\Exceptions\StreamNotFoundException;
use OCA\Social\Interfaces\Activity\AbstractActivityPubInterface;
use OCA\Social\Interfaces\IActivityPubInterface;
+use OCA\Social\Interfaces\Internal\SocialAppNotificationInterface;
use OCA\Social\Model\ActivityPub\ACore;
use OCA\Social\Model\ActivityPub\Activity\Create;
use OCA\Social\Model\ActivityPub\Activity\Delete;
+use OCA\Social\Model\ActivityPub\Internal\SocialAppNotification;
+use OCA\Social\Model\ActivityPub\Object\Mention;
use OCA\Social\Model\ActivityPub\Object\Note;
use OCA\Social\Service\PushService;
+use OCA\Social\Tools\Traits\TArrayTools;
class NoteInterface extends AbstractActivityPubInterface implements IActivityPubInterface {
+ use TArrayTools;
+
private StreamRequest $streamRequest;
+ private CacheActorsRequest $cacheActorsRequest;
private PushService $pushService;
- public function __construct(StreamRequest $streamRequest, PushService $pushService) {
+ public function __construct(
+ StreamRequest $streamRequest,
+ CacheActorsRequest $cacheActorsRequest,
+ PushService $pushService
+ ) {
$this->streamRequest = $streamRequest;
+ $this->cacheActorsRequest = $cacheActorsRequest;
$this->pushService = $pushService;
}
@@ -91,6 +106,7 @@ class NoteInterface extends AbstractActivityPubInterface implements IActivityPub
} catch (StreamNotFoundException $e) {
$this->streamRequest->save($note);
$this->updateDetails($note);
+ $this->generateNotification($note);
$this->pushService->onNewStream($note->getId());
}
}
@@ -115,4 +131,40 @@ class NoteInterface extends AbstractActivityPubInterface implements IActivityPub
} catch (StreamNotFoundException $e) {
}
}
+
+ private function generateNotification(Note $note): void {
+ $mentions = $note->getTags('Mention');
+ if (empty($mentions)) {
+ return;
+ }
+
+ /** @var SocialAppNotificationInterface $notificationInterface */
+ $notificationInterface = AP::$activityPub->getInterfaceFromType(SocialAppNotification::TYPE);
+ $post = $this->streamRequest->getStreamById($note->getId(), false, ACore::FORMAT_LOCAL);
+
+ foreach ($mentions as $mention) {
+ try {
+ $recipient = $this->cacheActorsRequest->getFromId($this->get('href', $mention));
+ if (!$recipient->isLocal()) { // only interested on local
+ throw new CacheActorDoesNotExistException();
+ }
+ } catch (CacheActorDoesNotExistException $e) {
+ continue;
+ }
+
+ /** @var SocialAppNotification $notification */
+ $notification = AP::$activityPub->getItemFromType(SocialAppNotification::TYPE);
+ $notification->setDetailItem('post', $post);
+ $notification->addDetail('account', $post->getActor()->getAccount());
+ $notification->setAttributedTo($recipient->getId())
+ ->setSubType(Mention::TYPE)
+ ->setId($post->getId() . '/notification+mention')
+ ->setSummary('{account} mentioned you in a post')
+ ->setObjectId($post->getId())
+ ->setTo($recipient->getId())
+ ->setLocal(true);
+
+ $notificationInterface->save($notification);
+ }
+ }
}
diff --git a/lib/Model/ActivityPub/Object/Mention.php b/lib/Model/ActivityPub/Object/Mention.php
new file mode 100644
index 00000000..2c5d7d15
--- /dev/null
+++ b/lib/Model/ActivityPub/Object/Mention.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * Nextcloud - Social Support
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Social\Model\ActivityPub\Object;
+
+use JsonSerializable;
+use OCA\Social\Model\ActivityPub\ACore;
+use OCA\Social\Model\ActivityPub\Stream;
+
+class Mention extends Stream implements JsonSerializable {
+ public const TYPE = 'Mention';
+
+ public function __construct(ACore $parent = null) {
+ parent::__construct($parent);
+
+ $this->setType(self::TYPE);
+ }
+
+ public function import(array $data): void {
+ parent::import($data);
+ }
+
+ public function importFromDatabase(array $data): void {
+ parent::importFromDatabase($data);
+ }
+
+ public function jsonSerialize(): array {
+ $result = parent::jsonSerialize();
+
+ return $result;
+ }
+}
diff --git a/lib/Model/ActivityPub/Stream.php b/lib/Model/ActivityPub/Stream.php
index 18ca8c53..ca34a237 100644
--- a/lib/Model/ActivityPub/Stream.php
+++ b/lib/Model/ActivityPub/Stream.php
@@ -43,6 +43,7 @@ use OCA\Social\Model\ActivityPub\Object\Document;
use OCA\Social\Model\ActivityPub\Object\Follow;
use OCA\Social\Model\ActivityPub\Object\Image;
use OCA\Social\Model\ActivityPub\Object\Like;
+use OCA\Social\Model\ActivityPub\Object\Mention;
use OCA\Social\Model\Client\MediaAttachment;
use OCA\Social\Model\StreamAction;
use OCA\Social\Tools\IQueryRow;
@@ -661,11 +662,19 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
public function exportAsNotification(): array {
+ // TODO - implements:
+ // status = Someone you enabled notifications for has posted a status
+ // follow_request = Someone requested to follow you
+ // poll = A poll you have voted in or created has ended
+ // update = A status you boosted with has been edited
switch ($this->getSubType()) {
case Like::TYPE:
$type = 'favourite';
break;
case Announce::TYPE:
+ $type = 'reblog';
+ break;
+ case Mention::TYPE:
$type = 'mention';
break;
case Follow::TYPE: