0d8036fd4a
Custom categories (rights.canDelete=true) have no locale field set by the API and were silently excluded by the locale filter. They now bypass both the locale and taskListType filters so they always appear in get_categories output regardless of the locale parameter. Also: deleted 7 test categories (TEmojiApple, Obst & Gemüse (old), TestKategorie, ProbeKat2, [TEST]emoji=apple, ProbeKat1, TDelMeta) and restored 'Obst & Gemüse' (emoji 🍎) as a clean custom category. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
493 lines
21 KiB
Markdown
493 lines
21 KiB
Markdown
# Family Wall API – Spezifikation
|
||
|
||
Erarbeitet durch Browser-Traffic-Analyse (April 2026).
|
||
Es gibt keine offizielle API-Dokumentation.
|
||
|
||
## Base URL
|
||
https://api.familywall.com/api
|
||
|
||
## Authentifizierung
|
||
|
||
### Login
|
||
POST https://api.familywall.com/api/log2in
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Request-Parameter:**
|
||
|
||
| Parameter | Wert |
|
||
|---|---|
|
||
| `identifier` | E-Mail-Adresse |
|
||
| `password` | Passwort |
|
||
| `type` | nicht senden — wird als `undefined` ignoriert (verifiziert per JS-Analyse) |
|
||
| `clientId` | weglassen |
|
||
| `clientSecret` | weglassen |
|
||
| `generateAutologinToken` | weglassen |
|
||
| `countryCode` | weglassen |
|
||
|
||
**Response (Erfolg):**
|
||
|
||
```json
|
||
{ "a00": { "r": { "r": <SessionObject> }, "cn": "log2in" } }
|
||
```
|
||
|
||
`SessionObject` enthält u.a. `tokenCsrf` und `webApiUrl`.
|
||
`tokenCsrf` ist die Session-ID – identisch zur `JSESSIONID` im Cookie.
|
||
|
||
**Response (Fehler):**
|
||
|
||
```json
|
||
{ "ex": { "ex": <ErrorObject> } }
|
||
{ "un": { "un": <ErrorObject> } }
|
||
```
|
||
|
||
Der Server setzt nach erfolgreichem Login ein Session-Cookie:
|
||
Set-Cookie: JSESSIONID=<session-id> (= tokenCsrf)
|
||
|
||
### Folgecalls (nach Login)
|
||
|
||
Alle API-Calls nach dem Login benötigen:
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Cookie** | `JSESSIONID=<session-id>` |
|
||
| **Header** | `Tokencsrf: <session-id>` (identisch zur JSESSIONID) |
|
||
| **Content-Type** | `application/x-www-form-urlencoded` |
|
||
|
||
### Logout
|
||
POST https://api.familywall.com/api/log2out
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
Keine Parameter. Session wird serverseitig invalidiert.
|
||
|
||
### Session-Strategie
|
||
|
||
Kein Session-Caching. Jeder MCP-Tool-Call führt folgende Sequenz aus:
|
||
|
||
POST /api/log2in → Session-ID
|
||
POST /api/<endpoint> → Nutzdaten
|
||
POST /api/log2out → Session invalidieren
|
||
|
||
|
||
Credentials (E-Mail + Passwort) werden einmalig via `mcp-familywall setup`
|
||
im OS Keyring gespeichert (Keys: `email`, `password`). Kein Keyring-Eintrag
|
||
für `session_id`.
|
||
|
||
## Bekannte Endpoints
|
||
|
||
### `famlistfamily` – Kreise abrufen
|
||
POST https://api.familywall.com/api/famlistfamily
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter:** keine (verifiziert)
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r[] → Kreise
|
||
.metaId → eindeutige Kreis-ID (Format family/<id>)
|
||
.name → Kreisname
|
||
.family_id → numerische Kreis-ID
|
||
.members[] → Mitglieder des Kreises
|
||
.accountId → numerische Account-ID
|
||
.metaId → Mitglieds-ID (Format familymember/<accountId>_<familyId>)
|
||
.firstName → Vorname (Display-Name; bevorzugen gegenüber .name)
|
||
.name → E-Mail-Adresse (Family Wall Default wenn kein Anzeigename)
|
||
.role → Familienrolle (z.B. "Unknown", "Parent", "Child")
|
||
.right → Berechtigung (z.B. "SuperAdmin", "Admin", "Member")
|
||
.color → Profilfarbe als Hex-String (z.B. "#FF8086")
|
||
.medias[0].pictureUrl → Avatar-URL (generierter Default wenn pictureDefault=true)
|
||
.identifiers[] → Kontaktdaten
|
||
.type → Typ (z.B. "Email")
|
||
.value → Wert (z.B. E-Mail-Adresse)
|
||
.familyId → Zugehöriger Kreis (= metaId des Kreises)
|
||
.isloggedaccount → "true" wenn das der angemeldete Account ist
|
||
.joinDate → Beitrittsdatum (ISO 8601)
|
||
.lastLoginDate → Letzter Login (ISO 8601)
|
||
.locale → Spracheinstellung (z.B. "de_DE")
|
||
.timeZone → Zeitzone (z.B. "Europe/Berlin")
|
||
.invitations[] → Offene Einladungen (leer wenn keine)
|
||
.coverUri → Cover-Bild URL
|
||
```
|
||
|
||
### `taskgettasklists` – Listen abrufen
|
||
POST https://api.familywall.com/api/taskgettasklists
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter:** keine
|
||
|
||
**Response-Struktur:** zu verifizieren beim ersten echten Call
|
||
|
||
### `accgetallfamily` – Listen + Tasks abrufen
|
||
POST https://api.familywall.com/api/accgetallfamily
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter:**
|
||
|
||
| Parameter | Wert |
|
||
|---|---|
|
||
| `a01call` | `"taskcategorysync"` |
|
||
| `a02call` | `"tasksync"` |
|
||
|
||
Hinweis: `a03call=tasklistsync` ist **kein gültiger Endpoint** — API antwortet mit
|
||
"The call tasklistsync is not registered". Nicht verwenden.
|
||
`partnerScope`, `a03id`, `withStateBean` werden weggelassen.
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00 → famlistfamily-Daten (Kreise inkl. members[]) – Nebeneffekt
|
||
a01.r.r.updatedCreated[] → taskcategorysync (Kategorien/Abteilungen pro Liste)
|
||
.metaId → Kategorie-ID (Format taskCategory/<familyId>_<sysId>)
|
||
.name → Kategoriename (sprachabhängig, z.B. "Beverages")
|
||
.emoji → Emoji-Symbol der Kategorie
|
||
.systemCategoryId → numerische System-ID (sprach-unabhängig)
|
||
.taskListType → Listentyp der Kategorie (z.B. "SHOPPING_LIST")
|
||
**Wichtig:** Alle 171 Kategorien sind SHOPPING_LIST —
|
||
es gibt keine TODO-Kategorien in der API
|
||
.sortingIndexByTaskList → dict: Listen-ID → Sortierposition
|
||
**Achtung:** enthält ALLE Listen-IDs unabhängig vom Typ
|
||
→ NICHT für Typ-Filterung verwenden!
|
||
Stattdessen: taskListType der Kategorie mit
|
||
taskListType der Liste (aus taskgettasklists) vergleichen
|
||
.locale → Sprache des Namens (z.B. "de", "en", "ru", "fr", "es",
|
||
"it", "nl", "pt", "sv", "ko", "ja")
|
||
Jede Sprache = eigener Eintrag mit eigenem metaId/systemCategoryId
|
||
**Wichtig:** Custom-Kategorien (rights.canDelete='true') haben
|
||
kein locale-Feld gesetzt — sie werden sprachunabhängig
|
||
zurückgegeben und dürfen nie über locale gefiltert werden.
|
||
.hiddenByTaskList → Liste von Listen-IDs, in denen die Kat. versteckt ist
|
||
a02.r.r.updatedCreated[] → tasksync (Tasks)
|
||
.metaId → eindeutige Task-ID
|
||
.taskId → identisch zu metaId (zweiter Alias)
|
||
.text → Aufgabentext
|
||
.description → optionale Beschreibung
|
||
.taskListId → Zugehörigkeit zur Liste
|
||
.complete → "true" / "false" (String, nicht Boolean!)
|
||
.categories[] → Listen-Level-Systemkategorie (z.B. SYS-CAT-SHOPPINGLIST);
|
||
NICHT die spezifische Task-Kategorie — immer identisch
|
||
für alle Tasks einer Liste
|
||
.system → "true" (immer System-Kategorie)
|
||
.name → Listen-Systemkategorien (z.B. "SYS-CAT-SHOPPINGLIST", "SYS-CAT-TODOS")
|
||
.taskCategoryId → spezifische Task-Kategorie (verifiziert): metaId-Format
|
||
(z.B. "taskCategory/23431854_200"), null wenn nicht gesetzt
|
||
.assignee / .assigneeIds → zugewiesene Mitglieder
|
||
.reminder → Erinnerungsdatum (ISO 8601, optional)
|
||
.recurrency → Wiederholungsregel (optional)
|
||
.sortingIndex → Anzeigereihenfolge
|
||
```
|
||
|
||
**Kategorie-Zuweisung bei taskcreate2 / taskupdate2 (verifiziert):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `taskCategoryId` | nein | Kategorie-MetaId aus `get_categories` (z.B. `taskCategory/23431854_200`) |
|
||
|
||
Hinweise:
|
||
- Wert muss das vollständige metaId-Format `taskCategory/<familyId>_<systemCategoryId>` sein.
|
||
Nur der numerische `systemCategoryId`-Teil (z.B. `200`) führt zu API-Fehler
|
||
`"cannot find task category id=200"`.
|
||
- Das `categories[]`-Feld in der Response zeigt immer `SYS-CAT-SHOPPINGLIST`
|
||
(Listen-Level-Systemkategorie, unabhängig vom gesetzten `taskCategoryId`).
|
||
Die tatsächliche Task-Kategorie ist im Feld `taskCategoryId` der Task gespeichert.
|
||
- Nur für Einkaufslisten (`taskListType=SHOPPING_LIST`) relevant;
|
||
TODO-Listen haben keine Kategorien.
|
||
|
||
## Systembezeichnungen für Listen-Namen
|
||
|
||
Bekannte Systembezeichnungen werden deutsch übersetzt:
|
||
|
||
| Systembezeichnung | Deutsch |
|
||
|---|---|
|
||
| `SYS-CAT-SHOPPINGLIST` | `Einkaufsliste` |
|
||
|
||
Unbekannte Bezeichnungen werden unverändert zurückgegeben.
|
||
Mapping-Tabelle bei Bedarf erweitern.
|
||
|
||
### `wallget` – Aktivitäten (Wall) abrufen
|
||
POST https://api.familywall.com/api/wallget
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter:**
|
||
|
||
| Parameter | Wert |
|
||
|---|---|
|
||
| `nb` | Anzahl Einträge (z.B. `"20"`) |
|
||
| `date` | optional, für Paginierung (Datum des letzten Eintrags) |
|
||
| `accountId` | optional |
|
||
| `type` | optional |
|
||
| `nested` | optional |
|
||
| `masterNested` | optional |
|
||
| `sortBy` | optional |
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r[]
|
||
.metaId → ID der Aktivität (= wallMessageId)
|
||
.refType → Aktivitätstyp (z.B. STATUS, FAMILY_CREATED)
|
||
.text → Text (optional, fehlt bei System-Events)
|
||
.creationDate → Datum (ISO 8601)
|
||
.accountId → Autor-ID
|
||
```
|
||
|
||
**Response-Struktur:** zu verifizieren beim ersten echten Call
|
||
|
||
### `wallactivityget` – Einzelne Aktivität abrufen
|
||
POST https://api.familywall.com/api/wallactivityget
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter:**
|
||
|
||
| Parameter | Wert |
|
||
|---|---|
|
||
| `accountId` | optional |
|
||
| `masterNested` | optional |
|
||
|
||
**Response-Struktur:** zu verifizieren beim ersten echten Call
|
||
(Endpoint noch nicht implementiert — für spätere Versionen)
|
||
|
||
## Debug-Logging
|
||
|
||
Wenn die Umgebungsvariable `FW_DEBUG=1` gesetzt ist, loggt `fw_client.py`
|
||
vollständige Request-Bodies und Responses nach stderr. Dient zur Verifikation
|
||
offener Punkte (z.B. `type`-Parameter beim Login, Kreis-Felder in Response).
|
||
|
||
**Wichtig:** Keine Secrets in Debug-Ausgaben (Passwort maskieren).
|
||
|
||
### `taskcreate2` – Task erstellen
|
||
POST https://api.familywall.com/api/taskcreate2
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter (verifiziert):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `taskListId` | ja | Listen-ID aus `get_lists` (z.B. `taskList/123_456`) |
|
||
| `text` | ja | Aufgabentitel |
|
||
| `description` | nein | Optionale Beschreibung |
|
||
| `taskCategoryId` | nein | Kategorie-MetaId aus `get_categories` (z.B. `taskCategory/23431854_200`) |
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r → vollständiges Task-Objekt der neu erstellten Task
|
||
.metaId → eindeutige Task-ID (z.B. "task/23431854_726362809")
|
||
.taskListId → Listen-ID
|
||
.text → Titel
|
||
.complete → "false" (immer, direkt nach Erstellung)
|
||
```
|
||
|
||
### `taskupdate2` – Task aktualisieren
|
||
POST https://api.familywall.com/api/taskupdate2
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter (verifiziert):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `metaId` | ja | Task-ID aus `get_tasks` |
|
||
| `text` | nein | Neuer Titel (mindestens eines der optionalen Felder erforderlich) |
|
||
| `description` | nein | Neue Beschreibung |
|
||
| `taskCategoryId` | nein | Kategorie-MetaId aus `get_categories` (z.B. `taskCategory/23431854_200`) |
|
||
|
||
Hinweis: `taskListId` ist **nicht** erforderlich (verifiziert – Update ohne `taskListId` funktioniert).
|
||
|
||
**Response-Struktur:** kein spezifischer Rückgabewert – Erfolg = kein `ex`/`un`-Key auf Top-Level.
|
||
|
||
### `taskmark` – Task als erledigt/offen markieren
|
||
POST https://api.familywall.com/api/taskmark
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter (verifiziert):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `taskId` | ja | Task-ID aus `get_tasks` (**WICHTIG: `taskId`, nicht `metaId`!**) |
|
||
| `complete` | ja | `"true"` oder `"false"` (String, nicht Boolean!) |
|
||
|
||
**Achtung:** Der Endpoint heißt intern `taskId`, nicht `metaId`.
|
||
Falsche Parameter (`metaId`, `id`, `taskMetaId`) werden serverseitig ignoriert –
|
||
die API antwortet dann mit einem Fehler in `a00.un.un` (nicht Top-Level!),
|
||
der vom Standard-Error-Check im fw_client übersehen wird.
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r → vollständiges Task-Objekt mit aktuellem Stand (inkl. lastAction: "MARK_COMPLETED")
|
||
```
|
||
|
||
### `metadelete` – Objekt löschen
|
||
POST https://api.familywall.com/api/metadelete
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter (verifiziert):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `id` | ja | Task-ID aus `get_tasks` (**WICHTIG: `id`, nicht `metaId`!**) |
|
||
|
||
Hinweis: `metadelete` ist ein generischer Lösch-Endpoint für beliebige Objekte (Tasks, etc.).
|
||
Entsprechend vorsichtig verwenden.
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r → "true" (String)
|
||
```
|
||
|
||
**Fehlerverhalten:** Bei falschem Parameter-Namen (`metaId`, `taskId` etc.) antwortet die API
|
||
mit `{"a00": {"un": {"un": {"message": "missing value in: id"}}}}` auf Top-Level ohne `un`-Key
|
||
→ wird vom fw_client fälschlich als Erfolg interpretiert. Daher ist der korrekte Parameter-Name
|
||
kritisch.
|
||
|
||
### `taskcategoryput` – Kategorie erstellen
|
||
POST https://api.familywall.com/api/taskcategoryput
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter (verifiziert via FW_DEBUG=1):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `name` | ja | Kategorie-Name (beliebiger String) |
|
||
| `emoji` | nein | Icon: Unicode-Emoji-Zeichen (z.B. `🌿`) oder beliebiger String-Code (z.B. `"FOOD"`) — wird as-is gespeichert |
|
||
|
||
Hinweise:
|
||
- Die neue Kategorie wird **allen** Listen der Familie zugeordnet — es gibt keine per-Liste-Einschränkung.
|
||
- Benutzerdefinierte Kategorien haben `systemCategoryId=null` und `rights.canDelete='true'`.
|
||
- System-Kategorien haben `rights.canDelete=null` — API erlaubt Löschen, aber `delete_category` Tool verweigert es.
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r → vollständiges Kategorie-Objekt
|
||
.metaId → neue Kategorie-ID (z.B. "taskCategory/23431854_4956637")
|
||
.name → Kategorie-Name
|
||
.taskListType → "SHOPPING_LIST" (automatisch gesetzt)
|
||
.familyId → Familien-ID
|
||
.accountId → Account-ID des Erstellers
|
||
.rights.canDelete → "true" (custom Kategorien)
|
||
.rights.canUpdate → "true" (custom Kategorien)
|
||
.emoji → gespeicherter Icon-Wert (falls übergeben)
|
||
```
|
||
|
||
**Fehlerverhalten:** Ohne `name`-Parameter:
|
||
```json
|
||
{"a00": {"un": {"un": {"FiZClassId": "502", "message": "cat without a name ..."}}}}
|
||
```
|
||
|
||
### `taskcategorydelete` – Kategorie löschen
|
||
POST https://api.familywall.com/api/taskcategorydelete
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter (verifiziert via FW_DEBUG=1):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `id` | ja | Kategorie-MetaId aus `get_categories` (**WICHTIG: `id`, nicht `metaId`!**) |
|
||
|
||
**Achtung:** Falscher Parameter-Name `metaId` führt zu:
|
||
```json
|
||
{"a00": {"un": {"un": {"FiZClassId": "502", "message": "In request, missing value in : id"}}}}
|
||
```
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r → "true" (String)
|
||
```
|
||
|
||
**Wichtig – System-Kategorien:** Die API erlaubt technisch das Löschen von System-Kategorien
|
||
(`taskCategory/<familyId>_200` etc.), entfernt sie aber nur aus der Familie — nicht global.
|
||
Das `delete_category`-MCP-Tool verweigert dies (Schutz via `rights.canDelete`-Check).
|
||
Erkennung: custom Kategorien haben `rights.canDelete='true'`; System-Kategorien haben `rights.canDelete=null`.
|
||
|
||
### `wallmood` – Wall-Post liken
|
||
POST https://api.familywall.com/api/wallmood
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
**Body-Parameter (verifiziert via FW_DEBUG=1):**
|
||
|
||
| Parameter | Pflicht | Wert |
|
||
|---|---|---|
|
||
| `wall_message_id` | ja | Post-ID aus `get_activities` (z.B. `wall/23431854_31119189`) |
|
||
| `moodType` | ja | `"STAR"` (einziger bekannter Wert — entspricht dem Like-Button in der App) |
|
||
|
||
**Verhalten (verifiziert):**
|
||
- `wallmood` mit `moodType: "STAR"` ist eine **idempotente SET-Operation** — kein Toggle!
|
||
- Mehrfaches Aufrufen mit denselben Parametern hinterlässt denselben Zustand
|
||
- `moodType: "LIKE"` wurde serverseitig als `"STAR"` gespeichert → korrekter Wert ist `"STAR"`
|
||
- Nur für Post-Typ `STATUS` wirksam; `FAMILY_CREATED` und vermutlich System-Posts ignorieren den Call
|
||
|
||
**Unlike – nicht implementierbar (Stand: April 2026):**
|
||
|
||
Ausgiebig getestete Ansätze, die alle fehlschlugen:
|
||
|
||
| Ansatz | Ergebnis |
|
||
|---|---|
|
||
| `moodType: "NONE"` / `"REMOVE"` / `"DELETE"` / `""` | moodMap unverändert |
|
||
| `moodType` ganz weglassen | moodMap unverändert |
|
||
| `moodStarShortcut: "false"` als Parameter | moodMap unverändert |
|
||
| Alternative Endpoints: `wallmooddelete`, `wallmoodremove`, `wallmoodelete`, `wallunmood`, `wallcommentdelete`, `wallmoodstar`, `wallstar`, `wallreact`, `wallreactdelete` | alle: `"The call X is not registered"` (502) |
|
||
| `metadelete` auf Mood-Comment-ID | löscht den Comment, aber `moodStarShortcut` bleibt gesetzt |
|
||
|
||
Die Web-App nutzt einen Service Worker, der Requests abfängt — der echte Unlike-Payload
|
||
ist dadurch nicht per Browser-DevTools inspizierbar. Unlike bleibt bis zur weiteren
|
||
Analyse nicht unterstützt.
|
||
|
||
**Response-Struktur (verifiziert):**
|
||
```
|
||
a00.r.r → vollständiges Wall-Message-Objekt
|
||
.metaId → Post-ID (= wallMessageId)
|
||
.wallMessageId → Post-ID (identisch zu metaId)
|
||
.refType → Aktivitätstyp (z.B. "STATUS")
|
||
.refAction → Letzte Aktion (z.B. "MOOD_STAR")
|
||
.text → Post-Text
|
||
.postAccountId → Account-ID des Post-Autors
|
||
.accountId → Account-ID (identisch)
|
||
.moodMap → dict: accountId → ["STAR"] wenn geliked
|
||
.moodStarShortcut → "true" wenn Like-Shortcut aktiv
|
||
.comments[] → Liste von Kommentaren/Moods
|
||
.commentId → Kommentar-ID (Format wallComment/...)
|
||
.accountId → Account-ID des Kommentators
|
||
.mood → Mood-Typ (z.B. "STAR")
|
||
.text → Kommentartext (falls vorhanden)
|
||
.creationDate → Erstelldatum (ISO 8601)
|
||
.creationDate → Erstelldatum des Posts (ISO 8601)
|
||
.modifDate → Letztes Änderungsdatum (ISO 8601)
|
||
.familyId → Kreis-ID (Format family/...)
|
||
.rights.canUpdate → "true"/"false"
|
||
.rights.canDelete → "true"/"false"
|
||
```
|
||
|
||
**Like-Zustand bestimmen (zwei Indikatoren, beide auswerten):**
|
||
|
||
| Feld | Typ | Bedeutung |
|
||
|---|---|---|
|
||
| `moodStarShortcut` | `"true"` / `"false"` | Primär: direktes User-Like-Flag für den anfragenden Account |
|
||
| `moodMap[accountId]` | `["STAR"]` | Sekundär: accountId → Mood-Liste; enthält `"STAR"` wenn geliked |
|
||
|
||
Beide Indikatoren können den Like-Zustand korrekt abbilden — je nach API-internem
|
||
Speicherpfad ist nur einer gesetzt. Immer beide prüfen.
|
||
|
||
**Silent-Fail-Szenarien (API antwortet 200, aber Like wird nicht gesetzt):**
|
||
- **Self-Like-Restriction**: Eigener Post kann nicht geliked werden
|
||
(verifiziert: Account 23431898 kann Post `wall/23431854_31119189` nicht liken,
|
||
obwohl API regulär antwortet — `modifDate` bleibt eingefroren)
|
||
- **Unsupported Post-Typ**: `FAMILY_CREATED`-Posts ignorieren wallmood-Calls
|
||
- **Rate-Limit**: Nach vielen Calls kann die API Still-Fails zurückgeben
|
||
|
||
Erkennungsmerkmal für Silent-Fail: `modifDate` im Response identisch zum Vorherigen
|
||
AND `moodStarShortcut: false` AND `moodMap: {}`.
|
||
|
||
## Noch zu verifizieren
|
||
|
||
- ~~Exakter Wert für `type`-Parameter beim Login~~ → nicht senden (verifiziert per JS-Analyse)
|
||
- ~~Response-Struktur von `famlistfamily` (Kreise)~~ → a00.r.r[], metaId + name (verifiziert)
|
||
- ~~Ob `a03call=tasklistsync` benötigt wird~~ → **nein**, kein gültiger Endpoint (verifiziert)
|
||
- Listen-IDs aus `a01.r.r.updatedCreated[].sortingIndexByTaskList`-Keys (verifiziert)
|
||
- Listen-Namen und Zähler (remainingTaskNumber, totalTaskNumber) → noch unbekannt
|
||
- Kreis-Zuordnung in `accgetallfamily`-Response → noch offen
|
||
- ~~Ob `partnerScope` / `withStateBean` benötigt werden~~ → nein (verifiziert)
|
||
- Session-Lebensdauer (irrelevant da kein Caching)
|
||
- ~~`taskcreate2`: Response-Struktur~~ → `a00.r.r` = vollständiges Task-Objekt (verifiziert)
|
||
- ~~`taskupdate2`: ob `taskListId` Pflichtfeld ist~~ → **nein**, nicht erforderlich (verifiziert)
|
||
- ~~`taskmark`: korrekter Parameter-Name~~ → **`taskId`** (nicht `metaId`!) (verifiziert)
|
||
- ~~`metadelete`: korrekter Parameter-Name + Response-Struktur~~ → **`id`**, Response `"true"` (verifiziert)
|
||
- ~~`wallmood`: Parameter-Name `wallId`~~ → **`wall_message_id`** (verifiziert via API-Fehlermeldung)
|
||
- ~~`wallmood`: `moodType`-Werte, Toggle vs. explizit, Response-Struktur~~ → verifiziert: idempotentes SET mit `"STAR"`, kein Toggle (siehe oben)
|
||
- `wallmood` Unlike: Mechanismus unbekannt — Service Worker verhindert Browser-Inspektion; alle getesteten Ansätze fehlgeschlagen (siehe oben)
|
||
- ~~`taskcreate2` / `taskupdate2`: Kategorie-Paramter-Name~~ → **`taskCategoryId`**, Wert = vollständige metaId (verifiziert)
|
||
- ~~`taskcategoryput`: Body-Parameter, Response-Struktur~~ → `name` (Pflicht), `emoji` (optional), Response = neues Kategorie-Objekt (verifiziert)
|
||
- ~~`taskcategorydelete`: Body-Parameter~~ → **`id`** (nicht `metaId`!), Response = `"true"` (verifiziert) |