22"""Main Bot module.
33"""
44from datetime import datetime , timedelta
5- from typing import NoReturn , List , Dict , Any
5+ from typing import NoReturn , List , Dict , Any , Optional
6+ import threading
7+ import time
68
79from saya import Vk
810import requests
911
1012from modules import (
1113 BetterBotBaseDataService , Commands
1214)
15+ from modules .rules_service import RulesService
1316from tokens import BOT_TOKEN
1417from userbot import UserBot
1518import patterns
@@ -38,7 +41,8 @@ def __init__(
3841 self .messages_to_delete = {}
3942 self .userbot = UserBot ()
4043 self .data = BetterBotBaseDataService ()
41- self .commands = Commands (self , self .data )
44+ self .rules_service = RulesService ()
45+ self .commands = Commands (self , self .data , self .rules_service )
4246 self .commands .register_cmds (
4347 (patterns .HELP , self .commands .help_message ),
4448 (patterns .INFO , self .commands .info_message ),
@@ -63,8 +67,15 @@ def __init__(
6367 (patterns .WHAT_IS , self .commands .what_is ),
6468 (patterns .WHAT_MEAN , self .commands .what_is ),
6569 (patterns .APPLY_KARMA , self .commands .apply_karma ),
66- (patterns .GITHUB_COPILOT , self .commands .github_copilot )
70+ (patterns .GITHUB_COPILOT , self .commands .github_copilot ),
71+ (patterns .SET_RULES_GIST , self .commands .set_rules_gist ),
72+ (patterns .REMOVE_RULES_GIST , self .commands .remove_rules_gist ),
73+ (patterns .GET_RULES_STATUS , self .commands .get_rules_status )
6774 )
75+
76+ # Start rules monitoring thread
77+ self .rules_monitor_thread = threading .Thread (target = self ._monitor_rules , daemon = True )
78+ self .rules_monitor_thread .start ()
6879
6980 def message_new (
7081 self ,
@@ -167,6 +178,83 @@ def send_msg(
167178 dict (
168179 message = msg , peer_id = peer_id ,
169180 disable_mentions = 1 , random_id = 0 ))
181+
182+ def pin_message (
183+ self ,
184+ peer_id : int ,
185+ message_id : int
186+ ) -> dict :
187+ """Pin a message in chat
188+
189+ :param peer_id: chat ID
190+ :param message_id: message ID to pin
191+ """
192+ return self .call_method (
193+ 'messages.pin' ,
194+ dict (peer_id = peer_id , message_id = message_id ))
195+
196+ def unpin_message (
197+ self ,
198+ peer_id : int ,
199+ message_id : int
200+ ) -> dict :
201+ """Unpin a message in chat
202+
203+ :param peer_id: chat ID
204+ :param message_id: message ID to unpin
205+ """
206+ return self .call_method (
207+ 'messages.unpin' ,
208+ dict (peer_id = peer_id , message_id = message_id ))
209+
210+ def send_and_pin_message (
211+ self ,
212+ msg : str ,
213+ peer_id : int
214+ ) -> Optional [int ]:
215+ """Send a message and pin it
216+
217+ :param msg: message text
218+ :param peer_id: chat ID
219+ :return: message ID if successful, None otherwise
220+ """
221+ try :
222+ # Send message
223+ response = self .call_method (
224+ 'messages.send' ,
225+ dict (
226+ message = msg , peer_id = peer_id ,
227+ disable_mentions = 1 , random_id = 0 ))
228+
229+ if 'response' in response :
230+ message_id = response ['response' ]
231+ # Pin the message
232+ pin_response = self .pin_message (peer_id , message_id )
233+ if 'response' in pin_response :
234+ return message_id
235+ return None
236+ except Exception as e :
237+ print (f"Error sending and pinning message: { e } " )
238+ return None
239+
240+ def edit_message (
241+ self ,
242+ peer_id : int ,
243+ message_id : int ,
244+ message : str
245+ ) -> dict :
246+ """Edit a message
247+
248+ :param peer_id: chat ID
249+ :param message_id: message ID to edit
250+ :param message: new message text
251+ """
252+ return self .call_method (
253+ 'messages.edit' ,
254+ dict (
255+ peer_id = peer_id ,
256+ message_id = message_id ,
257+ message = message ))
170258
171259 def get_user_name (
172260 self ,
@@ -197,6 +285,69 @@ def get_messages(
197285 """
198286 reply_message = event .get ("reply_message" , {})
199287 return [reply_message ] if reply_message else event .get ("fwd_messages" , [])
288+
289+ def _monitor_rules (self ) -> NoReturn :
290+ """Background thread to monitor rules changes"""
291+ while True :
292+ try :
293+ # Check every 5 minutes
294+ time .sleep (300 )
295+
296+ # Get all monitored chats
297+ monitored_chats = self .rules_service .get_all_monitored_chats ()
298+
299+ for peer_id_str , config in monitored_chats .items ():
300+ peer_id = int (peer_id_str )
301+
302+ # Check for updates
303+ updated_content = self .rules_service .check_gist_updates (peer_id )
304+
305+ if updated_content :
306+ # Rules have been updated
307+ new_rules_message = f"📋 Правила чата:\n \n { updated_content } "
308+
309+ # Try to edit existing pinned message
310+ pinned_message_id = config .get ("pinned_message_id" )
311+
312+ if pinned_message_id :
313+ try :
314+ # Try to edit the existing pinned message
315+ edit_response = self .edit_message (
316+ peer_id , pinned_message_id , new_rules_message )
317+
318+ if 'response' in edit_response :
319+ # Successfully edited
320+ self .send_msg (
321+ "🔄 Правила чата обновлены в закрепленном сообщении!" ,
322+ peer_id )
323+ else :
324+ # Failed to edit, create new pinned message
325+ self ._create_new_pinned_rules (peer_id , new_rules_message )
326+ except Exception as e :
327+ print (f"Error editing pinned message: { e } " )
328+ self ._create_new_pinned_rules (peer_id , new_rules_message )
329+ else :
330+ # No existing pinned message, create new one
331+ self ._create_new_pinned_rules (peer_id , new_rules_message )
332+
333+ except Exception as e :
334+ print (f"Error in rules monitoring: { e } " )
335+
336+ def _create_new_pinned_rules (self , peer_id : int , rules_message : str ) -> NoReturn :
337+ """Helper method to create and pin new rules message"""
338+ try :
339+ message_id = self .send_and_pin_message (rules_message , peer_id )
340+ if message_id :
341+ self .rules_service .update_pinned_message_id (peer_id , message_id )
342+ self .send_msg (
343+ "🔄 Правила чата обновлены и закреплено новое сообщение!" ,
344+ peer_id )
345+ else :
346+ self .send_msg (
347+ "🔄 Правила чата обновлены, но не удалось закрепить сообщение." ,
348+ peer_id )
349+ except Exception as e :
350+ print (f"Error creating new pinned rules: { e } " )
200351
201352
202353if __name__ == '__main__' :
0 commit comments