---
title: "Triggers"
manual: "Webhooks"
version: "13.4"
permalink: "https://docs.typo3.org/permalink/typo3/cms-webhooks:triggers@13.4"
source: "Triggers/Index.rst"
rendered: "2026-10-03T08:25:02+00:00"
---

# Triggers {#triggers}

The TYPO3 Core currently provides the following triggers for webhooks:

-   **Page Modification**

    Triggers when a page is created, updated or deleted

-   **File Added**

    Triggers when a file is added

-   **File Updated**

    Triggers when a file is updated

-   **File Removed**

    Triggers when a file is removed

-   **Login Error Occurred**

    Triggers when a login error occurred

These triggers are meant as a first set of triggers that can be used to send
webhooks. In most projects however, it is likely
that custom triggers are required.

## Custom triggers {#custom-triggers}

### Trigger by PSR-14 events {#custom-triggers-events}

Custom triggers can be added by creating a `Message` for a specific PSR-14
event and by tagging that message as a webhook message.

The following example shows how to create a simple webhook message for the
`\TYPO3\CMS\Core\Resource\Event\AfterFolderAddedEvent`:

**EXT:my_extension/Webhooks/Message/FolderAddedMessage.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Webhooks\Message;

use TYPO3\CMS\Core\Attribute\WebhookMessage;
use TYPO3\CMS\Core\Messaging\WebhookMessageInterface;
use TYPO3\CMS\Core\Resource\Event\AfterFolderAddedEvent;

#[WebhookMessage(
    identifier: 'typo3/folder-added',
    description: 'LLL:EXT:webhooks/Resources/Private/Language/locallang_db.xlf:sys_webhook.webhook_type.typo3-folder-added'
)]
final class FolderAddedMessage implements WebhookMessageInterface
{
    public function __construct(
        private readonly int $storageUid,
        private readonly string $identifier,
        private readonly string $publicUrl
    ) {}

    public static function createFromEvent(AfterFolderAddedEvent $event): self
    {
        $folder = $event->getFolder();
        return new self($folder->getStorage()->getUid(), $folder->getIdentifier(), $folder->getPublicUrl());
    }

    public function jsonSerialize(): array
    {
        return [
            'storage' => $this->storageUid,
            'identifier' => $this->identifier,
            'url' => $this->publicUrl,
        ];
    }
}

```

1.  Create a final class implementing the `\TYPO3\CMS\Core\Messaging\WebhookMessageInterface`.
1.  Add the `\TYPO3\CMS\Core\Attribute\WebhookMessage` attribute to
    the class. The attribute requires the
    following information:

    -   `identifier`: The identifier of the webhook message.
    -   `description`: The description of the webhook message. This description
        is used to describe the trigger in the TYPO3 backend.
1.  Add a static method `createFromEvent()` that creates a new instance of the message from the event you want to use as a trigger.
1.  Add a method `jsonSerialize()` that returns an array with the data that should be send with the webhook.

#### Use `Services.yaml` instead of the PHP attribute {#custom-triggers-events-services-yaml}

Instead of the PHP attribute the `Services.yaml` can be used to define the
webhook message. The following example shows how to define the webhook message
from the example above in the `Services.yaml`:

**EXT: my_extension/Configuration/Services.yaml**

```yaml
# ...

TYPO3\CMS\Webhooks\Message\FolderAddedMessage:
  tags:
    - name: 'core.webhook_message'
      identifier: 'typo3/folder-added'
      description: 'LLL:EXT:webhooks/Resources/Private/Language/locallang_db.xlf:sys_webhook.webhook_type.typo3-folder-added'

```

#### Trigger by hooks or custom code {#custom-triggers-hooks}

In case a trigger is not provided by the TYPO3 Core or a PSR-14 event is not available,
it is possible to create a custom trigger - for example by using a TYPO3 hook.

The message itself should look similar to the example above, but does not need the
`createFromEvent()` method.

Instead, the custom code (hook implementation) will create the message
and dispatch it.

Example hook implementation for a datahandler hook
(see `\TYPO3\CMS\Webhooks\Listener\PageModificationListener`):

**EXT:my_extension/Webhooks/Message/PageModificationListener.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Webhooks\Hook;

use Symfony\Component\Messenger\MessageBusInterface;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Webhooks\Message\PageModificationMessage;

final class PageModificationListener
{
    public function __construct(
        private readonly MessageBusInterface $bus,
        private readonly SiteFinder $siteFinder,
    ) {}

    public function processDatamap_afterDatabaseOperations($status, $table, $id, $fieldArray, DataHandler $dataHandler)
    {
        if ($table !== 'pages') {
            return;
        }
        // ...
        $site = $this->siteFinder->getSiteByPageId($id);
        $message = new PageModificationMessage(
            'new',
            $id,
            $fieldArray,
            $site->getIdentifier(),
            (string)$site->getRouter()->generateUri($id),
            $dataHandler->BE_USER,
        );
        // ...
        $this->bus->dispatch($message);
    }
}

```
