fix: use moodType=STAR for wallmood, parse moodMap from response (v0.4.4)

FW_DEBUG=1 verification revealed:
- moodType "LIKE" was silently mapped to "STAR" server-side; use "STAR" directly
- Response a00.r.r contains full wall object with moodMap showing actual like state
- liked status now derived from moodMap rather than echoing the input bool
- SPEC.md updated with fully verified wallmood endpoint details

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-15 15:48:54 +02:00
parent 9534658472
commit a3274b349a
4 changed files with 55 additions and 26 deletions
+19 -13
View File
@@ -487,15 +487,16 @@ def like_post(post_id: str, like: bool = True) -> str:
Returns:
JSON success indicator or an error message.
"""
# wallmood is a toggle endpoint — same endpoint for like and unlike.
# The 'like' parameter controls the intended state; since the endpoint
# toggles server-side state, it is sent as 'moodType' to allow the server
# to differentiate.
# Verified: correct parameter name is 'wall_message_id' (API error message confirmed).
# 'moodType' values ("LIKE" / "NONE") still to be confirmed via FW_DEBUG=1.
# wallmood toggles the STAR mood on a wall post (same endpoint for like/unlike).
# Verified via FW_DEBUG=1:
# - Parameter 'wall_message_id': post ID as returned by get_activities
# - Parameter 'moodType': "STAR" (Family Wall's internal like type)
# - Response a00.r.r: full wall message object with moodMap showing current state
# The endpoint is a toggle — calling it again removes the mood.
# 'like=False' relies on this toggle behaviour (call again to undo).
params: dict[str, Any] = {
"wall_message_id": post_id,
"moodType": "LIKE" if like else "NONE",
"moodType": "STAR",
}
try:
@@ -503,12 +504,13 @@ def like_post(post_id: str, like: bool = True) -> str:
except RuntimeError as exc:
return f"Error: {exc}"
# The response structure is not yet fully verified — return raw JSON
# if the expected shape is absent so the caller can inspect it.
# Extract moodMap from response to determine actual resulting state.
try:
result_data = data["a00"]["r"]["r"]
if result_data is None:
raise KeyError("empty result")
wall_obj = data["a00"]["r"]["r"]
if not isinstance(wall_obj, dict):
raise TypeError("a00.r.r is not a dict")
mood_map: dict[str, Any] = wall_obj.get("moodMap") or {}
account_id: str = wall_obj.get("postAccountId", "")
except (KeyError, TypeError):
return json.dumps(
{"warning": "Unexpected wallmood response structure", "raw": data},
@@ -516,8 +518,12 @@ def like_post(post_id: str, like: bool = True) -> str:
indent=2,
)
# Determine whether the post is now liked by checking if any entry in
# moodMap contains "STAR" (the server-side representation of a like).
now_liked = any("STAR" in moods for moods in mood_map.values())
return json.dumps(
{"liked": like, "id": post_id},
{"liked": now_liked, "id": post_id, "author": account_id},
ensure_ascii=False,
indent=2,
)