Send moved-card notices as Nextcloud notifications too
Build package / xml-lint (push) Successful in 33s
Build package / php-lint (8.5) (push) Successful in 1m48s
Build package / php-lint (8.4) (push) Successful in 1m50s
Build package / unit-tests (push) Successful in 1m52s
Build package / package (push) Successful in 1m38s
Build package / xml-lint (push) Successful in 33s
Build package / php-lint (8.5) (push) Successful in 1m48s
Build package / php-lint (8.4) (push) Successful in 1m50s
Build package / unit-tests (push) Successful in 1m52s
Build package / package (push) Successful in 1m38s
Each workflow now has a notify channel (mail, notification or both) next to its recipient mode. Notifications go out per card through OCP\Notification\IManager, so they show up in the bell and as push on the mobile and desktop clients. Without the notifications app nothing is sent. The one-off "workflow disabled" notice is sent as a notification as well. Existing workflows keep mail (migration Version1004). Bumps to 35.3.0 so the migration runs.
This commit is contained in:
1 parent
35903772eb
commit
7612344726
19 files changed
+585
-70
No files matched your search
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\WorkflowDeckAutomation\Service;
|
||||
|
||||
use OCA\Deck\Db\Card;
|
||||
use OCA\WorkflowDeckAutomation\AppInfo\Application;
|
||||
use OCA\WorkflowDeckAutomation\Db\Workflow;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IUser;
|
||||
use OCP\Notification\IManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Nextcloud notifications (the bell, and from there push to the mobile and
|
||||
* desktop clients) — the counterpart to NotificationMailer. Only the raw
|
||||
* values are stored here; Notification\Notifier turns them into text when a
|
||||
* client fetches the notification.
|
||||
*
|
||||
* Without the notifications app nothing is sent and nothing is logged as an
|
||||
* error: the app is optional, and IManager would just drop the notification.
|
||||
*/
|
||||
class NotificationPusher {
|
||||
public const SUBJECT_CARD_MOVED = 'card_moved';
|
||||
public const SUBJECT_WORKFLOW_DISABLED = 'workflow_disabled';
|
||||
|
||||
public const OBJECT_CARD = 'card';
|
||||
public const OBJECT_WORKFLOW = 'workflow';
|
||||
|
||||
private const NOTIFICATIONS_APP = 'notifications';
|
||||
|
||||
public function __construct(
|
||||
private IManager $notificationManager,
|
||||
private IAppManager $appManager,
|
||||
private ITimeFactory $timeFactory,
|
||||
private LoggerInterface $logger,
|
||||
) {
|
||||
}
|
||||
|
||||
public function isAvailableFor(IUser $user): bool {
|
||||
try {
|
||||
return $this->appManager->isEnabledForUser(self::NOTIFICATIONS_APP, $user);
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* One notification per card, unlike the mail: each one links its card
|
||||
* and can be dismissed on its own. An older notification about the same
|
||||
* card is removed first, so a card that comes back and falls due again
|
||||
* is not listed twice.
|
||||
*
|
||||
* @param non-empty-list<array{workflow: Workflow, card: Card, targets: array{board: string, sourceStack: string, targetStack: string}}> $entries
|
||||
*/
|
||||
public function sendCardsMovedNotification(IUser $recipient, array $entries): void {
|
||||
if (!$this->isAvailableFor($recipient)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$workflow = $entry['workflow'];
|
||||
$card = $entry['card'];
|
||||
$targets = $entry['targets'];
|
||||
|
||||
try {
|
||||
$this->dismiss($recipient, self::OBJECT_CARD, (string)$card->getId(), self::SUBJECT_CARD_MOVED);
|
||||
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification->setApp(Application::APP_ID)
|
||||
->setUser($recipient->getUID())
|
||||
->setDateTime($this->timeFactory->getDateTime())
|
||||
->setObject(self::OBJECT_CARD, (string)$card->getId())
|
||||
->setSubject(self::SUBJECT_CARD_MOVED, [
|
||||
'cardTitle' => (string)$card->getTitle(),
|
||||
'boardId' => $workflow->getBoardId(),
|
||||
'boardTitle' => $targets['board'],
|
||||
'sourceStackId' => $workflow->getSourceStackId(),
|
||||
'sourceStackTitle' => $targets['sourceStack'],
|
||||
'targetStackId' => $workflow->getTargetStackId(),
|
||||
'targetStackTitle' => $targets['targetStack'],
|
||||
]);
|
||||
$this->notificationManager->notify($notification);
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->error('Could not notify ' . $recipient->getUID() . ' about moved card ' . $card->getId() . ': ' . $e->getMessage(), [
|
||||
'app' => Application::APP_ID,
|
||||
'exception' => $e,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Companion to NotificationMailer::sendWorkflowDisabledNotification().
|
||||
*
|
||||
* @param WorkflowRunner::TARGET_* $brokenTarget
|
||||
*/
|
||||
public function sendWorkflowDisabledNotification(IUser $user, Workflow $workflow, string $brokenTarget): void {
|
||||
if (!$this->isAvailableFor($user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification->setApp(Application::APP_ID)
|
||||
->setUser($user->getUID())
|
||||
->setDateTime($this->timeFactory->getDateTime())
|
||||
->setObject(self::OBJECT_WORKFLOW, (string)$workflow->getId())
|
||||
->setSubject(self::SUBJECT_WORKFLOW_DISABLED, [
|
||||
'workflowTitle' => (string)$workflow->getTitle(),
|
||||
'brokenTarget' => $brokenTarget,
|
||||
]);
|
||||
$this->notificationManager->notify($notification);
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->error('Could not notify ' . $user->getUID() . ' about disabled workflow ' . $workflow->getId() . ': ' . $e->getMessage(), [
|
||||
'app' => Application::APP_ID,
|
||||
'exception' => $e,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function dismiss(IUser $user, string $objectType, string $objectId, string $subject): void {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification->setApp(Application::APP_ID)
|
||||
->setUser($user->getUID())
|
||||
->setObject($objectType, $objectId)
|
||||
->setSubject($subject);
|
||||
$this->notificationManager->markProcessed($notification);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user