Referenz
Webhook-Ereignisse
Was Samy an deine Webhook-URL schickt: Ereignisse, Header, Signatur und Wiederholungen.
Tust du etwas in der App, schickt Samy ein Ereignis an die Webhook-URL deines Packlets. Diese Seite ist zum Nachschlagen. Wie du einen Empfänger baust, steht unter Webhook einrichten.
Übersicht
type | X-Samy-Event | Wann |
|---|---|---|
button | button.pressed | Du tippst einen Aktions-Knopf unter einer Nachricht. |
ui | ui.changed | Du bedienst ein Element in einer Nachricht: Button, Schalter oder Eingabefeld. |
message | message.created | Du schreibst in einem Kanal mit Antworten. |
Jedes Ereignis ist ein POST mit JSON-Body. type, packlet_id, event_id und timestamp sind immer dabei. Alle Zeitpunkte sind ISO 8601 in UTC, nur timestamp ist eine Zahl.
| Feld | Bedeutung |
|---|---|
event_id | Kennung des Ereignisses. Wiederholt Samy die Zustellung, bleibt sie gleich. |
timestamp | Zeitpunkt der Zustellung in Sekunden seit 1970 (Unix-Zeit). |
Beide stehen im Body und sind damit von der Signatur gedeckt. Damit erkennst du wiederholte und alte Anfragen.
Knopf getippt: button
{
"type": "button",
"packlet_id": "9d2f7c10-3a5b-4c8e-9f21-6b7d8e9f0a12",
"message_id": "5b0c1a52-7c1e-4a43-9d0b-2f6f0c7d1e11",
"button_id": "done",
"pressed_at": "2026-11-09T18:00:00.000Z"
}| Feld | Bedeutung |
|---|---|
message_id | Die Nachricht, zu der der Knopf gehört. Derselbe Wert wie in der Antwort von POST /v1/push. |
button_id | Die id, die du dem Knopf gegeben hast. |
pressed_at | Zeitpunkt des Tipps. |
Pro Nachricht kommt dieses Ereignis höchstens einmal: Nach dem ersten Tipp sind die Aktions-Knöpfe der Nachricht erledigt. Link-Knöpfe (mit url) lösen kein Ereignis aus.
Element bedient: ui
{
"type": "ui",
"packlet_id": "9d2f7c10-3a5b-4c8e-9f21-6b7d8e9f0a12",
"message_id": "5b0c1a52-7c1e-4a43-9d0b-2f6f0c7d1e11",
"element_id": "rollback",
"value": null,
"changed_at": "2026-11-10T18:00:00.000Z"
}| Feld | Bedeutung |
|---|---|
message_id | Die Nachricht, zu der das Element gehört. Derselbe Wert wie in der Antwort von POST /v1/push. |
element_id | Die id des Elements. |
value | Der neue Wert: true oder false beim Schalter, der Text beim Eingabefeld, null beim Button. |
changed_at | Zeitpunkt der Bedienung. |
Den neuen Wert hat Samy schon gespeichert. Dein Tool muss ihn nicht zurückschicken.
Chat-Nachricht: message
{
"type": "message",
"packlet_id": "9d2f7c10-3a5b-4c8e-9f21-6b7d8e9f0a12",
"message_id": "c41e8a77-0d1f-4e6a-b2c3-91a4d5e6f708",
"text": "Läuft der Shop wieder?",
"sent_at": "2026-11-10T08:15:00.000Z"
}| Feld | Bedeutung |
|---|---|
message_id | Deine Nachricht. |
text | Was du geschrieben hast, 1 bis 4.000 Zeichen, ohne Formatierung. |
sent_at | Zeitpunkt. |
Header
| Header | Wert |
|---|---|
Content-Type | application/json |
X-Samy-Event | button.pressed, ui.changed oder message.created |
X-Samy-Signature | sha256= und dahinter die Signatur als Hex-Text |
X-Samy-Event-Id | Dasselbe wie event_id im Body |
X-Samy-Timestamp | Dasselbe wie timestamp im Body |
User-Agent | Samy-Webhook/1.0 |
Signatur
X-Samy-Signature = "sha256=" + hex( HMAC-SHA256( Geheimnis, Body ) )
Geheimnis = hex( SHA-256( SAMY_KEY ) )- Body sind die rohen Bytes der Anfrage, so wie sie ankommen. Nicht das neu erzeugte JSON.
- Geheimnis ist der SHA-256-Hash deines Schlüssels als Hex-Text in Kleinbuchstaben, 64 Zeichen. Dieser Text ist der HMAC-Schlüssel, nicht die 32 Bytes dahinter.
- Erzeugst du in der App einen neuen Schlüssel, ändert sich auch das Geheimnis.
Fertiger Code dazu steht unter Webhook einrichten.
Schutz vor Wiederholung
Eine gültige Anfrage bleibt gültig, auch wenn sie jemand mitschneidet und später noch einmal schickt. Löst dein Tool etwas aus, das nicht doppelt passieren darf, prüf nach der Signatur zwei Dinge:
timestampliegt höchstens 5 Minuten zurück. Ältere Anfragen lehnst du ab.event_idhast du in diesen 5 Minuten noch nicht gesehen. Sonst antwortest du mit200und tust nichts.
Lies beide Werte aus dem Body, nicht aus den Headern: Nur der Body ist signiert.
Zustellung
| Regel | Wert |
|---|---|
| Zeitlimit | 10 Sekunden bis zu deiner Antwort |
| Zeitbudget | 30 Sekunden Antwortzeit pro Minute und Konto. Ist es verbraucht, verschiebt Samy weitere Ereignisse um einige Sekunden. Antworte deshalb sofort und erledige die Arbeit danach. |
| Erfolg | jeder Status 2xx. Der Inhalt deiner Antwort wird nicht gelesen. |
| Wird wiederholt | keine Verbindung, Zeitüberschreitung, 429, 5xx |
| Wird nicht wiederholt | alle anderen Antworten, auch 3xx. Weiterleitungen folgt Samy nicht. |
| Wiederholungen | bis zu 5, also höchstens 6 Versuche |
| Abstand | erst etwa 10 bis 20 Sekunden, dann jedes Mal doppelt so lang. Nach rund zehn Minuten gibt Samy auf. |
- Mindestens einmal: Wegen der Wiederholungen kann dasselbe Ereignis mehrfach ankommen. Es trägt dann dieselbe
event_id. Wie du Doppelte erkennst, steht unter Webhook einrichten. - Kein Nachholen: Hat das Packlet keine Webhook-URL, wird nichts gesendet und später auch nichts nachgeliefert.
- Jeden Versuch zeigt die App im Protokoll des Packlets, mit dem Status deiner Antwort.
Die Webhook-URL
| Regel | |
|---|---|
| Protokoll | nur https:// |
| Länge | bis 2.048 Zeichen |
| Zugangsdaten in der Adresse | nicht erlaubt (https://name:passwort@…) |
| Ziel | öffentlich erreichbar. Private Adressen wie localhost, 10.…, 192.168.… lehnt Samy ab. |