netresearch / universal-messenger
TYPO3 extension providing a backend module to send newsletters using Universal Messenger API
Package info
github.com/netresearch/t3x-universal-messenger
Type:typo3-cms-extension
pkg:composer/netresearch/universal-messenger
Requires
- php: ^8.2
- ext-fileinfo: *
- ext-libxml: *
- netresearch/sdk-api-universal-messenger: ^3.0
- nyholm/psr7: ^1.8
- pelago/emogrifier: ^7.2 || ^8.0
- typo3/cms-backend: ^14.0
- typo3/cms-core: ^14.0
- typo3/cms-extbase: ^14.0
- typo3/cms-fluid: ^14.0
- typo3/cms-frontend: ^14.0
- typo3/cms-lowlevel: ^14.0
Requires (Dev)
Suggests
- typo3/cms-scheduler: Allows you to run CLI scripts as a task within TYPO3
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-10 13:39:18 UTC
README
Universal Messenger
A TYPO3 extension that provides a TYPO3 backend module to send TYPO3 pages as newsletters using the Universal Messenger API.
Installation
The extension should be installed via composer:
composer require netresearch/universal-messenger
Setup
Update database structure
Use the Analyze Database Structure in the Maintenance Admin Tools section to update the database structure.
Webservice
API endpoint
To access the Universal Messenger API, store the corresponding configuration in the file additional.php within the
global structure TYPO3_CONF_VARS under EXTENSIONS and universal_messenger (note the spelling) of your TYPO3 installation.
// The universal messenger API endpoint $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['universal_messenger'] = array_merge( $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['universal_messenger'] ?? [], [ 'apiUrl' => 'YOUR-API-URL', 'apiKey' => 'YOUR-API-KEY', 'apiSecret' => 'YOUR-API-SECRET', ] );
The webservice authenticates via HTTP basic authentication. Create an API key in the Universal Messenger backend; it consists of a public key (used as the username) and a secret key (used as the password).
| Field | Description |
|---|---|
| apiUrl | Your general Universal Messenger API URL, which is the basis of all requests, e.g. https://your-domain.td.universal-messenger.de/p |
| apiKey | The public key of your Universal Messenger API key (basic auth username) |
| apiSecret | The secret key of your Universal Messenger API key (basic auth password) |
Server compatibility: The Universal Messenger REST API is not versioned on the client side — the authentication scheme depends on the Universal Messenger server version. API-key basic authentication requires a Universal Messenger server 7.56.0 or later. The
umopen/cmsbs.opentoken is deprecated since UM 7.41 and works only transitionally; older servers use it and require the2.xline of this extension (and of the underlying SDK).
Extension configuration
Open the Settings page under the Admin Tools section and switch to the Extension Configuration. Open the
configuration section of the extension universal_messenger.
General
Fig. 1: Extension Configuration Tab General
| Field | Tab | Default value | Description |
|---|---|---|---|
| Storage page ID | General | 0 | The page ID used to store the Universal Messenger newsletter channel records. |
| Page type | General | 20 | This value defines the page type used for Universal Messenger newsletter pages. It is used for the doctype field of the page table in your instance. Set a different value here if the default value is already used for other things. |
| Enable logging | Webservice | 0 | Log all Universal Messenger API requests in a log file. |
| Test newsletter channel suffix | Expert | _Test | Enter the suffix for the TEST newsletter channels here. |
| Live newsletter channel suffix | Expert | _Live | Enter the suffix for the LIVE newsletter channels here. |
Webservice
Fig. 2: Extension Configuration Tab Webservice
API logging
To enable the request/response logging of the Universal Messenger, enable the extension configuration Enable logging
and add a log writer configuration to your ext_localconf.php:
// Add logger for universal messenger $GLOBALS['TYPO3_CONF_VARS']['LOG']['Netresearch']['UniversalMessenger']['writerConfiguration'] = [ \Psr\Log\LogLevel::DEBUG => [ \TYPO3\CMS\Core\Log\Writer\FileWriter::class => [ 'logFileInfix' => 'universal_messenger', ], ], ];
Expert
Fig. 3: Extension Configuration Tab Expert
Test-/Live channels
To enable test operation, a separate channel can be set up as a test channel for a newsletter in Universal Messenger and, for example, given a suffix.
Test operation
- Channel: Newsletter_TEST
- Recipient: Defined recipient list for validating the newsletter before it is actually sent to customers.
Live operation
- Channel: Newsletter_LIVE
- Recipient: Recipient list with customer addresses
Using the setting newsletter => testChannelSuffix and liveChannelSuffix, this suffix can be
adapted to the setting in Universal Messenger.
Backend user configuration
Use the backend user setting in the Universal Messenger tab to allow individual backend users specific rights
for sending via individual newsletter channels.
Fig. 4: Backend user configuration
Note (TYPO3 v14): The newsletter page type appears in the page tree "new page" drag area automatically. Administrators always see it; for non-admin editors it is shown only when the
Newsletterpage type is enabled in their backend group underAccess Rights => Page types. Since TYPO3 v14.2 the drag area is derived from these group permissions — the formeroptions.pageTree.doktypesToShowInNewPageDragAreauser TSconfig option was deprecated and is removed in v15.0. If your installation still sets that option explicitly to a custom value, add the newsletter page type to that list, or (recommended) drop the deprecated option and grant the page type via the group permission instead.
TypoScript
The extension's default TypoScript (the newsletter preview page type, the plugin and the content element configuration) is loaded automatically, no manual "include static template" step is required for it:
- On classic (
sys_templatebased) sites it is registered globally viaExtensionManagementUtility::addTypoScript(). - On Site Set based sites, add
netresearch/universal-messengerto the site's Set dependencies inconfig/sites/<site-identifier>/config.yaml.
A second static template, Universal Messenger: Fluid Content Elements, provides the actual Fluid rendering of the
newsletter content and is required for newsletters to work, it is not loaded automatically. On classic sites,
go to the TypoScript page, select Edit TypoScript Record and then click Edit the whole TypoScript record. On the
page that opens, go to the Advanced Options tab and add it to the list of selected TypoScript configurations. On
Site Set based sites it is already imported by the netresearch/universal-messenger Set.
When creating a newsletter, the CSS is finally read from an external CSS file and the information is added as inline style attributes to the respective HTML elements.
By setting the inlineCssFiles setting, additional CSS can be passed to the newsletter container. By default,
the CSS of the Foundation for Emails 2 framework is already included (https://get.foundation/emails.html, https://github.com/foundation/foundation-emails).
plugin.tx_universalmessenger {
settings {
inlineCssFiles {
10 = EXT:universal_messenger/Resources/Public/Css/ZurbFoundation.css
20 = EXT:<YOUR-EXTENTSION>/Resources/Private/Css/<YOUR-CSS-FILE>.css
}
}
}
module.tx_universalmessenger < plugin.tx_universalmessenger
Note: Some HTML elements used by the bundled Fluid partials are not reset by the shipped
ZurbFoundation.css, nor by browser default stylesheets. For example,Textpic.html/Media.htmlrender images inside<figure>, and browsers apply a defaultmarginto it (Chrome:margin: 1em 40px) that Foundation for Emails never resets, since its own image component is class-based (.thumbnail) rather than built on<figure>. This shrinks the image's content box and can make awidth: 100%image rule look "too narrow" compared to the surrounding text column. If you hit this, add your own reset (e.g.figure { margin: 0; }) to your owninlineCssFilesentry, other elements may need the same treatment depending on your design.
Example backend layout
Go to the TypoScript page, select Edit TypoScript Record and then click Edit the whole TypoScript record. On the
page that opens, go to the Advanced Options tab and add the static TypoScript
Universal Messenger: Example Newsletter Template to the list of selected TypoScript configurations.
Open a page where you want to use the backend layout and switch to page properties and select resources tab and add
Universal Messenger: Backend Layout to the Page TSconfig selection.
Now you can select the backend layout in the layout tab.
Scheduler-Task
The extension provides a console command universal-messenger:newsletter-channels:import for importing the
Universal Messenger newsletter channels. This command can be configured as a scheduler task to automatically load the
newsletter channels into TYPO3 once a day, for example.
Usage
Basic
The newsletter channels are imported into TYPO3 as generic channels, i.e. the configured suffixes for the test or live channels are cut off (regardless of the spelling, i.e. an upper and lower case is ignored).
A newsletter page is always assigned only the generic channel name, and the separation after a TEST or LIVE dispatch only takes place in the dispatch module.
Each newsletter channel can also be configured with additional settings (a new import does not overwrite these settings):
| Field | Default value | Description |
|---|---|---|
| Sender email address | The sender's email address. If set, this overwrites the sender ID preset in the configuration file. | |
| Reply-to email address | The reply-to email address. If set, this overwrites the reply-to ID preset in the configuration file. | |
| Skip used ID | 0 | Enable if the sending should be canceled if there is already a newsletter with the same event ID in the archive. |
| Embed images | none | Behavior for embedding images. |
These settings are sent to the Universal Messenger API when the newsletter page is submitted.
Note: If "Embed images" is set to
all, Universal Messenger downloads the images from your TYPO3 instance's public URLs to embed them into the newsletter. This only works if those URLs are covered by thecmsbs.contentDownloader.urlAllowListconfigured on the Universal Messenger server side. Ask your Universal Messenger contact to add your domain to the allow list before usingall, otherwise the newsletter dispatch fails with anEventException: Ressource(n) fehlen in "html body"error.byPathonly rewrites the image URLs to relative links and is not affected by this restriction.
Creating newsletters
To create a new newsletter, simply create a new page in the TYPO3 backend. To do this, use the new shortcut
Newsletter in the page tree or create a new standard page.
Then open the page properties. For a standard page, select the new page type Newsletter.
The page will then reload and the selection for the Universal Messenger newsletter channel will appear below the selection for the page type. Select the appropriate channel for sending the newsletter here.
Create your newsletter with the usual TYPO3 content elements. If necessary, use a container framework such as https://extensions.typo3.org/extension/container_elements to group elements more easily into columns and rows.
The Universal Messenger Extension already provides some ViewHelpers to group and arrange elements according to
the Foundation for Emails 2 framework (See https://get.foundation/emails.html how to create newsletters using
this framework).
Content elements
The extension also provides content elements for use with the Universal Messenger API.
Control structure
In the settings of the content element, you enter the corresponding control structure (e.g. personalized salutation) of the Universal Messenger. You also specify the alternative that is displayed if the newsletter is displayed in the web view, for examp le, and personalization is not available.
Both the control structure and the alternative can be formatted using the RTE editor and thus adapted to the layout of the newsletter.
Since tt_content.control_structure is registered as a standalone FLUIDTEMPLATE object, it bypasses whatever
wrapping a site theme applies to other content types. If you need to wrap its website-rendered output (but not the
mail rendering) in your own site-level TypoScript, scope the override using the classic stdWrap.if / data = GP:...
pattern, not a TypoScript condition with ExpressionLanguage array access on request.getQueryParams():
# Safe: "GP:type" returns an empty string, never a PHP warning, when the "type" GET parameter is absent
tt_content.control_structure.stdWrap.wrap = <div class="component"><div class="component__content">|</div></div>
tt_content.control_structure.stdWrap.wrap.if.value.data = GP:type
tt_content.control_structure.stdWrap.wrap.if.equals = 1715682913
tt_content.control_structure.stdWrap.wrap.if.negate = 1
A condition such as [request.getQueryParams()["type"] != 1715682913] crashes with an HTTP 500 whenever the type
GET parameter is absent, i.e. on every plain page view without a newsletter render type: Symfony ExpressionLanguage's
array-access node has no null-coalescing equivalent to PHP's ??, so the resulting E_WARNING: Undefined array key
is escalated by TYPO3's default SYS.exceptionalErrors configuration into a fatal, uncaught exception.
View helpers
Initialization
To use the ViewHelpers provided by the extension, they must be made known within the HTML using the namespace
xmlns:um="http://typo3.org/ns/Netresearch/UniversalMessenger/ViewHelpers".
View helper "format.placeholder"
To pass additional placeholders within URLs, e.g. the unsubscribe link for newsletters, to the Universal Messenger, the
view helper um:format.placeholder can be used to mark a value as a placeholder using curly brackets.
<f:link.external uri="https://newsletter.example.org/unsubscribe?identifier={um:format.placeholder(value: 'identifier')}">Unsubscribe</f:link.external>
This results in an URL like https://newsletter.example.org/unsubscribe?identifier={identifier}.
Backend module
To open the backend module, click on the new entry Universal Messenger below the Netresearch group on the left side navigation.
In the view that now opens, you have the option of selecting the corresponding newsletter page and, assuming you have the appropriate access rights, you can see a preview of the respective newsletter as it would be transferred to the Universal Messenger and sent.
A language switcher will appear above the preview if there are multiple versions of a newsletter in different languages.
Note: The language switcher only appears if the newsletter page itself has been localized (e.g. via the page tree context menu or the language column in the
Pagemodule), translating individual content elements alone is not sufficient. This mirrors TYPO3 core's own page-translation detection and applies regardless of how many languages are configured for the site.
Below the preview there are two buttons for testing the sending and for the final LIVE sending. The actual LIVE sending must be confirmed again in a dialog.
Note: Once a newsletter page has been sent LIVE, the module keeps showing a status banner ("The newsletter has been sent out: ...") every time it is opened for that page and language, not just once right after sending. This is not a stale flash message, the module derives a deterministic event ID from the site, page and language, and queries Universal Messenger for that exact ID's status on every request. Once that ID has been sent, its status stays "finished" in Universal Messenger, so the banner keeps reappearing. This is the visible counterpart of the "Skip used ID" channel setting, which cancels a resend of an already-used event ID, the banner is a reminder that this newsletter/language combination has already gone out, not a report of a send that just happened.
Development
Testing
composer install composer ci:cgl composer ci:test composer ci:test:php:phplint composer ci:test:php:phpstan composer ci:test:php:rector





