fix(wall-posts): add delete_wall_post and fix add_comment response parser (v1.3.1)

- Fix add_comment response parser: corrected to a00.r.r.comment.commentId structure
- Fix add_comment error handling: return errors directly instead of warnings
- Add delete_wall_post: permanently delete wall posts via metadelete endpoint
- Add delete_wall_post to README.md Wall & Activities section
- Update SPEC.md with correct walladdComment response structure
- Update SPEC.md metadelete to include wall posts as supported type
- Update CHANGELOG.md with v1.3.1 bugfixes and additions
- Version bumped to 1.3.1 in pyproject.toml

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 23:25:45 +02:00
parent 0e7c4da362
commit 35cbfd3061
5 changed files with 77 additions and 17 deletions
+55 -12
View File
@@ -2042,9 +2042,8 @@ def get_wall_posts(limit: int = 20) -> str:
raw_author: str = item.get("accountId", "")
mood_map: dict[str, Any] = item.get("moodMap") or {}
liked_by_me = (
item.get("moodStarShortcut") == "true"
or any("STAR" in moods for moods in mood_map.values())
liked_by_me = item.get("moodStarShortcut") == "true" or any(
"STAR" in moods for moods in mood_map.values()
)
like_count = sum(len(moods) for moods in mood_map.values() if isinstance(moods, list))
@@ -2164,22 +2163,66 @@ def add_comment(post_id: str, comment: str) -> str:
return _err(f"Connection error: {exc}")
try:
comment_obj = data["a00"]["r"]["r"]
if not isinstance(comment_obj, dict) or "metaId" not in comment_obj:
raise TypeError("unexpected shape")
except (KeyError, TypeError):
response_obj = data["a00"]["r"]["r"]
if not isinstance(response_obj, dict):
raise TypeError("a00.r.r is not a dict")
comment_obj = response_obj.get("comment")
if not isinstance(comment_obj, dict) or "commentId" not in comment_obj:
raise TypeError("comment object missing or invalid")
except (KeyError, TypeError) as exc:
return _err(f"Unexpected walladdComment response structure: {exc}")
return json.dumps(
{
"created": True,
"id": comment_obj.get("commentId"),
"post_id": post_id,
"text": comment_obj.get("text"),
"date": comment_obj.get("creationDate"),
},
ensure_ascii=False,
indent=2,
)
# ---------------------------------------------------------------------------
# Tool: delete_wall_post
# ---------------------------------------------------------------------------
@mcp.tool()
def delete_wall_post(post_id: str) -> str:
"""Permanently delete a wall post.
IMPORTANT: Ask the user for confirmation before calling this tool.
Args:
post_id: Wall post metaId from get_wall_posts
(e.g. ``"wall/16282169_31146617"``).
Returns:
JSON success indicator or an error message.
"""
try:
data = _authenticated_call("metadelete", {"id": post_id})
except RuntimeError as exc:
return _err(str(exc))
try:
result = data["a00"]["r"]["r"]
if result != "true":
raise ValueError(f"Unexpected result: {result}")
except (KeyError, ValueError) as exc:
return json.dumps(
{"warning": "Unexpected walladdComment response structure", "raw": data},
{"warning": "Unexpected metadelete response structure", "error": str(exc), "raw": data},
ensure_ascii=False,
indent=2,
)
return json.dumps(
{
"id": comment_obj.get("metaId"),
"post_id": post_id,
"text": comment_obj.get("text") or comment_obj.get("comment"),
"date": comment_obj.get("creationDate"),
"deleted": True,
"id": post_id,
},
ensure_ascii=False,
indent=2,