Skip to content

Commit 9d3754f

Browse files
konardclaude
andcommitted
Implement message logging from main chat to logging chat
- Add configuration options for main chats and logging chat in config.py - Implement message forwarding functionality in Bot._forward_message_to_logging_chat() - Add chat title resolution for better log formatting - Include comprehensive message metadata (timestamp, user, attachments, etc.) - Add safety checks to prevent infinite loops and handle errors gracefully - Add documentation for configuration and usage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 57699d5 commit 9d3754f

File tree

3 files changed

+183
-0
lines changed

3 files changed

+183
-0
lines changed

python/MESSAGE_LOGGING.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Message Logging Feature
2+
3+
This feature allows the bot to forward all messages from specified main chats to a dedicated logging chat for monitoring and archival purposes.
4+
5+
## Configuration
6+
7+
To enable message logging, edit `config.py` and configure the following variables:
8+
9+
### MAIN_CHATS
10+
List of chat IDs from which messages should be forwarded to the logging chat.
11+
12+
```python
13+
MAIN_CHATS = [
14+
2000000001, # Example main chat ID
15+
2000000011 # Another main chat ID
16+
]
17+
```
18+
19+
### LOGGING_CHAT_ID
20+
The chat ID where all messages from main chats will be forwarded for logging.
21+
22+
```python
23+
LOGGING_CHAT_ID = 2000000020 # Example logging chat ID
24+
```
25+
26+
## How to Find Chat IDs
27+
28+
1. Go to the VK conversation you want to use
29+
2. Look at the URL in your browser address bar
30+
3. For group chats, the URL will look like: `https://vk.com/im?peers=c477`
31+
4. The chat ID is `2000000000 + 477 = 2000000477`
32+
33+
## Message Format
34+
35+
Messages forwarded to the logging chat include:
36+
37+
- **Timestamp**: When the original message was sent
38+
- **Chat title**: Name of the source chat
39+
- **User name**: Who sent the message
40+
- **Message content**: The actual message text
41+
- **Attachments**: List of attachment types (if any)
42+
- **Special indicators**: For forwarded messages and replies
43+
44+
Example logged message:
45+
```
46+
[2024-01-01 12:30:45] Development Chat
47+
John Doe: Hello, how is everyone doing?
48+
Attachments: [photo], [doc]
49+
[Reply to message]
50+
```
51+
52+
## Features
53+
54+
### What Gets Logged
55+
- All text messages from configured main chats
56+
- Information about attachments (type only, not content)
57+
- Indication of forwarded messages
58+
- Indication of replies to other messages
59+
- User names and chat titles for context
60+
61+
### What Doesn't Get Logged
62+
- Messages from non-main chats
63+
- Bot messages (to avoid infinite loops)
64+
- Messages when logging is disabled or misconfigured
65+
- Actual attachment content (for privacy and performance)
66+
67+
### Error Handling
68+
- If logging fails for any reason, an error is printed to console
69+
- The bot continues to function normally even if logging fails
70+
- Invalid configurations are silently ignored
71+
72+
## Security Considerations
73+
74+
- The logging chat should have restricted access
75+
- Only trusted administrators should have access to logged messages
76+
- Consider the privacy implications of logging all messages
77+
- Ensure the logging chat is properly secured against unauthorized access
78+
79+
## Disabling Logging
80+
81+
To disable logging, set either:
82+
- `LOGGING_CHAT_ID = None`
83+
- `MAIN_CHATS = []`
84+
85+
The bot will automatically skip logging when these are not properly configured.

python/__main__.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ def message_new(
7878
from_id = event["from_id"]
7979
msg_id = event["conversation_message_id"]
8080

81+
# Forward messages from main chats to logging chat
82+
self._forward_message_to_logging_chat(event, peer_id, from_id)
83+
8184
if peer_id in self.messages_to_delete:
8285
peer = CHAT_ID_OFFSET + config.USERBOT_CHATS[peer_id]
8386
new_messages_to_delete = []
@@ -189,6 +192,91 @@ def get_user_name(
189192
'users.get', dict(user_ids=uid, name_case=name_case)
190193
)['response'][0]["first_name"]
191194

195+
def _forward_message_to_logging_chat(
196+
self,
197+
event: Dict[str, Any],
198+
peer_id: int,
199+
from_id: int
200+
) -> NoReturn:
201+
"""Forwards messages from main chats to logging chat.
202+
203+
:param event: message event data
204+
:param peer_id: chat ID where the message was sent
205+
:param from_id: user ID who sent the message
206+
"""
207+
# Check if logging is enabled and configured
208+
if not config.LOGGING_CHAT_ID or not config.MAIN_CHATS:
209+
return
210+
211+
# Only forward messages from specified main chats
212+
if peer_id not in config.MAIN_CHATS:
213+
return
214+
215+
# Don't forward our own messages to avoid loops
216+
if from_id < 0: # Negative from_id means it's from a group/bot
217+
return
218+
219+
try:
220+
# Get user name for better logging format
221+
user_name = self.get_user_name(from_id) if from_id > 0 else "Unknown"
222+
223+
# Format the original message with metadata
224+
original_text = event.get("text", "")
225+
chat_title = self._get_chat_title(peer_id)
226+
timestamp = datetime.fromtimestamp(event.get("date", 0)).strftime("%Y-%m-%d %H:%M:%S")
227+
228+
# Create formatted log message
229+
log_message = f"[{timestamp}] {chat_title}\n{user_name}: {original_text}"
230+
231+
# Handle attachments
232+
attachments = event.get("attachments", [])
233+
if attachments:
234+
attachment_info = []
235+
for attachment in attachments:
236+
att_type = attachment.get("type", "unknown")
237+
attachment_info.append(f"[{att_type}]")
238+
if attachment_info:
239+
log_message += f"\nAttachments: {', '.join(attachment_info)}"
240+
241+
# Handle forwarded messages
242+
fwd_messages = event.get("fwd_messages", [])
243+
if fwd_messages:
244+
log_message += f"\n[Forwarded {len(fwd_messages)} message(s)]"
245+
246+
# Handle reply to message
247+
reply_message = event.get("reply_message", {})
248+
if reply_message:
249+
log_message += "\n[Reply to message]"
250+
251+
# Send to logging chat
252+
self.send_msg(log_message, config.LOGGING_CHAT_ID)
253+
254+
except Exception as e:
255+
print(f"Error forwarding message to logging chat: {e}")
256+
257+
def _get_chat_title(self, peer_id: int) -> str:
258+
"""Get chat title for better logging format.
259+
260+
:param peer_id: chat ID
261+
:return: chat title or formatted chat ID
262+
"""
263+
try:
264+
# For group chats (peer_id > 2000000000), try to get conversation info
265+
if peer_id > 2000000000:
266+
response = self.call_method(
267+
'messages.getConversationsById',
268+
{'peer_ids': peer_id}
269+
)
270+
if 'response' in response and 'items' in response['response']:
271+
items = response['response']['items']
272+
if items:
273+
chat_settings = items[0].get('chat_settings', {})
274+
title = chat_settings.get('title', f'Chat {peer_id}')
275+
return title
276+
return f'Chat {peer_id}'
277+
except Exception:
278+
return f'Chat {peer_id}'
279+
192280
@staticmethod
193281
def get_messages(
194282
event: Dict[str, Any]

python/config.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@
2727
2000000011
2828
]
2929

30+
# Message logging configuration
31+
# Main chats that should have their messages forwarded to logging chat
32+
MAIN_CHATS = [
33+
# 2000000001, # Add your main chat IDs here
34+
# 2000000011
35+
]
36+
37+
# Chat ID where all messages from main chats will be forwarded for logging
38+
LOGGING_CHAT_ID = None # Set this to your logging chat ID (e.g., 2000000020)
39+
3040
POSITIVE_VOTES_PER_KARMA = 2
3141
NEGATIVE_VOTES_PER_KARMA = 3
3242

0 commit comments

Comments
 (0)