Ports the standalone due-date cron script into a proper Nextcloud 34 app with a personal-settings UI, per-user workflow configuration (source/target stack, assigned-user and label filters, email notification), a TimedJob background runner, and Gitea CI pipelines. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
73 lines
2.3 KiB
PHP
73 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace OCA\WorkflowDeckAutomation\Service;
|
|
|
|
use OCA\Deck\Db\Card;
|
|
use OCA\WorkflowDeckAutomation\Db\Workflow;
|
|
use OCP\IL10N;
|
|
use OCP\IURLGenerator;
|
|
use OCP\IUser;
|
|
use OCP\Mail\IMailer;
|
|
use OCP\Util;
|
|
use Psr\Log\LoggerInterface;
|
|
use Throwable;
|
|
|
|
class NotificationMailer {
|
|
public function __construct(
|
|
private IMailer $mailer,
|
|
private IURLGenerator $urlGenerator,
|
|
private IL10N $l10n,
|
|
private LoggerInterface $logger,
|
|
) {
|
|
}
|
|
|
|
public function sendCardMovedNotification(IUser $user, Workflow $workflow, Card $card): void {
|
|
$email = $user->getEMailAddress();
|
|
if ($email === null || $email === '') {
|
|
$this->logger->info('Skipping notification for workflow ' . $workflow->getId() . ': user ' . $user->getUID() . ' has no email address', [
|
|
'app' => 'workflow_deck_automation',
|
|
]);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$cardLink = $this->urlGenerator->getAbsoluteURL(
|
|
'/apps/deck/board/' . $workflow->getBoardId() . '/card/' . $card->getId(),
|
|
);
|
|
|
|
$template = $this->mailer->createEMailTemplate('workflow_deck_automation.CardMoved', [
|
|
'cardTitle' => $card->getTitle(),
|
|
'workflowTitle' => $workflow->getTitle(),
|
|
]);
|
|
$template->setSubject($this->l10n->t('Deck card moved: %s', [$card->getTitle()]));
|
|
$template->addHeader();
|
|
$template->addHeading($this->l10n->t('A card was moved automatically'), false);
|
|
$template->addBodyText($this->l10n->t(
|
|
'The card "%1$s" was moved because it is overdue (workflow "%2$s").',
|
|
[$card->getTitle(), $workflow->getTitle()],
|
|
));
|
|
$template->addBodyButton($this->l10n->t('Open card'), $cardLink);
|
|
$template->addFooter();
|
|
|
|
$message = $this->mailer->createMessage();
|
|
$message->setTo([$email => $user->getDisplayName()]);
|
|
$message->setFrom([Util::getDefaultEmailAddress('noreply') => $this->l10n->t('Deck Workflow Automation')]);
|
|
$message->useTemplate($template);
|
|
|
|
$failedRecipients = $this->mailer->send($message);
|
|
if (!empty($failedRecipients)) {
|
|
$this->logger->error('Notification mail for card ' . $card->getId() . ' failed for: ' . implode(', ', $failedRecipients), [
|
|
'app' => 'workflow_deck_automation',
|
|
]);
|
|
}
|
|
} catch (Throwable $e) {
|
|
$this->logger->error('Could not send notification mail for card ' . $card->getId() . ': ' . $e->getMessage(), [
|
|
'app' => 'workflow_deck_automation',
|
|
'exception' => $e,
|
|
]);
|
|
}
|
|
}
|
|
}
|