# Vorlagen

Fertige Nachrichten zum Kopieren: Server-Alarm, Deploy, Bestellung, Tagesbericht und Rechnung.

Fertige Nachrichten für einen Kanal. Jede Vorlage sieht hier so aus wie in Samy, und Schalter, Buttons und Eingabefelder kannst du direkt ausprobieren.

So nutzt du eine Vorlage: JSON kopieren, mit `POST /v1/push` schicken, Texte und IDs an dein Tool anpassen. Wie das geht, steht ganz unten unter [Schicken](#schicken). Was die einzelnen Felder bedeuten, steht unter [Knöpfe](https://packlets.app/docs/knoepfe.md) und [Elemente](https://packlets.app/docs/elemente.md).

## Server antwortet nicht

Dein Uptime-Check merkt, dass ein Dienst ausfällt. Die Meldung kommt mit Ton, auch in der Ruhezeit. Ein Knopf startet den Dienst neu, der zweite öffnet die Statusseite.

```json
{
  "title": "shop-api antwortet nicht",
  "text": "Seit **9:38 Uhr** kein Health-Check mehr. Letzter Status: 502.",
  "priority": "high",
  "elements": [
    {
      "type": "table", "id": "checks", "label": "Letzte Checks",
      "columns": ["Zeit", "Status", "ms"],
      "rows": [["9:36", "200", 182], ["9:37", "200", 240], ["9:38", "502", 30012], ["9:39", "502", 30008]]
    }
  ],
  "buttons": [
    { "id": "restart", "label": "Neu starten" },
    { "id": "status", "label": "Status", "url": "https://status.example.com" }
  ]
}
```

Tippst du **Neu starten**, bekommt dein Webhook das Ereignis `button` mit `button_id: "restart"`.

## Deploy fehlgeschlagen

Deine CI meldet einen roten Build. Die Tabelle zeigt, welche Tests scheitern. Den Button **Erneut starten** kannst du mehrmals tippen, anders als einen Knopf.

```json
{
  "title": "Deploy fehlgeschlagen",
  "text": "**shop-api** auf `main`, Commit a3f9c21 von Jonas.",
  "priority": "high",
  "elements": [
    {
      "type": "table", "id": "tests", "label": "Fehlgeschlagene Tests",
      "columns": ["Test", "Dauer"],
      "rows": [["checkout › Gutschein", "1,2 s"], ["checkout › Versand", "0,8 s"]]
    },
    { "type": "button", "id": "retry", "label": "Erneut starten", "width": 3 },
    { "type": "button", "id": "rollback", "label": "Zurückrollen", "style": "secondary", "width": 3 }
  ],
  "buttons": [
    { "id": "log", "label": "Log öffnen", "url": "https://ci.example.com/runs/4711" }
  ]
}
```

## Neue Bestellung

Dein Shop meldet jede Bestellung. Der Knopf markiert sie als versendet, der Link öffnet sie im Backend.

```json
{
  "title": "Neue Bestellung #1049",
  "text": "Tim R. aus Leipzig, **129,00 €**, bezahlt mit PayPal.",
  "elements": [
    {
      "type": "table", "id": "artikel",
      "columns": ["Artikel", "Menge", "€"],
      "rows": [["Kaffeemühle Classic", 1, 99], ["Bohnen Espresso 1 kg", 2, 15]]
    }
  ],
  "buttons": [
    { "id": "shipped", "label": "Versendet" },
    { "id": "open", "label": "Öffnen", "url": "https://shop.example.com/admin/orders/1049" }
  ]
}
```

## Tagesbericht

Ein Cronjob schickt jeden Morgen die Zahlen von gestern. Mit `priority: "silent"` kommt er ohne Ton.

```json
{
  "title": "Tagesbericht",
  "text": "## Gestern\n- **23 Bestellungen**, 1.204 € Umsatz\n- 3 Deploys, alle erfolgreich\n- Backup um 3:00 fertig",
  "priority": "silent",
  "elements": [
    {
      "type": "chart", "id": "umsatz", "label": "Umsatz der Woche", "unit": "€", "height": 160,
      "points": [
        { "label": "Do", "value": 1310 }, { "label": "Fr", "value": 1580 }, { "label": "Sa", "value": 720 },
        { "label": "So", "value": 640 }, { "label": "Mo", "value": 860 }, { "label": "Di", "value": 1204 }
      ]
    }
  ]
}
```

## Rechnung freigeben

Eine neue Rechnung wartet auf deine Freigabe. Zwei Knöpfe entscheiden, das Eingabefeld schickt eine Rückfrage an dein Tool. Musst du viele Rechnungen nacheinander prüfen, ist eine [eigene App](https://packlets.app/docs/apps.md) bequemer.

```json
{
  "title": "Rechnung von Hosting GmbH",
  "text": "**189,00 €**, fällig am 20.11. Leistung: Server November.",
  "elements": [
    {
      "type": "input", "id": "frage", "label": "Rückfrage an die Buchhaltung",
      "placeholder": "z. B. Warum teurer als im Oktober?", "button": "Fragen"
    }
  ],
  "buttons": [
    { "id": "approve", "label": "Freigeben" },
    { "id": "reject", "label": "Ablehnen" },
    { "id": "pdf", "label": "PDF", "url": "https://example.com/rechnungen/2026-118.pdf" }
  ]
}
```

## Schicken

Speicher das JSON einer Vorlage als `vorlage.json` und schick es als Nachricht:

```bash
curl https://api.packlets.app/v1/push \
  -H "Authorization: Bearer $SAMY_KEY" \
  -H "Content-Type: application/json" \
  -d @vorlage.json
```

```python
import json, os, requests

with open("vorlage.json") as f:
    requests.post("https://api.packlets.app/v1/push", timeout=10, json=json.load(f),
                  headers={"Authorization": f"Bearer {os.environ['SAMY_KEY']}"}).raise_for_status()
```

```typescript
import vorlage from "./vorlage.json" with { type: "json" };

const res = await fetch("https://api.packlets.app/v1/push", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.SAMY_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify(vorlage),
});
if (!res.ok) throw new Error(`Samy ${res.status}: ${await res.text()}`);
```

Danach kommt jeder Tipp auf einen Knopf als Webhook-Ereignis `button`, jede Bedienung eines Elements als Ereignis `ui`, beide mit der `message_id` der Nachricht. Wie dein Tool darauf reagiert, steht unter [Webhook einrichten](https://packlets.app/docs/webhook.md#5-auf-ereignisse-reagieren).
