This commit is contained in:
Corrado Mulas
2026-06-19 15:11:04 +02:00
parent 0d26d5a8d3
commit 512e64f83d
10 changed files with 407 additions and 145 deletions

View File

@@ -75,6 +75,15 @@ docker run telegram-groupfactory
## Quick Start ## Quick Start
### GroupFactory Commands (Staff Chat Only)
```
!newgrp - Start interactive group creation
!confirm - Confirm pending group creation
!cancel - Cancel pending group creation
!PING - Check if the userbot is online
!help - Show GroupFactory commands
```
### Admin Commands (Admin Chat Only) ### Admin Commands (Admin Chat Only)
``` ```
/admin_add_user <username> - Add user to database /admin_add_user <username> - Add user to database
@@ -86,9 +95,9 @@ docker run telegram-groupfactory
/admin_get_qr - Retrieve GroupHelp backup QR data /admin_get_qr - Retrieve GroupHelp backup QR data
``` ```
### User Commands ### Legacy User Commands
``` ```
/create_group <name> - Create group with default users /create_group <name> - Deprecated; use !newgrp in staff chat
/users - List all users /users - List all users
/user <user_id> - Get user info /user <user_id> - Get user info
/help - Show all available commands /help - Show all available commands
@@ -96,7 +105,8 @@ docker run telegram-groupfactory
## Available Commands ## Available Commands
- `/create_group <name>` - Create a new group - `!newgrp` - Create a new group with DB users and stored GroupHelp QR import
- `/create_group <name>` - Deprecated; use `!newgrp`
- `/add_users <group_id> <user_ids>` - Add users to a group - `/add_users <group_id> <user_ids>` - Add users to a group
- `/get_group <group_id>` - Get group information - `/get_group <group_id>` - Get group information
- `/users` - List all users - `/users` - List all users

View File

@@ -6,7 +6,6 @@ from src.api.schemas import (
CommandResponse, CommandResponse,
CreateGroupRequest, CreateGroupRequest,
) )
from src.config import save_user_admin_role
def _envelope(message: str) -> CommandResponse: def _envelope(message: str) -> CommandResponse:
@@ -19,14 +18,13 @@ router = APIRouter(prefix="/api/groups", tags=["groups"], dependencies=[Depends(
@router.post("", response_model=CommandResponse) @router.post("", response_model=CommandResponse)
async def create_group(payload: CreateGroupRequest, request: Request): async def create_group(payload: CreateGroupRequest, request: Request):
handler = request.app.state.group_handler handler = request.app.state.group_handler
message = await handler.handle_create_group(payload.name, payload.user_ids) message = await handler.handle_create_group(
payload.name,
# Mirror the Telegram inline-button flow: persist the admin-role choice user_ids=payload.user_ids,
# against the bot user (the entity creating the group via the API). description=payload.description or payload.name,
if payload.full_admin is not None: staff_chat_id=request.app.state.config["telegram"].get("staff_chat_id"),
bot_user_id = request.app.state.config["telegram"].get("factory_bot_id") factory_bot_id=request.app.state.config["telegram"].get("factory_bot_id"),
if bot_user_id: )
save_user_admin_role(bot_user_id, payload.full_admin)
return _envelope(message) return _envelope(message)

View File

@@ -15,6 +15,7 @@ class AddUserRequest(BaseModel):
class CreateGroupRequest(BaseModel): class CreateGroupRequest(BaseModel):
name: str = Field(..., min_length=1) name: str = Field(..., min_length=1)
description: Optional[str] = None
user_ids: Optional[List[int]] = None user_ids: Optional[List[int]] = None
full_admin: Optional[bool] = None full_admin: Optional[bool] = None

View File

@@ -2,7 +2,7 @@ import logging
from typing import List from typing import List
from src.config import ( from src.config import (
get_default_group_users, set_default_group_users, get_qr_data, get_default_group_users, set_default_group_users, get_qr_data,
set_qr_backup_data, verify_admin_access, save_user_admin_role set_qr_backup_data, verify_admin_access
) )
from src.services.user_service import UserService from src.services.user_service import UserService
from src.models.user import User from src.models.user import User
@@ -191,7 +191,7 @@ class AdminHandler:
import hashlib import hashlib
user_id = int(hashlib.md5(username.encode()).hexdigest()[:8], 16) user_id = int(hashlib.md5(username.encode()).hexdigest()[:8], 16)
user = User(id=user_id, username=username, name=username) user = User(id=user_id, username=username, first_name=username)
success = self.user_service.save_user(user) success = self.user_service.save_user(user)
if success: if success:
return f"✅ User {username} added successfully (ID: {user_id})" return f"✅ User {username} added successfully (ID: {user_id})"

View File

@@ -1,10 +1,12 @@
import logging import logging
from typing import List from typing import Awaitable, Callable, List, Optional
from src.services.user_service import UserService from src.services.user_service import UserService
from src.services.group_service import GroupService from src.services.group_service import GroupService
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
StatusCallback = Callable[[str], Awaitable[object]]
class GroupHandler: class GroupHandler:
"""Handler class for group-related commands""" """Handler class for group-related commands"""
@@ -12,12 +14,34 @@ class GroupHandler:
self.user_service = user_service self.user_service = user_service
self.group_service = group_service self.group_service = group_service
async def handle_create_group(self, group_name: str, user_ids: List[int]) -> str: async def handle_create_group(
self,
group_name: str,
user_ids: List[int] = None,
description: str = "",
status_callback: Optional[StatusCallback] = None,
staff_chat_id: Optional[int] = None,
factory_bot_id: Optional[int] = None,
) -> str:
"""Handle command to create a new group""" """Handle command to create a new group"""
try: try:
group_id = await self.group_service.create_group(group_name, user_ids) result = await self.group_service.create_group(
if group_id: group_name,
return f"✅ Group '{group_name}' created successfully with ID: {group_id}" description=description,
user_ids=user_ids,
status_callback=status_callback,
staff_chat_id=staff_chat_id,
factory_bot_id=factory_bot_id,
)
if result:
invite = f"\n🔗 {result['invite_link']}" if result.get("invite_link") else ""
qr_status = "\n✅ GroupHelp QR import sent" if result.get("qr_imported") else "\n⚠️ GroupHelp QR import not configured"
return (
f"✅ Group '{group_name}' created successfully with ID: {result['id']}\n"
f"👥 Added {result['users_added']}/{result['users_total']} users"
f"{qr_status}"
f"{invite}"
)
else: else:
return "❌ Failed to create group" return "❌ Failed to create group"
except Exception as e: except Exception as e:

View File

@@ -43,7 +43,7 @@ class UserHandler:
import hashlib import hashlib
user_id = int(hashlib.md5(username.encode()).hexdigest()[:8], 16) user_id = int(hashlib.md5(username.encode()).hexdigest()[:8], 16)
user = User(id=user_id, username=username, name=username) user = User(id=user_id, username=username, first_name=username)
success = self.user_service.save_user(user) success = self.user_service.save_user(user)
if success: if success:
return f"✅ User {username} added successfully (ID: {user_id})" return f"✅ User {username} added successfully (ID: {user_id})"

View File

@@ -1,9 +1,8 @@
import asyncio import asyncio
import logging import logging
import json
import uvicorn import uvicorn
from telethon import Button, TelegramClient, events from telethon import TelegramClient, events
from src.config import load_config, save_user_admin_role, get_user_admin_role from src.config import load_config
from src.services.mongodb_service import MongoDBService from src.services.mongodb_service import MongoDBService
from src.services.user_service import UserService from src.services.user_service import UserService
from src.services.group_service import GroupService from src.services.group_service import GroupService
@@ -25,6 +24,8 @@ async def main():
# Load configuration # Load configuration
config = load_config() config = load_config()
staff_chat_id = config['telegram']['staff_chat_id']
factory_bot_id = config['telegram']['factory_bot_id']
# Initialize MongoDB service # Initialize MongoDB service
mongo_service = MongoDBService( mongo_service = MongoDBService(
@@ -47,46 +48,21 @@ async def main():
config['telegram']['api_id'], config['telegram']['api_id'],
config['telegram']['api_hash'] config['telegram']['api_hash']
) )
group_service.set_client(client)
group_conversations = {}
@client.on(events.CallbackQuery()) async def create_group_from_staff_flow(event, name: str, description: str):
async def callback_handler(event): response = await group_handler.handle_create_group(
"""Handle inline button callbacks for admin role selection""" name,
try: description=description,
data = event.data.decode() if isinstance(event.data, bytes) else event.data status_callback=event.respond,
staff_chat_id=staff_chat_id,
factory_bot_id=factory_bot_id,
)
await event.respond(response)
# Parse callback data def is_staff_chat(chat_id: int) -> bool:
if data.startswith('admin_role:'): return chat_id == staff_chat_id
user_id = event.sender_id
is_full_admin = data.split(':')[1] == 'yes'
# Save the user's admin role preference
if save_user_admin_role(user_id, is_full_admin):
role_text = "✅ Full Group Admin" if is_full_admin else "👤 Regular Member"
await event.answer(f"Set as {role_text}")
# Edit the message to show the selection
await event.edit(f"Group Admin Role Selection\n\n{role_text} - Confirmed!")
else:
await event.answer("❌ Failed to save preference", alert=True)
elif data.startswith('group_create:'):
# Extract group name and user IDs from callback
parts = data.split(':', 2)
if len(parts) >= 3:
group_name = parts[1]
user_ids_str = parts[2]
try:
user_ids = [int(uid) for uid in user_ids_str.split(',')] if user_ids_str else None
response = await group_handler.handle_create_group(group_name, user_ids)
await event.answer()
await event.edit(response)
except ValueError:
await event.answer("❌ Invalid user IDs", alert=True)
except Exception as e:
logger.error(f"Error handling callback: {e}")
await event.answer(f"❌ Error: {str(e)}", alert=True)
@client.on(events.NewMessage()) @client.on(events.NewMessage())
async def message_handler(event): async def message_handler(event):
@@ -101,6 +77,105 @@ async def main():
return return
try: try:
# ==================== IMS GROUPFACTORY STAFF FLOW ====================
if is_staff_chat(chat_id):
raw_text = text.strip()
lower_text = raw_text.lower()
if lower_text == '!ping':
await event.respond('PONG -> IMS GroupFactory Userbot')
return
if lower_text == '!help':
help_text = """**IMS GroupFactory Commands**
`!newgrp` - Start creating a new Telegram group
`!cancel` - Cancel the current operation
`!confirm` - Confirm group creation
`!PING` - Check if the userbot is online
`!help` - Display this help message"""
await event.respond(help_text)
return
if lower_text == '!cancel':
if sender_id in group_conversations:
del group_conversations[sender_id]
await event.respond('🛑 Operation canceled.')
else:
await event.respond('❓ No active operation to cancel.')
return
if lower_text.startswith('!newgrp'):
if lower_text != '!newgrp':
cmd_args = raw_text[len('!newgrp'):].strip()
marker = "\n\nDescription:\n"
if marker in cmd_args:
name, description = cmd_args.split(marker, 1)
name = name.strip()
description = description.strip()
if not name or not description:
await event.respond('⚠️ Group name and description cannot be empty.')
return
await create_group_from_staff_flow(event, name, description)
else:
await event.respond('⚠️ Old format detected but missing description.\nUse `!newgrp` alone to start interactive mode.')
return
group_conversations[sender_id] = {
'step': 'name',
'data': {}
}
await event.respond('👋 Let\'s create a new group!\n\nPlease enter the group name:')
return
if sender_id in group_conversations:
current_step = group_conversations[sender_id]['step']
if lower_text == '!confirm' and current_step == 'confirm':
name = group_conversations[sender_id]['data']['name']
description = group_conversations[sender_id]['data']['description']
await event.respond('✅ Confirmed! Starting group creation process...')
try:
await create_group_from_staff_flow(event, name, description)
finally:
group_conversations.pop(sender_id, None)
return
if raw_text.startswith('!'):
if current_step == 'confirm':
await event.respond('❓ Please type `!confirm` to create the group or `!cancel` to abort.')
return
if current_step == 'name':
if not raw_text:
await event.respond('⚠️ Group name cannot be empty. Please try again:')
return
group_conversations[sender_id]['data']['name'] = raw_text
group_conversations[sender_id]['step'] = 'description'
await event.respond(f'📝 Group name set to: "{raw_text}"\n\nNow please enter the group description:')
return
if current_step == 'description':
if not raw_text:
await event.respond('⚠️ Group description cannot be empty. Please try again:')
return
group_conversations[sender_id]['data']['description'] = raw_text
name = group_conversations[sender_id]['data']['name']
group_conversations[sender_id]['step'] = 'confirm'
await event.respond(
f'📋 **Group Creation Summary**\n\n'
f'**Name**: {name}\n'
f'**Description**: {raw_text}\n\n'
f'Type `!confirm` to create this group or `!cancel` to abort.'
)
return
if current_step == 'confirm':
await event.respond('❓ Please type `!confirm` to create the group or `!cancel` to abort.')
return
# ==================== ADMIN COMMANDS ==================== # ==================== ADMIN COMMANDS ====================
# All admin commands require being in the admin chat # All admin commands require being in the admin chat
@@ -178,36 +253,7 @@ async def main():
# ==================== GROUP COMMANDS ==================== # ==================== GROUP COMMANDS ====================
elif text.startswith('/create_group'): elif text.startswith('/create_group'):
# Parse group name and optional user IDs await event.respond(" `/create_group` has been replaced. Use `!newgrp` in the staff chat.")
parts = text.split(maxsplit=2)
if len(parts) > 1:
group_name = parts[1]
user_ids = None
if len(parts) > 2:
try:
user_ids = [int(uid) for uid in parts[2].split(',')]
except ValueError:
await event.respond("❌ Invalid user IDs format.\n\nUsage: `/create_group <name>` or `/create_group <name> <user_id1>,<user_id2>,...`")
return
# Create the group
response = await group_handler.handle_create_group(group_name, user_ids)
# Ask about admin role with inline buttons
buttons = [
[
Button.inline("✅ Yes, I want to be full admin", b"admin_role:yes"),
Button.inline("❌ No, just regular member", b"admin_role:no"),
]
]
await event.respond(
f"{response}\n\n" +
"👤 Would you like to be added as a full admin to this group?",
buttons=buttons
)
else:
await event.respond("❌ Please provide a group name.\n\nUsage: `/create_group <name>` or `/create_group <name> <user_id1>,<user_id2>,...`")
elif text.startswith('/add_users'): elif text.startswith('/add_users'):
# Parse group ID and user IDs # Parse group ID and user IDs
@@ -287,8 +333,8 @@ async def main():
• `/delete_user <user_id>` - Delete user • `/delete_user <user_id>` - Delete user
**Group Management:** **Group Management:**
• `/create_group <name>` - Create group with default users • `!newgrp` - Create a group with database users and stored GroupHelp QR import
• `/create_group <name> <id1>,<id2>` - Create group with specific users • `/create_group` - Deprecated; use `!newgrp`
• `/add_users <group_id> <id1>,<id2>` - Add users to group • `/add_users <group_id> <id1>,<id2>` - Add users to group
• `/get_group <group_id>` - Get group info • `/get_group <group_id>` - Get group info

View File

@@ -13,6 +13,11 @@ class User:
if self.id is None: if self.id is None:
raise ValueError("User ID cannot be None") raise ValueError("User ID cannot be None")
@property
def name(self) -> str:
parts = [part for part in [self.first_name, self.last_name] if part]
return " ".join(parts) or self.username or str(self.id)
@classmethod @classmethod
def from_dict(cls, data: dict): def from_dict(cls, data: dict):
"""Create User instance from dictionary""" """Create User instance from dictionary"""

View File

@@ -1,32 +1,135 @@
import logging import logging
from typing import List, Optional import asyncio
from src.models.user import User from typing import Awaitable, Callable, List, Optional
from telethon import functions, types
from telethon.errors.rpcerrorlist import PeerFloodError, UserPrivacyRestrictedError
from telethon.tl.functions.channels import CreateChannelRequest, InviteToChannelRequest
from src.services.mongodb_service import MongoDBService from src.services.mongodb_service import MongoDBService
from src.config import get_telegram_client, get_default_group_users from src.config import get_default_group_users, get_qr_data
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
StatusCallback = Callable[[str], Awaitable[object]]
class GroupService: class GroupService:
"""Service class for group creation and management""" """Service class for group creation and management"""
def __init__(self, mongo_service: MongoDBService): def __init__(self, mongo_service: MongoDBService, telegram_client=None):
self.mongo_service = mongo_service self.mongo_service = mongo_service
self.client = get_telegram_client() self.client = telegram_client
async def create_group(self, group_name: str, user_ids: List[int] = None) -> Optional[str]: def set_client(self, telegram_client):
"""Create a Telegram group with specified users or default users""" self.client = telegram_client
async def _notify(self, status_callback: Optional[StatusCallback], message: str):
if status_callback:
return await status_callback(message)
return None
async def _edit_status(self, status_message, message: str):
if hasattr(status_message, "edit"):
await status_message.edit(message)
else:
await self.client.edit_message(status_message, message)
def _admin_rights(self, **rights):
try:
return types.ChatAdminRights(**rights)
except TypeError:
rights.pop("manage_topics", None)
return types.ChatAdminRights(**rights)
async def _promote_user(self, channel, user_id, full_admin: bool):
if full_admin:
admin_rights = self._admin_rights(
change_info=True,
post_messages=True,
edit_messages=True,
delete_messages=True,
ban_users=True,
invite_users=True,
pin_messages=True,
add_admins=True,
anonymous=False,
manage_call=True,
other=True,
manage_topics=True,
)
rank = "manager"
else:
admin_rights = self._admin_rights(
change_info=False,
post_messages=True,
edit_messages=True,
delete_messages=True,
ban_users=True,
invite_users=True,
pin_messages=True,
add_admins=False,
anonymous=False,
manage_call=True,
other=False,
manage_topics=True,
)
rank = "admin"
await self.client(functions.channels.EditAdminRequest(
channel=channel,
user_id=user_id,
admin_rights=admin_rights,
rank=rank,
))
async def _export_invite_link(self, channel) -> Optional[str]:
try:
invite = await self.client(functions.messages.ExportChatInviteRequest(
peer=channel,
))
return getattr(invite, "link", None)
except Exception as e:
logger.warning(f"Failed to export invite link: {e}")
return None
def _build_importbackup_message(self, qr_data: str) -> str:
qr_data = qr_data.strip()
if qr_data.lower().startswith((".importbackup", "/importbackup")):
return qr_data
return f".importbackup {qr_data}"
async def create_group(
self,
group_name: str,
description: str = "",
user_ids: List[int] = None,
status_callback: Optional[StatusCallback] = None,
staff_chat_id: Optional[int] = None,
factory_bot_id: Optional[int] = None,
) -> Optional[dict]:
"""Create a Telegram megagroup and run the IMS GroupFactory setup flow."""
try: try:
if not self.client: if not self.client:
logger.error("Telegram client not initialized") logger.error("Telegram client not initialized")
return None return None
# Use default users if none specified await self._notify(status_callback, f'🚀 Creating group "{group_name}"...')
created_channel = await self.client(CreateChannelRequest(
group_name,
description,
megagroup=True,
broadcast=False,
))
channel = created_channel.chats[0]
target_group = types.InputPeerChannel(channel.id, channel.access_hash)
await self._notify(status_callback, f'✅ Group "{group_name}" created successfully!')
if user_ids is None or len(user_ids) == 0: if user_ids is None or len(user_ids) == 0:
user_ids = get_default_group_users() user_ids = get_default_group_users()
if len(user_ids) == 0: if len(user_ids) == 0:
logger.warning("No default users configured for group creation") logger.warning("No default users configured for group creation")
# Get users from MongoDB
users = [] users = []
for user_id in user_ids: for user_id in user_ids:
user = self.mongo_service.get_user_by_id(user_id) user = self.mongo_service.get_user_by_id(user_id)
@@ -35,19 +138,98 @@ class GroupService:
else: else:
logger.warning(f"User {user_id} not found in database") logger.warning(f"User {user_id} not found in database")
if not users: await self._notify(status_callback, f"👥 Found {len(users)} configured users to add")
logger.warning("No valid users found for group creation") status_message = await self._notify(status_callback, "👥 Adding users to the group...")
success_count = 0
error_count = 0
for index, user in enumerate(users):
try:
if index % 5 == 0 and status_message:
await self._edit_status(
status_message,
f"👥 Adding users: {index}/{len(users)} completed",
)
user_ref = user.username or user.id
user_to_add = await self.client.get_input_entity(user_ref)
await self.client(InviteToChannelRequest(target_group, [user_to_add]))
await self._promote_user(target_group, user_to_add, full_admin=False)
success_count += 1
await asyncio.sleep(2)
except PeerFloodError:
logger.warning("Telegram flood limit reached while adding users")
await self._notify(status_callback, "⚠️ Telegram flood limit reached. Pausing for 30 seconds...")
await asyncio.sleep(30)
except UserPrivacyRestrictedError:
logger.warning(f"User {user.username or user.id} has privacy restrictions")
error_count += 1
except Exception as e:
logger.error(f"Error adding user {user.username or user.id}: {e}")
error_count += 1
if error_count > 10:
await self._notify(status_callback, "❌ Too many errors, aborting user addition!")
return None return None
# Create group using Telegram API if status_message:
result = await self.client.create_group(group_name, [user.id for user in users]) await self._edit_status(
status_message,
f"✅ Added {success_count}/{len(users)} users to the group",
)
if result: if factory_bot_id:
logger.info(f"Successfully created group '{group_name}' with {len(users)} members") try:
return result.id logger.info(f"Promoting factory bot {factory_bot_id} as manager")
factory_bot = await self.client.get_input_entity(factory_bot_id)
try:
await self.client(InviteToChannelRequest(target_group, [factory_bot]))
except Exception as e:
logger.info(f"Factory bot invite skipped or failed before promotion: {e}")
await self._promote_user(target_group, factory_bot, full_admin=True)
await asyncio.sleep(2)
except Exception as e:
logger.error(f"Failed to promote factory bot {factory_bot_id}: {e}")
await self._notify(status_callback, f"⚠️ Failed to promote factory bot: {e}")
await self._notify(status_callback, "⚙️ Sending GroupHelp setup commands...")
await self.client.send_message(target_group, "/pro")
await asyncio.sleep(2)
if staff_chat_id:
await self.client.send_message(target_group, f"/setstaffgroup {staff_chat_id}")
await asyncio.sleep(2)
qr_imported = False
qr_data = get_qr_data()
if qr_data:
logger.info("Sending GroupHelp QR backup import command")
await self.client.send_message(
target_group,
self._build_importbackup_message(qr_data),
)
qr_imported = True
if staff_chat_id:
await self.client.send_message(staff_chat_id, "✅ GroupHelp QR backup import sent to the new group.")
elif staff_chat_id:
await self.client.send_message(staff_chat_id, "⚠️ No GroupHelp QR backup data configured. Use `/admin_set_qr <qr_data>`.")
invite_link = await self._export_invite_link(target_group)
if staff_chat_id:
if invite_link:
await self.client.send_message(staff_chat_id, f"🔗 Invite link:\n\n{invite_link}")
else: else:
logger.error("Failed to create group") await self.client.send_message(staff_chat_id, "⚠️ Failed to generate invite link")
return None
logger.info(f"Group creation process completed for {group_name}")
return {
"id": channel.id,
"access_hash": channel.access_hash,
"title": channel.title,
"invite_link": invite_link,
"users_added": success_count,
"users_total": len(users),
"qr_imported": qr_imported,
}
except Exception as e: except Exception as e:
logger.error(f"Error creating group '{group_name}': {e}") logger.error(f"Error creating group '{group_name}': {e}")
@@ -60,7 +242,6 @@ class GroupService:
logger.error("Telegram client not initialized") logger.error("Telegram client not initialized")
return False return False
# Get users from MongoDB
users = [] users = []
for user_id in user_ids: for user_id in user_ids:
user = self.mongo_service.get_user_by_id(user_id) user = self.mongo_service.get_user_by_id(user_id)
@@ -73,15 +254,14 @@ class GroupService:
logger.warning("No valid users found for adding to group") logger.warning("No valid users found for adding to group")
return False return False
# Add users to group using Telegram API group = await self.client.get_input_entity(group_id)
result = await self.client.add_users_to_group(group_id, [user.id for user in users]) for user in users:
user_ref = user.username or user.id
user_to_add = await self.client.get_input_entity(user_ref)
await self.client(InviteToChannelRequest(group, [user_to_add]))
if result:
logger.info(f"Successfully added {len(users)} users to group {group_id}") logger.info(f"Successfully added {len(users)} users to group {group_id}")
return True return True
else:
logger.error("Failed to add users to group")
return False
except Exception as e: except Exception as e:
logger.error(f"Error adding users to group {group_id}: {e}") logger.error(f"Error adding users to group {group_id}: {e}")
@@ -94,15 +274,13 @@ class GroupService:
logger.error("Telegram client not initialized") logger.error("Telegram client not initialized")
return None return None
# Get group info using Telegram API result = await self.client.get_entity(group_id)
result = await self.client.get_group_info(group_id)
if result:
logger.info(f"Retrieved information for group {group_id}") logger.info(f"Retrieved information for group {group_id}")
return result return {
else: "id": getattr(result, "id", None),
logger.warning(f"Failed to retrieve information for group {group_id}") "title": getattr(result, "title", None),
return None "username": getattr(result, "username", None),
}
except Exception as e: except Exception as e:
logger.error(f"Error retrieving group info for {group_id}: {e}") logger.error(f"Error retrieving group info for {group_id}: {e}")

View File

@@ -33,7 +33,7 @@ class MongoDBService:
def get_users(self) -> List[User]: def get_users(self) -> List[User]:
"""Retrieve all users from MongoDB collection""" """Retrieve all users from MongoDB collection"""
try: try:
if not self.collection: if self.collection is None:
logger.error("MongoDB collection not initialized") logger.error("MongoDB collection not initialized")
return [] return []
@@ -48,7 +48,7 @@ class MongoDBService:
def get_user_by_id(self, user_id: int) -> Optional[User]: def get_user_by_id(self, user_id: int) -> Optional[User]:
"""Retrieve a specific user by ID from MongoDB""" """Retrieve a specific user by ID from MongoDB"""
try: try:
if not self.collection: if self.collection is None:
logger.error("MongoDB collection not initialized") logger.error("MongoDB collection not initialized")
return None return None
@@ -63,7 +63,7 @@ class MongoDBService:
def save_user(self, user: User) -> bool: def save_user(self, user: User) -> bool:
"""Save a user to MongoDB collection""" """Save a user to MongoDB collection"""
try: try:
if not self.collection: if self.collection is None:
logger.error("MongoDB collection not initialized") logger.error("MongoDB collection not initialized")
return False return False
@@ -84,7 +84,7 @@ class MongoDBService:
def delete_user(self, user_id: int) -> bool: def delete_user(self, user_id: int) -> bool:
"""Delete a user from MongoDB collection""" """Delete a user from MongoDB collection"""
try: try:
if not self.collection: if self.collection is None:
logger.error("MongoDB collection not initialized") logger.error("MongoDB collection not initialized")
return False return False