Zum Inhalt springen

Mit EXT:reactions auf Webhooks reagieren

seit TYPO3 12.1

Es gibt Zuwachs in der TYPO3 Familie und zwar gibt es ab TYPO3 12.1 die neue Systemextension reactions. Damit wird es in Zukunft möglich sein Datensätze in TYPO3 über Webhooks anzulegen, zu bearbeiten, aber auch andere Aufgaben wie einen Import zu initiieren oder auch bestimmte Statusinformationen von TYPO3 abzugreifen.

Bei Webhooks handelt es sich um Anfragen (Web-Request) an ein System, um vorgegebene Aufgaben zu erledigen. Evtl. kennt ihr Webhooks schon von Github, denn auch dort könnt ihr Webhooks einrichten, sodass z.B. nach einem Deployment die neue Version automatisch bei Packagist aktualisiert oder eine frische Version Eurer Extension Dokumentation gerendert wird.

Aktuell (02.12.2022) wird TYPO3 nur mit einem vorgegebenen Reaction-Typ ausgeliefert. Mit diesem Typ können bestimmte Datensätze wie Seiten, Kategorien, Inhaltselemente oder auch Dateisammlungen angelegt werden. Das neue System kommt schon jetzt mit einer eigenen Registrierung für Reactions, es ist also nur eine Frage der Zeit, dass TYPO3 selbst weitere Reaction-Typen anbieten wird oder, dass die TYPO3 Community mittels Extensions dieses System um weitere reaction-Typen erweitern wird.

Neuen Reaction Datensatz anlegen

Die EXT:reactions kommt mit einem neuen Backend Modul, mit dem ihr Reactions anlegen und bearbeiten könnt. Klickt im Reactions-Modul oben auf "Create new Reaction". Dort könnt ihr nun den Reaction-Typ auswählen um die sich der Reaction kümmern soll. Wie gesagt, derzeit ist nur der Typ "Create database record" verfügbar. Beim Namen und der Beschreibung könnt ihr mit eigenen Worten die Reaction detaillierter beschreiben wie "Erstelle Kategorie aus Shopware". Der Identifier wird von TYPO3 automatisiert ausgefüllt und kann nicht geändert werden. Über diesen Identifier lässt sich die Reaction eindeutig identifizieren und ist zwingender Teil des späteren Requests. Bei dem Feld Secret klickt ihr auf das kleine Generieren-Icon, um einen neuen Authorisierungs-Token für diese Reaction zu erzeugen. Achtung: Kopiert Euch den Authorisierungs-Token irgendwo hin, denn er wird nur einmal angezeigt! Nach der Speicherung habt ihr da keinen Zugriff mehr drauf und in der Datenbank befindet sich nur noch ein argon2id Hash, den ihr für den Request nicht verwenden könnt. Wenn ihr den Token verloren habt, erzeugt Euch über das Generieren-Icon bitte einen neuen Token und speichert den Datensatz ab.

Weiter unten wählt ihr die Tabelle aus, in die der neue Datensatz angelegt werden soll. Mit Storage-PID gebt ihr an, wo in welchem Systemordner (PID) neue Datensätze abzulegen sind und wählt im Feld Impersonate User einen Benutzer aus, in dessen Namen die neuen Datensätze anzulegen sind. Achtet darauf, dass der Benutzer alle Rechte oder einer entsprechenden Gruppe zugeordnet ist, die die neuen Datensätze anlegen darf. Evtl. testet ihr das zuvor mal eben manuell, um sicher zu gehen.

Je nach dem, welche Tabelle ihr ausgewählt habt, erscheinen nun unterschiedlich viele zusätzliche Felder, die ihr hier mit Standardwerten befüllen könnt. Wenn ihr mit dem Reaction nicht immer den gleichen Datensatz mit dem gleichen Titel und der gleichen Beschreibung anlegen wollt gibt es hier die Möglichkeit Platzhalten zu verwenden, die mit Daten aus dem Request (dem Payload) dynamisch befüllt werden können. Dazu später mehr.

Nach der Speicherung erscheint Eure neue Reaction in der Listenansicht des Reactions-Modul.

Aufruf des Reaction

In der Listenansicht des Reaction-Moduls seht ihr pro Reaction-Datensatz die URL, die ihr für den Aufruf verwenden sollt. Beispiel:

https://typo3git.ddev.site/typo3/reaction/baf6b616-e1ea-48d6-ab45-f8562e8028a7

Ein vollständiges Beispiel für einen cURL Request erhaltet ihr nach Klick auf Example:

curl -X 'POST' \
    'https://typo3git.ddev.site/typo3/reaction/baf6b616-e1ea-48d6-ab45-f8562e8028a7' \
      -d '{"my-payload":"my-value","field-b":"my-input"}' \
      -H 'accept: application/json' \
      -H 'x-api-key: ***your-secret***'

Den Abschnitt ***your-secret*** müsst ihr mit den Authorisierungs-Token, den ihr über das Generieren-Icon erstellt habt, ersetzen. Wenn ihr diesen Shell-Befehl nun in einem Terminalfenster ausführt, dann sollte Euch die Ausführung mit {"success":true} quittiert werden und ihr findet einen neu angelegten Datensatz in eurem oben definierten Systemordner.

Dynamische Werte mittels Payload

Anstatt feste Standardwerte für die Felder zu verwenden, habt ihr die Möglichkeit auf Daten aus dem Payload zuzugreifen. Dazu gibt es diese Syntax: ${pfad}

Schauen wir uns nochmal einen cURL Befehl an:

curl -X 'POST' \
    'https://typo3git.ddev.site/typo3/reaction/baf6b616-e1ea-48d6-ab45-f8562e8028a7' \
      -d '{"category":{"title":"Cars","desc":"wromm wromm"}}' \
      -H 'accept: application/json' \
      -H 'x-api-key: 25356c33f500f092daf65d0091eb90af6e9c3a78'

Mit der Option "-d" könnt ihr diesem POST Request zusätzliche Daten mitgeben. Diese Daten müssen in dem JSON Format angegeben sein und werden intern in ein Array umgewandelt. Dabei kann es sich auch, wie hier oben gezeigt, um ein mehrfach verschachteltes Array handeln.

TYPO3 bringt bereits eine entsprechende Pfad-Syntax mit, um auch in großen, mehrfach verschachtelten Arrays einen ganz bestimmten Wert zu extrahieren. Um in dem Request von oben an den Titel der Kategorie dranzukommen, müsst ihr folgenden Platzhalter: ${category.title} verwenden. Es liegt an Euch diesen Wert mit einem anderen fest vordefinierten Wert zu verknüpfen: Shopware Kat.: ${category.title}

Erstellen eigener Reaction-Typen

Laut Services.yaml der reactions-Extension braucht ihr nur eine neue PHP Klasse zu erstellen, die das Interface \TYPO3\CMS\Reactions\Reaction\ReactionInterface implementiert. Dadurch wird diese Klasse automatisch per Dependency Injection mit dem Tag reactions.reaction versehen und wird in der ReactionRegistry zur Verfügung gestellt und erweitert somit die Auswahlmöglichkeit der Reaction-Typen im Auswahlmenü des Reaction-Datensatzes.

Das Interface "zwingt" Euch unteranderem eine Methode react zu erstellen. Als Argumente werden Euch der komplette Request, der aufbereitete Payload (Die Daten als Array) und der Reaction-Datensatz als ReactionInstruction Objekt zur Verfügung gestellt. Werte, die nicht als Getter-Methode im ReactionInstruction Objekt abgerufen werden können, müsst Ihr mittels der toArray() Methode abrufen: toArray()['my_special_value'] ?? ''

Aktualisiert: 05.12.2022