Meine Anfragen: die Help-Center-Seite, die den echten Stand zeigt
Melde dich in fast jedem Zendesk-Help-Center an und klick auf «Meine Anfragen», bekommst du eine Liste: Betreff, Datum, ein Wort Status. Technisch korrekt, menschlich nutzlos. Denn die eine Frage, die Kundschaft hat, «Wo steht mein Anliegen gerade?», beantwortet diese tote Liste nicht.
Dabei liegen alle Daten dafür bereit. Man muss sie nur holen. Und weil die eingeloggte Kundschaft (JWT-Login vorausgesetzt) same-origin auf die eigene Instanz zugreift, geht das direkt aus der Help-Center-Seite, ohne API-Token. Denselben Aufruf von einer fremden Domain aus müsstest du über einen tokentragenden Proxy schicken; aus der Help-Center-Seite selbst genügt das Session-Cookie.
Der Ablauf: vier Aufrufe
Alle Aufrufe laufen client-seitig aus der eingeloggten HC-Seite. Authentifiziert wird über das Session-Cookie: kein Token, kein OAuth. Lesen (GET) braucht nichts weiter, Schreiben (PUT/POST) einen CSRF-Token.
// 1. Eigene Anfragen laden – Status inklusive
const { requests } = await (
await fetch('/api/v2/requests.json?sort_by=updated_at&sort_order=desc')
).json();
// requests[].status: new | open | pending | hold | solved | closed
// 2. Für alles Schreibende: CSRF-Token holen
const { user } = await (await fetch('/api/v2/users/me.json')).json();
const csrf = user.authenticity_token;
// 3. Datei hochladen → einmalig verwendbares Upload-Token
const { upload } = await (
await fetch(`/api/v2/uploads.json?filename=${encodeURIComponent(file.name)}`, {
method: 'POST',
headers: { 'Content-Type': file.type, 'X-CSRF-Token': csrf },
body: file,
})
).json();
// 4. Antwort + Anhang an die Anfrage hängen
await fetch(`/api/v2/requests/${id}.json`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf },
body: JSON.stringify({ request: { comment: { body: text, uploads: [upload.token] } } }),
});
Zwei Dinge, die die Doku ausdrücklich sagt und die man leicht übersieht: Das Upload-Token ist einmalig, nach dem Anhängen ist es verbraucht. Und End-User-Kommentare sind immer öffentlich; das «private» Flag können nur Agenten setzen.
Für die Statusanzeige lohnt ein Blick auf die Filter-Endpunkte: Die Standard-Liste GET /api/v2/requests.json kennt keinen ?status=-Parameter. Für getrennte Ansichten gibt es GET /api/v2/requests/open.json (new/open/pending/hold) und GET /api/v2/requests/solved.json (solved/closed). Frei nach Status filtern kannst du nur über den Such-Endpunkt: GET /api/v2/requests/search.json?query=&status=hold,open nimmt eine Status-Liste entgegen. Läuft der Agent Workspace mit Custom Statuses, trägt jeder Request zusätzlich eine custom_status_id; jede bildet auf einen der sechs Standardstatus ab. Welche Zuordnung gilt, legt deine Instanz fest.
Wo das im Theme lebt
Die Standard-Seiten sind Guide-Theme-Templates: request_list_page.hbs rendert die Liste, request_page.hbs die einzelne Anfrage. Das Listen-Template bringt bereits ein Status-Filterformular mit; bevor du etwas Eigenes baust, prüf, was schon da ist. Die Templates rendern aber server-seitig mit Curlybars. Für Live-Nachladen brauchst du eigenes JavaScript. Das bindest du über die Theme-Datei script.js ein (Guide/Knowledge admin → Customize design → Edit code); sie läuft global auf allen HC-Seiten, also erst auf die richtige Seite prüfen, dann ausführen. Lad die Daten beim Öffnen der Seite oder beim Fokuswechsel nach, nicht in einem Dauer-Intervall.
Zwei Hinweise: Das Bearbeiten des Theme-Codes braucht mindestens Suite Growth; die kleinste Stufe, Suite Team, hat keinen Code-Editor. Und sobald du ein Standard-Theme im Code anfasst, wird es zum custom theme: Du besitzt es, aber du besitzt auch seine Wartung. Zendesk-Feature-Updates spielen sich dann nicht mehr automatisch ein.
public/werkstatt/bauplaene/meine-anfragen/status-liste.png
Der sichere Rückkanal
Der interessanteste Teil ist nicht das Lesen, sondern das Hochladen. Ein naheliegender Fall: Jemand kann sich nicht mehr auf der Hauptplattform anmelden, muss aber ein Dokument sicher übermitteln. Der Reflex ist E-Mail, und E-Mail ist der schlechteste denkbare Kanal dafür: unterwegs oft unverschlüsselt, liegt danach in mehreren Postfächern, kein Zugriffsschutz, keine saubere Spur.
Der Upload über ein Help-Center-Ticket ist das Gegenteil: über HTTPS übertragen, über die Anmeldung identifiziert, per einmaligem Token an einen einzelnen Kommentar gebunden und im Verlauf nachvollziehbar. Statt eines losen Anhangs in einem Mail-Verlauf ein authentifizierter Vorgang am richtigen Ort. An der Grösse liegt der Vorteil nicht: API-Upload und Mailanhang liegen beide bei rund 50 MB pro Datei.
Ob dein Help Center End-User-Uploads überhaupt zulässt, steuert eine Instanz-Einstellung (Admin Center → Objects and rules → Tickets → Settings, Abschnitt Attachments); ohne die scheitert Schritt 3 oben.
Am gleichen Ort lohnt ein zweiter Blick, gerade unter dem revidierten Datenschutzgesetz: Mit Secure Downloads verlangt Zendesk eine Anmeldung, bevor ein Anhang angesehen werden kann, und die URLs öffentlicher Anhänge lassen sich mit einer Ablauffrist versehen. Ein Dokument über diesen Kanal liegt dann nicht als dauerhaft offener Link herum; es sitzt hinter der Anmeldung und verfällt nach Frist.
Und die Design-Frage, wenn sich jemand nicht mehr normal einloggen kann: Wie kommt er an dieses eine Ticket? Über einen eng begrenzten Zugang, der nur Anhänge erlaubt und sonst nichts.
Eine Liste zeigt, dass es ein Anliegen gibt. Eine Seite, die den Stand zeigt und einen sicheren Weg zurück öffnet, zeigt, dass jemand dahintersteht. Das ist der Unterschied zwischen einem Portal und einem Ort, an dem man sich ernst genommen fühlt.