How to send mail from a scheduled task in shopware6?

Viewed 63

I am trying to send mail from the scheduled task using MailService but in that, I need a sales channel Id how can I get that?

Can I send mail without the sales channel Id? or Is there any other method to send mail

Here is my code:

services.xml

<service id="Plugin\Service\ScheduledTask\TaskHandler">
    <argument type="service" id="Shopware\Core\Content\Mail\Service\MailService"/>
    <argument type="service" id="scheduled_task.repository" />
    <tag name="messenger.message_handler" />
</service>

TaskHandler.php

class TaskHandler extends ScheduledTaskHandler
{
    private AbstractMailService $mailService;

    public function __construct(AbstractMailService $mailService,EntityRepositoryInterface $scheduleTaskRepository)
    {
        parent::__construct($scheduleTaskRepository);
        $this->mailService = $mailService;
    }

    public static function getHandledMessages(): iterable
    {
        return [ Task::class ];
    }

    public function run(): void
    {
        $recipients = [
            'test@gmail.com' => 'test'
        ];
        $data = new DataBag();

        $data->set('recipients', $recipients);
        $data->set('senderName', 'RAJ');
        $data->set('subject', 'test');
        $data->set('contentPlain', 'test');
        $data->set('salesChannelId','');//TODO

        $this->mailService->send($data->all(), Context::createDefaultContext(), []);
    }
}
2 Answers

Ideally you should just fetch a sales channel id, even if you might not need sales channel specific data in your mail. In the service the id is used to fetch a sales channel entity and for getting the mail address of the sender from the config, as the config is sales channel specific. If you don't provide a sales channel id, you must provide the senderEmail yourself: $data->set('senderEmail', 'sender@example.com');.

The only way to avoid an exception being thrown without providing a sales channel id, if you absolutely must, is enabling the test mode: $data->set('testMode', true);

I think the only other side effect of this, as far as I can see, is the twig renderer being set to test mode, which makes it less strict in regards to faulty variables and such.

If you want to use the MailService then you have to set the salesChannelId. Otherwise you will get an exception.

If you don't have to use any particular sales channel or have only one storefront sales channel then you can get it's ID and use it:

services.xml

<service id="Plugin\Service\ScheduledTask\TaskHandler">
    <argument type="service" id="Shopware\Core\Content\Mail\Service\MailService"/>
    <argument type="service" id="scheduled_task.repository" />
    <argument type="service" id="sales_channel.repository"/>
    <tag name="messenger.message_handler" />
</service>

TaskHandler.php

class TaskHandler extends ScheduledTaskHandler
{
    private AbstractMailService $mailService;
    private EntityRepositoryInterface $salesChannelRepository;

    public function __construct(AbstractMailService $mailService, EntityRepositoryInterface $scheduleTaskRepository, EntityRepositoryInterface $salesChannelRepository)
    {
        parent::__construct($scheduleTaskRepository);
        $this->mailService = $mailService;
        $this->salesChannelRepository = $salesChannelRepository;
    }

    public static function getHandledMessages(): iterable
    {
        return [ Task::class ];
    }

    public function run(): void
    {
        $recipients = [
            'test@gmail.com' => 'test'
        ];
        $data = new DataBag();

        $data->set('recipients', $recipients);
        $data->set('senderName', 'RAJ');
        $data->set('subject', 'test');
        $data->set('contentPlain', 'test');
        $data->set('salesChannelId', $this->getSalesChannelId());
        $data->set('contentHtml','test');

        $this->mailService->send($data->all(), Context::createDefaultContext(), []);
    }

    private function getSalesChannelId(): string
    {
        $criteria = (new Criteria())
            ->addFilter(new EqualsFilter('type.iconName', 'default-building-shop'));

        return $this->salesChannelRepository->searchIds($criteria, Context::createDefaultContext())->firstId();
    }
}

Don't forget to set contentHtml. Otherwise you will get a violation error.

Related