-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessage_context.py
More file actions
133 lines (112 loc) Β· 5.59 KB
/
message_context.py
File metadata and controls
133 lines (112 loc) Β· 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python3
"""
Unified Message Context for SimpleX Bot
Handles all message parsing logic in one place to eliminate duplication
"""
import logging
from typing import Dict, Any, Optional
class MessageContext:
"""Unified message context that handles all SimpleX message parsing"""
def __init__(self, raw_message_data: Dict[str, Any]):
self.raw_message_data = raw_message_data
self.logger = logging.getLogger("message_context")
# Parse all data once
self.chat_info = self._extract_chat_info()
self.chat_item = self._extract_chat_item()
self.is_group = self._determine_is_group()
self.contact_name = self._extract_contact_name()
self.chat_id = self._determine_chat_id()
self.message_content = self._extract_message_content()
# Debug logging
self.logger.debug(f"π CONTEXT: is_group={self.is_group}, contact_name='{self.contact_name}', chat_id='{self.chat_id}'")
def _extract_chat_info(self) -> Dict[str, Any]:
"""Extract chat info handling both regular and XFTP event structures"""
# Check for regular message structure
chat_info = self.raw_message_data.get("chatInfo", {})
# Check for XFTP event structure
if not chat_info and "chatItem" in self.raw_message_data:
chat_item = self.raw_message_data["chatItem"]
chat_info = chat_item.get("chatInfo", {})
return chat_info
def _extract_chat_item(self) -> Dict[str, Any]:
"""Extract chat item from message data"""
return self.raw_message_data.get("chatItem", {})
def _determine_is_group(self) -> bool:
"""Determine if this is a group message"""
return "groupInfo" in self.chat_info
def _extract_contact_name(self) -> str:
"""Extract the actual sender's contact name (works for both direct and group messages)"""
try:
if self.is_group:
# For group messages, get the actual sender from groupMember
chat_dir = self.chat_item.get("chatDir", {})
group_member = chat_dir.get("groupMember", {})
if group_member:
contact_name = group_member.get("localDisplayName", "Unknown Member")
self.logger.debug(f"π CONTEXT: Group message from '{contact_name}' via groupMember")
return contact_name
else:
# Fallback: try to get from chat_info (less reliable for groups)
contact_info = self.chat_info.get("contact", {})
contact_name = contact_info.get("localDisplayName", "Unknown Member")
self.logger.debug(f"π CONTEXT: Group message fallback contact '{contact_name}'")
return contact_name
else:
# For direct messages, get from contact info
contact_info = self.chat_info.get("contact", {})
contact_name = contact_info.get("localDisplayName", "Unknown")
self.logger.debug(f"π CONTEXT: Direct message from '{contact_name}'")
return contact_name
except Exception as e:
self.logger.error(f"π CONTEXT: Error extracting contact name: {e}")
return "Unknown"
def _determine_chat_id(self) -> str:
"""Determine the correct chat ID for routing messages"""
try:
if self.is_group:
# Group message - route to group
group_info = self.chat_info.get("groupInfo", {})
chat_id = group_info.get("localDisplayName", group_info.get("groupName", self.contact_name))
self.logger.debug(f"π CONTEXT: Group chat_id='{chat_id}'")
return chat_id
else:
# Direct message - route to contact
self.logger.debug(f"π CONTEXT: Direct chat_id='{self.contact_name}'")
return self.contact_name
except Exception as e:
self.logger.error(f"π CONTEXT: Error determining chat ID: {e}")
# Fallback to contact name
return self.contact_name
def _extract_message_content(self) -> Dict[str, Any]:
"""Extract message content and metadata"""
try:
content = self.chat_item.get("content", {})
msg_content = content.get("msgContent", {})
return {
"type": msg_content.get("type", "unknown"),
"text": msg_content.get("text", ""),
"full_content": content,
"msg_content": msg_content
}
except Exception as e:
self.logger.error(f"π CONTEXT: Error extracting message content: {e}")
return {
"type": "unknown",
"text": "",
"full_content": {},
"msg_content": {}
}
def get_chat_context_string(self) -> str:
"""Get a human-readable context string for logging"""
if self.is_group:
return f"Group '{self.chat_id}' from {self.contact_name}"
else:
return f"DM from {self.contact_name}"
def should_quote_chat_id(self) -> bool:
"""Determine if chat_id needs quoting for SimpleX CLI"""
return self.is_group and ' ' in self.chat_id
def get_quoted_chat_id(self) -> str:
"""Get properly quoted chat_id for SimpleX CLI commands"""
if self.should_quote_chat_id():
return f"'{self.chat_id}'"
return self.chat_id