sgalinski/sg-mail

TYPO3 Mail Queue & Templates - TYPO3 mail management extension with multilingual template and layout editing (HTML/MJML), queue and priority handling, ext:form finishers, marker/event API, CSV export, blacklist controls, and Scheduler/CLI commands.

Maintainers

Package info

gitlab.sgalinski.de/typo3/sg_mail.git

Homepage

Type:typo3-cms-extension

pkg:composer/sgalinski/sg-mail

Transparency log

Statistics

Installs: 465

Dependents: 4

Suggesters: 1

11.1.1 2026-08-14 22:25 UTC

This package is auto-updated.

Last update: 2026-08-14 23:47:11 UTC


README

sgalinski logo

License: GNU GPL, Version 2

Repository: https://gitlab.sgalinski.de/typo3/sg_mail

Please report bugs here: https://gitlab.sgalinski.de/typo3/sg_mail/-/issues

Overview

sg_mail provides a site- and language-aware mail-template service, an editable mail-layout backend module and a durable mail queue for TYPO3. It also integrates with EXT:form, provides marker and event APIs, and can capture outgoing TYPO3 mail in the queue for operational visibility.

The extension is the generic mail layer. Domain-specific workflows, such as newsletter recipients, archives and their attachment lifecycle, belong in the consuming extension.

Requirements

  • TYPO3 14.3
  • PHP 8.3 or newer
  • A configured TYPO3 mail transport (MAIL.transport)

Installation

Install the Composer package and run the TYPO3 maintenance steps:

composer require sgalinski/sg-mail
vendor/bin/typo3 extension:setup
vendor/bin/typo3 database:updateschema
vendor/bin/typo3 cache:flush

Activate the extension's Site Set for every site that uses the site settings, for example bounce processing:

# config/sites/<site>/config.yaml
dependencies:
  - sgalinski/sg-mail

After installation, open the SG Mail backend module and create or review the layouts and templates required by the project. Existing installations must also follow UPGRADE.md.

Configuration

Mail transport and queue

Configure the actual delivery transport through TYPO3's MAIL.transport configuration. By default, sg_mail registers its spool transport so outgoing TYPO3 mails are recorded in the sg_mail queue. The queue worker uses the configured real transport and adds a bypass header to prevent mails being queued a second time.

Set enableGlobalMailSpoolTransport = 0 in Settings > Extension Configuration > sg_mail if the project must not capture all outgoing TYPO3 mail. This does not disable mails created explicitly through MailDeliveryService.

Create these Scheduler tasks (or invoke the equivalent commands from a system cron):

# Send up to 50 due queue entries.
vendor/bin/typo3 sg_mail:sendMail 50

# Remove queue history older than 180 days, including FAL attachments owned only by those records.
vendor/bin/typo3 sg_mail:deleteOldMails 180 1000

The project must choose its own execution interval, batch size and retention period. A practical starting point is a queue worker every five minutes and cleanup once a day.

Bounce mailbox

Configure only non-secret values in config/sites/<site>/settings.yaml. Credentials and complete DSNs must come from the deployment environment, not version control:

sgMail:
  bounceReturnPath: bounces@example.org
  bounceMailbox:
    host: imap.example.org
    port: 993
    user: bounces@example.org
    passwordEnvironmentVariable: SG_MAIL_BOUNCE_PASSWORD
    folder: INBOX
    encryption: ssl
    validateCertificate: true
    processedFolder: Processed
    deleteProcessed: false

Alternatively, configure the name of an environment variable that contains the full IMAP DSN:

sgMail:
  bounceMailbox:
    dsnEnvironmentVariable: SG_MAIL_BOUNCE_DSN

SG_MAIL_BOUNCE_DSN may use the schemes imap, imaps, imap+ssl, imap+tls or imap+notls. A DSN overrides the individual mailbox fields; an environment-variable value overrides the corresponding site setting. The generic parsing and classification live in sg_mail; the business reaction to a bounce belongs in the consuming extension.

Template exclusions

Use the extension configuration to exclude registered templates from the backend selector and from delivery:

  • excludeTemplatesAllDomains: comma-separated template keys, for example my_extension.confirm,my_extension.alert
  • excludeTemplates: semicolon-separated site rules, for example 1,my_extension.confirm;10,my_extension.alert

Each template key has the format <extension_key>.<template_key>.

Usage

Register a shipped template

Registrations that are part of extension code are PHP files registered from ext_localconf.php. Backend-managed and form-generated registrations are stored in the database; do not write mutable registrations to fileadmin.

// EXT:my_extension/ext_localconf.php
$GLOBALS['sg_mail']['my_extension']['registration_confirmed'] =
    'EXT:my_extension/Configuration/SgMail/RegistrationConfirmed.php';
// EXT:my_extension/Configuration/SgMail/RegistrationConfirmed.php
use SGalinski\SgMail\Service\MarkerService;

return [
    'extension_key' => 'my_extension',
    'template_key' => 'registration_confirmed',
    'description' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:mail.registrationConfirmed.description',
    'subject' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:mail.registrationConfirmed.subject',
    'templateContent' => '<p>Hello {user.name},</p>',
    'markers' => [
        [
            'marker' => 'user.name',
            'type' => MarkerService::TYPE_STRING,
            'value' => 'Ada Lovelace',
            'description' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:mail.marker.userName',
        ],
    ],
];

Use templateContent for the shipped content. The deprecated templatePath mechanism is not supported for new templates. Clear TYPO3 caches after changing a PHP registration.

Create and queue a mail

Inject TemplateService and MailDeliveryService. The page and language identify the site-specific template and layout. A CLI command or middleware without a complete Extbase request must use createMailFromTemplateNameInRuntimeContext().

use SGalinski\SgMail\Domain\Model\Mail;
use SGalinski\SgMail\Service\MailDeliveryService;
use SGalinski\SgMail\Service\TemplateService;

final class RegistrationMailService
{
    public function __construct(
        private readonly TemplateService $templateService,
        private readonly MailDeliveryService $mailDeliveryService,
    ) {}

    public function queue(string $recipient, int $pageId, int $languageId): bool
    {
        $mail = $this->templateService->createMailFromTemplateName(
            'registration_confirmed',
            'my_extension',
            ['user.name' => 'Ada Lovelace'],
            $pageId,
            $languageId,
            Mail::PRIORITY_MEDIUM,
        );
        $mail->setToAddress($recipient);

        return $this->mailDeliveryService->addMailToQueue($mail);
    }
}

addMailToQueue() persists the mail for the worker. Use sendMailFromQueue($mail) only for an intentional immediate send, such as a preview or a transactional mail that must not wait for the worker. Inspect the queue and its error messages in the SG Mail backend module.

Layouts, language and forms

Layouts and database templates are edited in the SG Mail backend module. The template editor provides marker previews and sends test mails with a (PREVIEW) subject prefix. Template fields and labels can use LLL: references; the selected site language is applied when rendering.

EXT:form receives the MailToUserFinisher and MailToAdminFinisher finishers once sg_mail is installed. Select an sg_mail template in the Form Editor and configure recipient, sender and optional reply-to/CC/BCC fields there. Generated registrations are stored in the database and are migrated by the provided upgrade wizard when required.

Attachments

For mail-queue history, sg_mail supports TYPO3 FAL attachments on mail records. The cleanup command removes a file only when the deleted mail record was its last reference. Consumers that need durable or public attachment links must create and retain their own FAL references; a transient filesystem path is not a durable attachment reference.

Testing

Run the extension checks from the project root:

composer ecs vendor/sgalinski/sg-mail
composer phpstan vendor/sgalinski/sg-mail
composer phpunit vendor/sgalinski/sg-mail

Upgrade notes

See UPGRADE.md before upgrading. In particular, version 11 requires TYPO3 14.3+, moves bounce settings to the Site Set, and provides an upgrade wizard for legacy file-based mutable registrations.