diff --git a/python/README.md b/python/README.md index a50c2d69..2090c82d 100644 --- a/python/README.md +++ b/python/README.md @@ -162,6 +162,38 @@ Если нужного языка нет в списке, о его добавлении можно попросить [здесь](https://github.com/linksplatform/Bot/issues/15) +## Friend Request Auto-Acceptance + +Бот автоматически принимает заявки в друзья при наличии пользовательского токена (`USER_TOKEN`). Эта функция работает в фоновом режиме и проверяет новые заявки в друзья каждые 30 секунд по умолчанию. + +### Настройка + +1. Установите `USER_TOKEN` в файле `tokens.py` (см. раздел Configure ниже) +2. Убедитесь что в `config.py` установлено `FRIEND_REQUEST_AUTO_ACCEPT = True` (по умолчанию включено) +3. При необходимости измените `FRIEND_REQUEST_CHECK_INTERVAL` в `config.py` для изменения интервала проверки + +### Тестирование + +Для тестирования функциональности выполните: +```bash +cd python +python3 test_friend_requests.py +``` + +Эта команда проверит: +- Настройку пользовательского токена +- Получение списка заявок в друзья +- Автоматическое принятие заявок +- Работу мониторинга в фоновом режиме + +### Логи + +При запуске бота будут выводиться сообщения о: +- Запуске мониторинга заявок в друзья +- Количестве найденных заявок +- Успешном принятии заявок +- Ошибках при работе с API VK + ## Prerequisites * [Git](https://git-scm.com/downloads) * [Python 3](https://www.python.org/downloads) diff --git a/python/__main__.py b/python/__main__.py index cdcbf7f6..18fdf2e1 100644 --- a/python/__main__.py +++ b/python/__main__.py @@ -201,4 +201,12 @@ def get_messages( if __name__ == '__main__': vk = Bot(token=BOT_TOKEN, group_id=config.BOT_GROUP_ID, debug=True) + + # Start friend request monitoring if enabled and USER_TOKEN is available + if config.FRIEND_REQUEST_AUTO_ACCEPT: + print("Starting VK Bot with friend request auto-acceptance") + vk.userbot.start_friend_request_monitor(check_interval=config.FRIEND_REQUEST_CHECK_INTERVAL) + else: + print("Friend request auto-acceptance is disabled") + vk.start_listen() diff --git a/python/config.py b/python/config.py index 1613aec9..5d81ed85 100644 --- a/python/config.py +++ b/python/config.py @@ -153,5 +153,9 @@ GITHUB_COPILOT_RUN_COMMAND = 'bash -c "./copilot.sh {input_file} {output_file}"' GITHUB_COPILOT_TIMEOUT = 120 # seconds +# Friend request auto-acceptance settings +FRIEND_REQUEST_AUTO_ACCEPT = True # Enable/disable automatic friend request acceptance +FRIEND_REQUEST_CHECK_INTERVAL = 30 # Check interval in seconds (default: 30) + DEFAULT_PROGRAMMING_LANGUAGES_PATTERN_STRING = "|".join(DEFAULT_PROGRAMMING_LANGUAGES) GITHUB_COPILOT_LANGUAGES_PATTERN_STRING = "|".join([i for i in GITHUB_COPILOT_LANGUAGES.keys()]) diff --git a/python/test_friend_requests.py b/python/test_friend_requests.py new file mode 100755 index 00000000..3c864cc0 --- /dev/null +++ b/python/test_friend_requests.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""Test script for friend request auto-acceptance functionality. +""" + +from userbot import UserBot +from tokens import USER_TOKEN +import time +import sys + +def main(): + """Test the friend request functionality.""" + print("VK User Bot - Friend Request Test") + print("=" * 40) + + # Check if USER_TOKEN is configured + if not USER_TOKEN: + print("ERROR: USER_TOKEN is not set in tokens.py") + print("Please configure your VK user token to test friend request functionality.") + print("You can get a user token from:") + print("https://oauth.vk.com/authorize?client_id=2685278&scope=1073737727&redirect_uri=https://api.vk.com/blank.html&display=page&response_type=token&revoke=1") + sys.exit(1) + + userbot = UserBot() + + print("1. Testing friend request retrieval...") + pending_requests = userbot.get_friend_requests() + + if pending_requests is None: + print("ERROR: Failed to retrieve friend requests (check token permissions)") + return + elif pending_requests == []: + print("✓ No pending friend requests found") + else: + print(f"✓ Found {len(pending_requests)} pending friend request(s): {pending_requests}") + + print("\n2. Testing manual check and accept...") + userbot.check_and_accept_friend_requests() + + print("\n3. Testing monitoring functionality...") + print("Starting friend request monitor for 30 seconds (check interval: 10 seconds)") + + userbot.start_friend_request_monitor(check_interval=10) + + try: + # Let it run for 30 seconds + time.sleep(30) + except KeyboardInterrupt: + print("\nInterrupted by user") + + print("\nStopping friend request monitor...") + userbot.stop_friend_request_monitor() + + print("\n✓ Test completed successfully!") + print("\nTo enable friend request auto-acceptance in the main bot:") + print("1. Set USER_TOKEN in tokens.py") + print("2. Set FRIEND_REQUEST_AUTO_ACCEPT = True in config.py") + print("3. Run the bot with: python3 __main__.py") + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/python/userbot.py b/python/userbot.py index 74f7bd5d..733b296d 100644 --- a/python/userbot.py +++ b/python/userbot.py @@ -2,6 +2,8 @@ """Provides working with VK API as user. """ from typing import NoReturn, List, Dict, Any +import time +import threading from exceptions import TooManyMessagesError from tokens import USER_TOKEN @@ -9,11 +11,15 @@ class UserBot: - """Automatically deleting unnecessary messages. + """Automatically deleting unnecessary messages and handling friend requests. """ session = Session() url = 'https://api.vk.com/method/' token = USER_TOKEN + + def __init__(self): + self._friend_request_checker_active = False + self._friend_request_thread = None @staticmethod def delete_messages( @@ -50,3 +56,132 @@ def execute(data: str) -> Dict[str, Any]: """Executes VK Script. """ return UserBot.session.post(UserBot.url + 'execute', data=data).json() + + @classmethod + def call_method(cls, method: str, params: Dict[str, Any]) -> Dict[str, Any]: + """Make VK API call with user token. + """ + params['access_token'] = cls.token + params['v'] = '5.131' + response = cls.session.post(cls.url + method, data=params) + return response.json() + + def get_friend_requests(self) -> List[int]: + """Get list of pending friend request user IDs. + """ + if not self.token: + print("Warning: USER_TOKEN not set, cannot check friend requests") + return [] + + response = self.call_method('friends.getRequests', { + 'out': 0, # incoming requests + 'count': 1000 + }) + + if 'error' in response: + print(f"Error getting friend requests: {response['error']}") + return [] + + if 'response' not in response: + return [] + + return response['response'].get('items', []) + + def accept_friend_request(self, user_id: int) -> bool: + """Accept a friend request from user_id. + + Returns: + bool: True if successfully accepted, False otherwise + """ + if not self.token: + print("Warning: USER_TOKEN not set, cannot accept friend requests") + return False + + response = self.call_method('friends.add', {'user_id': user_id}) + + if 'error' in response: + error_code = response['error'].get('error_code', 0) + if error_code == 174: + print(f"Cannot add yourself as friend (user {user_id})") + elif error_code == 175: + print(f"User {user_id} has blocked you") + elif error_code == 176: + print(f"You have blocked user {user_id}") + elif error_code == 177: + print(f"User {user_id} not found") + elif error_code == 242: + print(f"Too many friends, cannot add user {user_id}") + else: + print(f"Error accepting friend request from {user_id}: {response['error']}") + return False + + if 'response' in response: + response_code = response['response'] + if response_code == 2: + print(f"Successfully accepted friend request from user {user_id}") + return True + elif response_code == 1: + print(f"Friend request sent to user {user_id} (was not pending)") + return True + elif response_code == 4: + print(f"Request resent to user {user_id}") + return True + + return False + + def check_and_accept_friend_requests(self): + """Check for pending friend requests and accept them automatically. + """ + try: + pending_requests = self.get_friend_requests() + + if pending_requests: + print(f"Found {len(pending_requests)} pending friend request(s)") + + for user_id in pending_requests: + print(f"Accepting friend request from user {user_id}") + success = self.accept_friend_request(user_id) + + if success: + # Small delay between requests to avoid rate limits + time.sleep(1) + + elif pending_requests == []: + pass # No pending requests, no output needed + + except Exception as e: + print(f"Error checking friend requests: {e}") + + def start_friend_request_monitor(self, check_interval: int = 60): + """Start monitoring for friend requests in a background thread. + + Args: + check_interval: Time in seconds between checks (default: 60) + """ + if not self.token: + print("Warning: USER_TOKEN not set, cannot start friend request monitoring") + return + + if self._friend_request_checker_active: + print("Friend request monitor is already running") + return + + print(f"Starting friend request monitor (checking every {check_interval} seconds)") + self._friend_request_checker_active = True + + def monitor_loop(): + while self._friend_request_checker_active: + self.check_and_accept_friend_requests() + time.sleep(check_interval) + + self._friend_request_thread = threading.Thread(target=monitor_loop, daemon=True) + self._friend_request_thread.start() + + def stop_friend_request_monitor(self): + """Stop the friend request monitoring thread. + """ + if self._friend_request_checker_active: + print("Stopping friend request monitor") + self._friend_request_checker_active = False + if self._friend_request_thread: + self._friend_request_thread.join(timeout=5)