Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
use OCA\Mail\Service\UserPreferenceService;
use OCA\Mail\SetupChecks\MailConnectionPerformance;
use OCA\Mail\SetupChecks\MailTransport;
use OCA\Mail\TaskProcessing\MailSendTask;
use OCA\Mail\TaskProcessing\TaskProcessingProvider;
use OCA\Mail\Vendor\Favicon\Favicon;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
Expand Down Expand Up @@ -164,6 +166,9 @@
$context->registerSetupCheck(MailTransport::class);
$context->registerSetupCheck(MailConnectionPerformance::class);

$context->registerTaskProcessingProvider(TaskProcessingProvider::class);

Check failure on line 169 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedClass

lib/AppInfo/Application.php:169:44: UndefinedClass: Class, interface or enum named OCA\Mail\TaskProcessing\TaskProcessingProvider does not exist (see https://psalm.dev/019)

Check failure on line 169 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedClass

lib/AppInfo/Application.php:169:44: UndefinedClass: Class, interface or enum named OCA\Mail\TaskProcessing\TaskProcessingProvider does not exist (see https://psalm.dev/019)

Check failure on line 169 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedClass

lib/AppInfo/Application.php:169:44: UndefinedClass: Class, interface or enum named OCA\Mail\TaskProcessing\TaskProcessingProvider does not exist (see https://psalm.dev/019)
$context->registerTaskProcessingTaskType(MailSendTask::class);

// bypass Horde Translation system
Horde_Translation::setHandler('Horde_Imap_Client', new HordeTranslationHandler());
Horde_Translation::setHandler('Horde_Mime', new HordeTranslationHandler());
Expand Down
24 changes: 23 additions & 1 deletion lib/Provider/MailService.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@
*/
namespace OCA\Mail\Provider;

use OCA\Mail\AppInfo\Application;
use OCA\Mail\Provider\Command\MessageSend;
use OCA\Mail\TaskProcessing\MailSendTask;
use OCP\Mail\Provider\Address;
use OCP\Mail\Provider\Exception\SendException;
use OCP\Mail\Provider\IAddress;
use OCP\Mail\Provider\IMessage;
use OCP\Mail\Provider\IMessageSend;
use OCP\Mail\Provider\IService;
use OCP\Mail\Provider\Message;

use OCP\TaskProcessing\IManager as TaskProcessingManager;
use OCP\TaskProcessing\Task;
use Psr\Container\ContainerInterface;

class MailService implements IService, IMessageSend {
Expand Down Expand Up @@ -184,6 +187,25 @@
*/
#[\Override]
public function sendMessage(IMessage $message, array $options = []): void {
$taskProcessingManager = $this->container->get(TaskProcessingManager::class);
$availableTaskTypes = $taskProcessingManager->getAvailableTaskTypes();
// if task processing is available use it
if (isset($availableTaskTypes[MailSendTask::ID])) {
$task = new Task(
MailSendTask::ID,
[

Check failure on line 196 in lib/Provider/MailService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

ArgumentTypeCoercion

lib/Provider/MailService.php:196:5: ArgumentTypeCoercion: Argument 2 of OCP\TaskProcessing\Task::__construct expects array<string, list<numeric|string>|numeric|string>, but parent type array{message: OCP\Mail\Provider\IMessage, options: array<array-key, mixed>, serviceId: string, userId: string} provided (see https://psalm.dev/193)

Check failure on line 196 in lib/Provider/MailService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

ArgumentTypeCoercion

lib/Provider/MailService.php:196:5: ArgumentTypeCoercion: Argument 2 of OCP\TaskProcessing\Task::__construct expects array<string, list<numeric|string>|numeric|string>, but parent type array{message: OCP\Mail\Provider\IMessage, options: array<array-key, mixed>, serviceId: string, userId: string} provided (see https://psalm.dev/193)

Check failure on line 196 in lib/Provider/MailService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

ArgumentTypeCoercion

lib/Provider/MailService.php:196:5: ArgumentTypeCoercion: Argument 2 of OCP\TaskProcessing\Task::__construct expects array<string, list<numeric|string>|numeric|string>, but parent type array{message: OCP\Mail\Provider\IMessage, options: array<array-key, mixed>, serviceId: string, userId: string} provided (see https://psalm.dev/193)
'userId' => $this->userId,
'serviceId' => $this->serviceId,
'message' => $message,
'options' => $options,
],
Application::APP_ID,
null
);
$taskProcessingManager->scheduleTask($task);
return;
}
// fallback to direct send
/** @var MessageSend $cmd */
$cmd = $this->container->get(MessageSend::class);
// perform action
Expand Down
130 changes: 130 additions & 0 deletions lib/TaskProcessing/MailSendProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Mail\TaskProcessing;

use OCA\Mail\Provider\Command\MessageSend;
use OCP\IL10N;
use OCP\Mail\Provider\Message;
use OCP\TaskProcessing\EShapeType;
use OCP\TaskProcessing\ISynchronousProvider;
use OCP\TaskProcessing\ShapeDescriptor;
use Psr\Container\ContainerInterface;

/**
* This is the task processing provider for sending messages via the mail app.
*
* @since 5.6.0
*/
class MailSendProvider implements ISynchronousProvider {

public function __construct(
private readonly ContainerInterface $container,
private readonly IL10N $l,
) { }

public function getId(): string {
return 'mail:send';
}

public function getName(): string {
return 'Mail Send Provider';
}

public function getTaskTypeId(): string {
return 'mail:send';
}

public function getExpectedRuntime(): int {
return 60;
}

public function getOptionalInputShape(): array {
return [
'userId' => new ShapeDescriptor(
$this->l->t('User ID'),
$this->l->t('The ID of the user sending the email'),
EShapeType::Text
),
'serviceId' => new ShapeDescriptor(
$this->l->t('Service ID'),
$this->l->t('The ID of the service/account sending the email'),
EShapeType::Number
),
'message' => new ShapeDescriptor(
$this->l->t('Message'),
$this->l->t('The email message to be sent (OCP\Mail\IMessage)'),
EShapeType::Object

Check failure on line 63 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedConstant

lib/TaskProcessing/MailSendProvider.php:63:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Object is not defined (see https://psalm.dev/020)

Check failure on line 63 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedConstant

lib/TaskProcessing/MailSendProvider.php:63:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Object is not defined (see https://psalm.dev/020)

Check failure on line 63 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedConstant

lib/TaskProcessing/MailSendProvider.php:63:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Object is not defined (see https://psalm.dev/020)
),
'options' => new ShapeDescriptor(
$this->l->t('Options'),
$this->l->t('Additional options for sending the email'),
EShapeType::Array

Check failure on line 68 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedConstant

lib/TaskProcessing/MailSendProvider.php:68:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Array is not defined (see https://psalm.dev/020)

Check failure on line 68 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedConstant

lib/TaskProcessing/MailSendProvider.php:68:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Array is not defined (see https://psalm.dev/020)

Check failure on line 68 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedConstant

lib/TaskProcessing/MailSendProvider.php:68:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Array is not defined (see https://psalm.dev/020)
),
];

}

public function getOptionalOutputShape(): array {
return [];
}

public function getInputShapeEnumValues(): array {
return [];
}

public function getInputShapeDefaults(): array {
return [];
}

public function getOptionalInputShapeEnumValues(): array {
return [];
}

public function getOptionalInputShapeDefaults(): array {
return [];
}

public function getOutputShapeEnumValues(): array {
return [];
}

public function getOptionalOutputShapeEnumValues(): array {
return [];
}

public function process(?string $userId, array $input, callable $reportProgress): array {
// extract parameters
$userId = $input['userId'] ?? null;
$serviceId = $input['serviceId'] ?? null;
$options = $input['options'] ?? [];
if (isset($input['message'])) {
$message = new Message();
$message->jsonDeserialize((array)$input['message']);

Check failure on line 109 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedMethod

lib/TaskProcessing/MailSendProvider.php:109:14: UndefinedMethod: Method OCP\Mail\Provider\Message::jsonDeserialize does not exist (see https://psalm.dev/022)

Check failure on line 109 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedMethod

lib/TaskProcessing/MailSendProvider.php:109:14: UndefinedMethod: Method OCP\Mail\Provider\Message::jsonDeserialize does not exist (see https://psalm.dev/022)

Check failure on line 109 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedMethod

lib/TaskProcessing/MailSendProvider.php:109:14: UndefinedMethod: Method OCP\Mail\Provider\Message::jsonDeserialize does not exist (see https://psalm.dev/022)
} else {
$message = null;
}
// validate parameters
if ($userId === null || empty($userId)) {
throw new \InvalidArgumentException('Invalid or missing userId');
}
if ($serviceId === null || empty($serviceId) || $serviceId <= 0) {
throw new \InvalidArgumentException('Invalid or missing serviceId');
}
if (!$message instanceof Message) {
throw new \InvalidArgumentException('Invalid or missing message');
}
// perform task
/** @var MessageSend $cmd */
$cmd = $this->container->get(MessageSend::class);
$cmd->perform($userId, (string)$serviceId, $message, $options);

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

PossiblyInvalidArgument

lib/TaskProcessing/MailSendProvider.php:126:56: PossiblyInvalidArgument: Argument 4 of OCA\Mail\Provider\Command\MessageSend::perform expects array<array-key, mixed>, but possibly different type OCP\Files\File|list<OCP\Files\File|numeric|string>|numeric|string provided (see https://psalm.dev/092)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

PossiblyInvalidCast

lib/TaskProcessing/MailSendProvider.php:126:34: PossiblyInvalidCast: non-empty-list<OCP\Files\File|numeric|string> cannot be cast to string (see https://psalm.dev/190)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

InvalidScalarArgument

lib/TaskProcessing/MailSendProvider.php:126:17: InvalidScalarArgument: Argument 1 of OCA\Mail\Provider\Command\MessageSend::perform expects string, but OCP\Files\File|non-empty-list<OCP\Files\File|numeric|string>|non-falsy-string|numeric provided (see https://psalm.dev/012)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

PossiblyInvalidArgument

lib/TaskProcessing/MailSendProvider.php:126:56: PossiblyInvalidArgument: Argument 4 of OCA\Mail\Provider\Command\MessageSend::perform expects array<array-key, mixed>, but possibly different type OCP\Files\File|list<OCP\Files\File|numeric|string>|numeric|string provided (see https://psalm.dev/092)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

PossiblyInvalidCast

lib/TaskProcessing/MailSendProvider.php:126:34: PossiblyInvalidCast: non-empty-list<OCP\Files\File|numeric|string> cannot be cast to string (see https://psalm.dev/190)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

InvalidScalarArgument

lib/TaskProcessing/MailSendProvider.php:126:17: InvalidScalarArgument: Argument 1 of OCA\Mail\Provider\Command\MessageSend::perform expects string, but OCP\Files\File|non-empty-list<OCP\Files\File|numeric|string>|non-falsy-string|numeric provided (see https://psalm.dev/012)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

PossiblyInvalidArgument

lib/TaskProcessing/MailSendProvider.php:126:56: PossiblyInvalidArgument: Argument 4 of OCA\Mail\Provider\Command\MessageSend::perform expects array<array-key, mixed>, but possibly different type OCP\Files\File|list<OCP\Files\File|numeric|string>|numeric|string provided (see https://psalm.dev/092)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

PossiblyInvalidCast

lib/TaskProcessing/MailSendProvider.php:126:34: PossiblyInvalidCast: non-empty-list<OCP\Files\File|numeric|string> cannot be cast to string (see https://psalm.dev/190)

Check failure on line 126 in lib/TaskProcessing/MailSendProvider.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidScalarArgument

lib/TaskProcessing/MailSendProvider.php:126:17: InvalidScalarArgument: Argument 1 of OCA\Mail\Provider\Command\MessageSend::perform expects string, but OCP\Files\File|non-empty-list<OCP\Files\File|numeric|string>|non-falsy-string|numeric provided (see https://psalm.dev/012)

return [];
}
}
85 changes: 85 additions & 0 deletions lib/TaskProcessing/MailSendTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Mail\TaskProcessing;

use OCP\IL10N;
use OCP\L10N\IFactory;
use OCP\TaskProcessing\EShapeType;
use OCP\TaskProcessing\ITaskType;
use OCP\TaskProcessing\ShapeDescriptor;

/**
* This is the task processing task type for sending messages via the mail app.
*
* @since 5.6.0
*/
class MailSendTask implements ITaskType {

public const ID = 'mail:send';
private IL10N $l;

public function __construct(
private readonly IFactory $l10nFactory,
) {
$this->l = $l10nFactory->get('lib');
}

public function getName(): string {
return $this->l->t('Mail Send');
}

public function getDescription(): string {
return $this->l->t('Send an email using the mail app.');
}

public function getId(): string {
return self::ID;
}

public function getInputShape(): array {
return [
'userId' => new ShapeDescriptor(
$this->l->t('User ID'),
$this->l->t('The ID of the user sending the email'),
EShapeType::Text
),
'serviceId' => new ShapeDescriptor(
$this->l->t('Service ID'),
$this->l->t('The ID of the service/account sending the email'),
EShapeType::Number
),
'message' => new ShapeDescriptor(
$this->l->t('Message'),
$this->l->t('The email message to be sent (OCP\Mail\IMessage)'),
EShapeType::Object

Check failure on line 61 in lib/TaskProcessing/MailSendTask.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedConstant

lib/TaskProcessing/MailSendTask.php:61:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Object is not defined (see https://psalm.dev/020)

Check failure on line 61 in lib/TaskProcessing/MailSendTask.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedConstant

lib/TaskProcessing/MailSendTask.php:61:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Object is not defined (see https://psalm.dev/020)

Check failure on line 61 in lib/TaskProcessing/MailSendTask.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedConstant

lib/TaskProcessing/MailSendTask.php:61:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Object is not defined (see https://psalm.dev/020)
),
'options' => new ShapeDescriptor(
$this->l->t('Options'),
$this->l->t('Additional options for sending the email'),
EShapeType::Array

Check failure on line 66 in lib/TaskProcessing/MailSendTask.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedConstant

lib/TaskProcessing/MailSendTask.php:66:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Array is not defined (see https://psalm.dev/020)

Check failure on line 66 in lib/TaskProcessing/MailSendTask.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedConstant

lib/TaskProcessing/MailSendTask.php:66:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Array is not defined (see https://psalm.dev/020)

Check failure on line 66 in lib/TaskProcessing/MailSendTask.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedConstant

lib/TaskProcessing/MailSendTask.php:66:5: UndefinedConstant: Constant OCP\TaskProcessing\EShapeType::Array is not defined (see https://psalm.dev/020)
),
];
}

public function getOutputShape(): array {
return [
'status_code' => new ShapeDescriptor(
$this->l->t('Status Code'),
$this->l->t('The status code of the email sending operation'),
EShapeType::Number
),
'status_message' => new ShapeDescriptor(
$this->l->t('Status Message'),
$this->l->t('A message describing the result of the email sending operation'),
EShapeType::Text
),
];
}
}
Loading