Shopware: How to set a sender address on emails

There are a few tutorials out there how to send emails with Shopware, e.g. these two:

Unfortunately both hardcode the sender email address.

Configure sender email address and name

Back in the Magento days we had a couple of email addresses to chose from, but Shopware has only one, it is configured in Settings > Basic information:

Screenshot of the shopware admin area Settings > Basic Information showing a form with an arrow pointing on Shop owner's email address

To access this information you need to inject a \Shopware\Core\System\SystemConfig\SystemConfigService into your self implemented EmailService.

Then use it!

Then you can access the address via:

$senderAddress = $this->systemConfigService
->getString('core.basicInformation.email', $context);
$senderName = $this->systemConfigService
->getString('core.basicInformation.shopName', $context);

Make sure to provide the right context, so depending on the sales channel the correct configuration is used, especially if your EmailService is used inside a queued message, so the context might be gone. Confirm that you either can recreate it or pass it on from where the message is sourced.

You like typing? Shopware has you!

On the SystemConfigService we even have different methods to make sure the return type we get is correct, thanks Shopware! <3

getBool(key: string, [salesChannelId: null|string = null]): bool
getFloat(key: string, [salesChannelId: null|string = null]): float
getInt(key: string, [salesChannelId: null|string = null]): int
getString(key: string, [salesChannelId: null|string = null]): string

EmailService Example

Because there are so many examples out there how to send an email, I’ll only provide the most important part:

<?php declare(strict_types=1);

namespace Winkelwagen\Email\Service;

// [...]
use Shopware\Core\System\SystemConfig\SystemConfigService;

class EmailService
{
    public function __construct(
        private AbstractMailService $mailService,
        private SystemConfigService $systemConfigService
    ) {
    }

    public function sendMail(
        array $recipients,
        string $subject,
        string $messageHtml,
        SalesChannelContext $salesChannelContext
    )
    {
        $data = new DataBag();

        $data->set('recipients', $recipients);     //format: ['email address' => 'recipient name']

        $senderAddress = $this->systemConfigService->getString('core.basicInformation.email', $salesChannelContext->getContext());
        $senderName = $this->systemConfigService->getString('core.basicInformation.shopName', $salesChannelContext->getContext());

        $data->set('senderName', [$senderAddress => $senderName]);
        $data->set('subject', $subject);
 
        $data->set('contentHtml', $messageHtml);
        $data->set('contentPlain', strip_tags($messageHtml));

        $data->set('salesChannelId', $salesChannelContext->getSalesChannel()->getId());

        $this->mailService->send($data->all(), $salesChannelContext->getContext(), []);
    }
}

I hope this helps!

Update March 5th 2024: My colleague Bruno told me, that I used the wrong services – writing blog posts without testing is a stupid idea, but increases output by a lot.

Leave a Reply

Discover more from Winkelwagen

Subscribe now to keep reading and get access to the full archive.

Continue reading