feat(bot): refactor webhook parsing for better structure

- Updated webhook parsing to align with the latest Nextcloud Talk Bot format.
- Improved handling of actor, message, and conversation data for clarity and flexibility.
- Added robust JSON decoding with fallback for content extraction.
This commit is contained in:
Harald Hoyer 2026-02-03 16:29:10 +01:00
parent 77cf4a0aed
commit 1f61a0d1ec

View file

@ -214,28 +214,38 @@ async def handle_webhook(
log.info(f"Received webhook: {json.dumps(data, indent=2)[:500]}")
# Extract message info
# Nextcloud Talk Bot API structure
# Extract message info - Nextcloud Talk Bot webhook format
actor = data.get("actor", {})
actor_id = actor.get("id", "")
actor_type = actor.get("type", "")
actor_id_full = actor.get("id", "") # e.g., "users/harald"
message_data = data.get("message", {})
message_text = message_data.get("message", "")
message_id = message_data.get("id")
# Extract username from "users/username" format
if "/" in actor_id_full:
actor_id = actor_id_full.split("/", 1)[1]
else:
actor_id = actor_id_full
conversation = data.get("conversation", {})
conversation_token = conversation.get("token", "")
conversation_type = conversation.get("type", 0)
# Message is in object.content as JSON string
obj = data.get("object", {})
message_id = obj.get("id")
content_str = obj.get("content", "{}")
try:
content = json.loads(content_str)
message_text = content.get("message", "")
except json.JSONDecodeError:
message_text = content_str
# Only respond to user messages
if actor_type != "users":
# Conversation info is in target
target = data.get("target", {})
conversation_token = target.get("id", "")
# Only respond to user/person messages
if actor_type not in ("users", "Person"):
log.info(f"Ignoring non-user actor: {actor_type}")
return JSONResponse({"status": "ignored", "reason": "not a user message"})
# For group chats (type 2, 3, 4), only respond if bot is mentioned
# Type 1 = one-to-one, Type 2 = group, Type 3 = public, Type 4 = changelog
is_direct_message = conversation_type == 1
# For now, treat all conversations the same (respond to mentions)
is_direct_message = False # We can't easily determine this from the webhook
# Check for bot mention in message (Nextcloud uses @"Bot Name" format)
bot_mentioned = False