├── Procfile ├── requirements.txt ├── start.sh ├── heroku.yml ├── config.py ├── Dockerfile ├── README.md └── scr.py /Procfile: -------------------------------------------------------------------------------- 1 | worker: ./start.sh 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyrogram 2 | aiofiles 3 | asyncio 4 | tgcrypto 5 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Run the scr.py script 4 | python scr.py 5 | -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | web: Dockerfile 4 | 5 | run: 6 | web: ./start.sh 7 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | # Pyrogram setup 2 | API_ID = "123456" # Replace this API ID with your actual API ID 3 | API_HASH = "XXXXXXXXXXX" # Replace this API HASH with your actual API HASH 4 | SESSION_STRING = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Replace this SESSION STRING with your actual SESSION_STRING 5 | BOT_TOKEN = "12345678:XXXXXXXXXXXXXX" # Replace this BOT_TOKEN 6 | 7 | # Admin IDs 8 | ADMIN_IDS = [12345678, 12345678] 9 | 10 | # Limits 11 | DEFAULT_LIMIT = 10000 # Card Scrapping Limit For Everyone 12 | ADMIN_LIMIT = 50000 # Card Scrapping Limit For Admin -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official Python 3.10 image from the Docker Hub 2 | FROM python:3.10-slim 3 | 4 | # Set the working directory in the container 5 | WORKDIR /app 6 | 7 | # Copy the requirements.txt file into the container at /app 8 | COPY requirements.txt /app/ 9 | 10 | # Install any dependencies specified in requirements.txt 11 | RUN pip install --no-cache-dir -r requirements.txt 12 | 13 | # Copy the rest of the working directory contents into the container at /app 14 | COPY . /app 15 | 16 | # Make start.sh executable 17 | RUN chmod +x start.sh 18 | 19 | # Run start.sh when the container launches 20 | CMD ["./start.sh"] 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

CC Scraper Telegram Bot

2 | 3 |

4 | GitHub Repo stars 5 | GitHub issues 6 | GitHub pull requests 7 | GitHub contributors 8 | GitHub forks 9 |

10 | 11 |

12 | CC Scraper: An advanced Telegram bot script to scrape credit cards from specified Telegram groups and channels. 13 |

14 |
15 | 16 | ## Features 17 | 18 | - Scrapes cards from private/public Telegram groups and channels. 19 | - Supports format: group/channel username, ID, or link. 20 | - Scrapes specific BIN credit cards. 21 | - Removes duplicate credit cards. 22 | - Handles multiple requests at a time. 23 | - Super-fast scraping speed. 24 | - New Feature: Scrape from multiple chats using a single command. 25 | - Join Request Automatically Send Join Request To Chats Which Requires. 26 | - New Libraries Added For Speed Up. 27 | - Fixed UserAlreadyParticipant Error In Joinning And Scrapping From Private Chats. 28 | - Logging Added So That You Can See Every Functions Work In Console. 29 | - Updated All Regex Pattern. 30 | - Bin Filter Updated And Bank Filter Added. 31 | - `user_link` Variable Added For Nice Interface In Caption `CC Scrapped By` 32 | - Scrape Through Chat ID Of Chat Added Example `/scr -1003463745639 10` 33 | - Multiple CC Scrapper Has Some Common Features Of CC Scrapper. 34 | 35 | ## Requirements 36 | 37 | Before you begin, ensure you have met the following requirements: 38 | 39 | - Python 3.9 or higher. 40 | - `pyrogram` and `tgcrypto` libraries. ✨Note You Can Also Use `pyrofork` 41 | - A Telegram bot token (you can get one from [@BotFather](https://t.me/BotFather) on Telegram). 42 | - API ID and Hash: You can get these by creating an application on [my.telegram.org](https://my.telegram.org). 43 | - To Get `SESSION_STRING` Open [@ItsSmartToolBot](https://t.me/ItsSmartToolBot). Bot and use /pyro command and then follow all instructions. 44 | 45 | ## Installation 46 | 47 | To install `pyrogram` , `aiofiles` `asyncio` and `tgcrypto`, run the following command: 48 | 49 | ```bash 50 | pip install -r requirements.txt 51 | ``` 52 | 53 | **Note: If you previously installed `pyrofork`, uninstall it before installing `pyrogram`.** 54 | 55 | ## Configuration 56 | 57 | 1. Open the `config.py` file in your favorite text editor. 58 | 2. Replace the placeholders for `API_ID`, `API_HASH`, `SESSION_STRING`, `ADMIN_IDS`, `DEFAULT_LIMIT`, `ADMIN_LIMIT` and `BOT_TOKEN` with your actual values: 59 | - **`API_ID`**: Your API ID from [my.telegram.org](https://my.telegram.org). 60 | - **`API_HASH`**: Your API Hash from [my.telegram.org](https://my.telegram.org). 61 | - **`SESSION_STRING`**: The session string generated using [@ItsSmartToolBot](https://t.me/ItsSmartToolBot). 62 | - **`BOT_TOKEN`**: The token you obtained from [@BotFather](https://t.me/BotFather). 63 | 64 | 3. **Optional VARS**: 65 | - **`ADMIN_IDS`**: List of admin user IDs who have elevated permissions. 66 | - **`ADMIN_LIMIT`**: The maximum number of messages admins can scrape in a single request. 67 | - **`DEFAULT_LIMIT`**: The maximum number of messages regular users can scrape in a single request. 68 | 69 | ## Deploy the Bot 70 | 71 | ```sh 72 | git clone https://github.com/abirxdhack/CC-Scrapper 73 | cd CC-Scrapper 74 | python scrapper.py 75 | ``` 76 | ## Deploy The Bot With Screen 77 | 78 | ```sh 79 | git clone https://github.com/abirxdhack/CC-Scrapper 80 | cd CC-Scrapper 81 | screen -S CCScrapperBot 82 | python scr.py 83 | ``` 84 | 85 | ## Supported Commands 86 | 87 | ### Single Channel Scrape 88 | 89 | 1. Use the `/scr` command followed by the group or channel username and the number of messages to scrape. 90 | 91 | ```text 92 | /scr @channel_username 1000 93 | ``` 94 | 95 | 2. Optionally, you can scrape any target BIN cards by providing the BIN number. 96 | 97 | ```text 98 | /scr @channel_username 1000 434769 99 | ``` 100 | 101 | 3. Optionally, you can scrape messages containing a specific bank name by providing the bank name. 102 | 103 | ```text 104 | /scr @channel_username 1000 BankName 105 | ``` 106 | 107 | 4. Use a chat ID instead of the username for private channels: 108 | 109 | ```text 110 | /scr -1001234567890 1000 111 | ``` 112 | 113 | 5. Use an invite link for private channels: 114 | 115 | ```text 116 | /scr https://t.me/+abcdef1234567890 1000 117 | ``` 118 | 119 | ### Multi Channel Scrape 120 | 121 | 1. Use the `/mc` command to scrape from multiple chats by specifying multiple usernames and the total number of messages to scrape: 122 | 123 | ```text 124 | /mc @channel_username @channel_username1 1000 125 | ``` 126 | 127 | 2. For private channels using chat IDs with the `/mc` command: 128 | 129 | ```text 130 | /mc -1001234567890 -1009876543210 1000 131 | ``` 132 | 133 | 3. For private channels using invite links with the `/mc` command: 134 | 135 | ```text 136 | /mc https://t.me/+abcdef1234567890 https://t.me/+uvwxyz9876543210 1000 137 | ``` 138 | 139 | ### General Notes 140 | 141 | - The `@channel_username` can be replaced with the actual username of the channel or group. 142 | - The `-1001234567890` should be replaced with the actual chat ID of the private channel or group. 143 | - The `https://t.me/+abcdef1234567890` should be replaced with the actual invite link of the private channel or group. 144 | - The `1000` represents the number of messages to scrape and can be adjusted as needed. 145 | - For multi-channel scrape (`/mc`), the last argument should always be the total number of messages to scrape across all specified channels. 146 | 147 | ## Major Note 148 | **DEFAULT_LIMIT** Currently Set To 5000 Because Request Over 10000 May Cause Your User Acc `Ban Or Logout` 149 | **ADMIN_LIMIT** Currently Set To 10000 Because Request Over 10000 May Cause Your User Acc `Ban Or Logout` 150 | 151 | ✨ **Notes**: 152 | - Ensure the bot is an administrator in the channels/groups you want to scrape from for the best results. 153 | - The bot can handle a high number of requests simultaneously, but it's a good practice to monitor its performance and adjust limits if necessary. 154 | - If you encounter any issues, check the bot logs for detailed error messages. 155 | - Keep your API credentials and session string secure to prevent unauthorized access to your bot. 156 | - First Clone Repo Then Update Credentials Dont Direct Commit On Github To Keep Credentials Secure. 157 | 158 | ## Authors 159 | - Name: Bisnu Ray 160 | - Telegram: [@TheSmartBisnu](https://t.me/TheSmartBisnu) 161 | ## Update Author 162 | - Name: Abir Arafat Chawdhury 163 | - Telegram: [@ModVip_rm](https://t.me/ModVip_rm) 164 | 165 | Feel free to reach out if you have any questions or feedback In My Telegram [Abir Arafat Chawdhury](t.me/abirxdhackz) 166 | -------------------------------------------------------------------------------- /scr.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | import asyncio 4 | import logging 5 | import aiofiles 6 | from pyrogram.enums import ParseMode 7 | from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton 8 | from pyrogram import Client, filters 9 | from pyrogram.errors import ( 10 | UserAlreadyParticipant, 11 | InviteHashExpired, 12 | InviteHashInvalid, 13 | PeerIdInvalid, 14 | InviteRequestSent 15 | ) 16 | from urllib.parse import urlparse 17 | from config import ( 18 | API_ID, 19 | API_HASH, 20 | BOT_TOKEN, 21 | SESSION_STRING, 22 | ADMIN_LIMIT, 23 | ADMIN_IDS, 24 | DEFAULT_LIMIT 25 | ) 26 | 27 | # Setup logging For Capturing Errors 28 | logging.basicConfig(level=logging.INFO) 29 | logger = logging.getLogger(__name__) 30 | 31 | # Initialize Bot Client With Workers 32 | app = Client( 33 | "app_session", 34 | api_id=API_ID, 35 | api_hash=API_HASH, 36 | bot_token=BOT_TOKEN, 37 | workers=1000 38 | ) 39 | 40 | # Initialize User Client With Workers 41 | user = Client( 42 | "user_session", 43 | session_string=SESSION_STRING, 44 | workers=1000 45 | ) 46 | 47 | 48 | START_MESSAGE = """ 49 | Welcome to the Credit Card Scraper Bot 🕵️‍♂️💳 50 | 51 | I'm here to help you scrape credit card information from Telegram channels. 52 | Use the commands below to get started: 53 | 54 | /scr [channel_username] [limit] - Scrape from a single channel. 📺 55 | /mc [channel_username1] [channel_username2] ... [limit] - Scrape from multiple channels. 📡 56 | 57 | Examples: 58 | /scr @username 100 515462 59 | /scr @username 100 BankName 60 | /scr username 100 61 | /scr username 100 515462 62 | /scr username 100 BankName 63 | /scr t.me/username 100 64 | /scr t.me/username 100 515462 65 | /scr t.me/username 100 Bank Name 66 | /scr https://t.me/username 100 67 | /scr https://t.me/username 100 515462 68 | /scr https://t.me/username Bank Name 69 | /scr https://t.me/+ZBqGFP5evRpmY2Y1 100 70 | /scr https://t.me/+ZBqGFP5evRpmY2Y1 100 515462 71 | /scr https://t.me/+ZBqGFP5evRpmY2Y1 100 BankName 72 | 73 | Happy scraping! 🚀 74 | """ 75 | 76 | 77 | async def scrape_messages(client, channel_username, limit, start_number=None, bank_name=None): 78 | messages = [] 79 | count = 0 80 | pattern = r'\d{16}\D*\d{2}\D*\d{2,4}\D*\d{3,4}' 81 | bin_pattern = re.compile(r'^\d{6}') if start_number else None 82 | 83 | logger.info(f"Starting to scrape messages from {channel_username} with limit {limit}") 84 | 85 | # Fetch messages in batches 86 | async for message in user.search_messages(channel_username): 87 | if count >= limit: 88 | break 89 | text = message.text or message.caption 90 | if text: 91 | # Check if the bank name is mentioned in the message (case-insensitive) 92 | if bank_name and bank_name.lower() not in text.lower(): 93 | continue 94 | matched_messages = re.findall(pattern, text) 95 | if matched_messages: 96 | formatted_messages = [] 97 | for matched_message in matched_messages: 98 | extracted_values = re.findall(r'\d+', matched_message) 99 | if len(extracted_values) == 4: 100 | card_number, mo, year, cvv = extracted_values 101 | year = year[-2:] 102 | # Apply BIN filter if start_number is provided 103 | if start_number: 104 | if card_number.startswith(start_number[:6]): 105 | formatted_messages.append(f"{card_number}|{mo}|{year}|{cvv}") 106 | else: 107 | formatted_messages.append(f"{card_number}|{mo}|{year}|{cvv}") 108 | messages.extend(formatted_messages) 109 | count += len(formatted_messages) 110 | logger.info(f"Scraped {len(messages)} messages from {channel_username}") 111 | return messages[:limit] 112 | 113 | def remove_duplicates(messages): 114 | unique_messages = list(set(messages)) 115 | duplicates_removed = len(messages) - len(unique_messages) 116 | logger.info(f"Removed {duplicates_removed} duplicates") 117 | return unique_messages, duplicates_removed 118 | 119 | async def send_results(client, message, unique_messages, duplicates_removed, source_name, bin_filter=None, bank_filter=None): 120 | if unique_messages: 121 | file_name = f"x{len(unique_messages)}_{source_name.replace(' ', '_')}.txt" 122 | # Use aiofiles for asynchronous file writing 123 | async with aiofiles.open(file_name, mode='w') as f: 124 | await f.write("\n".join(unique_messages)) 125 | 126 | # Use aiofiles for asynchronous file reading 127 | async with aiofiles.open(file_name, mode='rb') as f: 128 | user_link = await get_user_link(message) 129 | caption = ( 130 | f"CC Scrapped Successful ✅\n" 131 | f"━━━━━━━━━━━━━━━━\n" 132 | f"Source: {source_name} 🌐\n" 133 | f"Amount: {len(unique_messages)} 📝\n" 134 | f"Duplicates Removed: {duplicates_removed} 🗑️\n" 135 | ) 136 | # Add BIN filter to caption if provided 137 | if bin_filter: 138 | caption += f"📝 BIN Filter: {bin_filter}\n" 139 | # Add Bank filter to caption if provided 140 | if bank_filter: 141 | caption += f"📝 Bank Filter: {bank_filter}\n" 142 | caption += ( 143 | f"━━━━━━━━━━━━━━━━\n" 144 | f"✅ Card-Scrapped By: {user_link}\n" 145 | ) 146 | await message.delete() 147 | await client.send_document(message.chat.id, file_name, caption=caption) 148 | os.remove(file_name) 149 | logger.info(f"Results sent successfully for {source_name}") 150 | else: 151 | await message.edit_text("Sorry Bro ❌ No Credit Card Found") 152 | logger.info("No credit cards found") 153 | 154 | async def get_user_link(message): 155 | if message.from_user is None: 156 | return 'Smart Tool' 157 | else: 158 | user_first_name = message.from_user.first_name 159 | user_last_name = message.from_user.last_name or "" 160 | user_full_name = f"{user_first_name} {user_last_name}".strip() 161 | return f'{user_full_name}' 162 | 163 | async def join_private_chat(client, invite_link): 164 | try: 165 | await client.join_chat(invite_link) 166 | logger.info(f"Joined chat via invite link: {invite_link}") 167 | return True 168 | except UserAlreadyParticipant: 169 | logger.info(f"Already a participant in the chat: {invite_link}") 170 | return True 171 | except InviteRequestSent: 172 | logger.info(f"Join request sent to the chat: {invite_link}") 173 | return False 174 | except (InviteHashExpired, InviteHashInvalid) as e: 175 | logger.error(f"Failed to join chat {invite_link}: {e}") 176 | return False 177 | 178 | async def send_join_request(client, invite_link, message): 179 | try: 180 | await client.join_chat(invite_link) 181 | logger.info(f"Sent join request to chat: {invite_link}") 182 | return True 183 | except PeerIdInvalid as e: 184 | logger.error(f"Failed to send join request to chat {invite_link}: {e}") 185 | return False 186 | except InviteRequestSent: 187 | logger.info(f"Join request sent to the chat: {invite_link}") 188 | await message.edit_text("Hey Bro I Have Sent Join Request✅") 189 | return False 190 | 191 | def setup_scr_handler(app): 192 | @app.on_message(filters.command(["scr", "ccscr", "scrcc"], prefixes=["/", ".", ",", "!"]) & (filters.group | filters.private)) 193 | async def scr_cmd(client, message): 194 | args = message.text.split()[1:] 195 | user_id = message.from_user.id if message.from_user else None 196 | 197 | if len(args) < 2: 198 | await client.send_message(message.chat.id, "⚠️ Provide channel username and amount to scrape ❌") 199 | logger.warning("Invalid command: Missing arguments") 200 | return 201 | 202 | # Extract channel identifier (username, invite link, or chat ID) 203 | channel_identifier = args[0] 204 | chat = None 205 | channel_name = "" 206 | channel_username = "" 207 | 208 | # Handle private channel chat ID (numeric) 209 | if channel_identifier.lstrip("-").isdigit(): 210 | # Treat it as a chat ID 211 | chat_id = int(channel_identifier) 212 | try: 213 | # Fetch the chat details 214 | chat = await user.get_chat(chat_id) 215 | channel_name = chat.title 216 | logger.info(f"Scraping from private channel: {channel_name} (ID: {chat_id})") 217 | except Exception as e: 218 | await client.send_message(message.chat.id, "Hey Bro! 🥲 Invalid chat ID ❌") 219 | logger.error(f"Failed to fetch private channel: {e}") 220 | return 221 | else: 222 | # Handle public channels or private invite links 223 | if channel_identifier.startswith("https://t.me/+"): 224 | # Private invite link 225 | invite_link = channel_identifier 226 | temporary_msg = await client.send_message(message.chat.id, "Checking Username...") 227 | joined = await join_private_chat(user, invite_link) 228 | if not joined: 229 | request_sent = await send_join_request(user, invite_link, temporary_msg) 230 | if not request_sent: 231 | return 232 | else: 233 | await temporary_msg.delete() 234 | chat = await user.get_chat(invite_link) 235 | channel_name = chat.title 236 | logger.info(f"Joined private channel via link: {channel_name}") 237 | elif channel_identifier.startswith("https://t.me/"): 238 | # Remove "https://t.me/" for regular links 239 | channel_username = channel_identifier[13:] 240 | elif channel_identifier.startswith("t.me/"): 241 | # Remove "t.me/" for short links 242 | channel_username = channel_identifier[5:] 243 | else: 244 | # Assume it's already a username 245 | channel_username = channel_identifier 246 | 247 | if not chat: 248 | try: 249 | # Fetch the chat details 250 | chat = await user.get_chat(channel_username) 251 | channel_name = chat.title 252 | logger.info(f"Scraping from public channel: {channel_name} (Username: {channel_username})") 253 | except Exception as e: 254 | await client.send_message(message.chat.id, "Hey Bro! 🥲 Incorrect username or chat ID ❌") 255 | logger.error(f"Failed to fetch public channel: {e}") 256 | return 257 | 258 | # Extract limit (second argument) 259 | try: 260 | limit = int(args[1]) 261 | logger.info(f"Scraping limit set to: {limit}") 262 | except ValueError: 263 | await client.send_message(message.chat.id, "⚠️ Invalid limit value. Please provide a valid number ❌") 264 | logger.warning("Invalid limit value provided") 265 | return 266 | 267 | # Extract optional arguments (starting number or bank name) 268 | start_number = None 269 | bank_name = None 270 | bin_filter = None 271 | if len(args) > 2: 272 | # Check if the third argument is a starting number (digits only) 273 | if args[2].isdigit(): 274 | start_number = args[2] 275 | bin_filter = args[2][:6] # Extract first 6 digits as BIN filter 276 | logger.info(f"BIN filter applied: {bin_filter}") 277 | else: 278 | # Otherwise, treat it as a bank name 279 | bank_name = " ".join(args[2:]) 280 | logger.info(f"Bank filter applied: {bank_name}") 281 | 282 | # Enforce maximum limit based on user role 283 | max_lim = ADMIN_LIMIT if user_id in ADMIN_IDS else DEFAULT_LIMIT 284 | if limit > max_lim: 285 | await client.send_message(message.chat.id, f"Sorry Bro! Amount over Max limit is {max_lim} ❌") 286 | logger.warning(f"Limit exceeded: {limit} > {max_lim}") 287 | return 288 | 289 | # Send a temporary message to check the username 290 | temporary_msg = await client.send_message(message.chat.id, "Checking The Username...") 291 | await asyncio.sleep(1.5) 292 | 293 | # Start scraping 294 | await temporary_msg.edit_text("Scraping In Progress") 295 | scrapped_results = await scrape_messages(user, chat.id, limit, start_number=start_number, bank_name=bank_name) 296 | unique_messages, duplicates_removed = remove_duplicates(scrapped_results) 297 | 298 | if not unique_messages: 299 | await temporary_msg.edit_text("Sorry Bro ❌ No Credit Card Found") 300 | else: 301 | await send_results(client, temporary_msg, unique_messages, duplicates_removed, channel_name, bin_filter=bin_filter, bank_filter=bank_name) 302 | 303 | @app.on_message(filters.command(["mc", "multiscr", "mscr"], prefixes=["/", ".", ",", "!"]) & (filters.group | filters.private)) 304 | async def mc_cmd(client, message): 305 | args = message.text.split()[1:] 306 | if len(args) < 2: 307 | await client.send_message(message.chat.id, "⚠️ Provide at least one channel username") 308 | logger.warning("Invalid command: Missing arguments") 309 | return 310 | 311 | channel_identifiers = args[:-1] 312 | limit = int(args[-1]) 313 | user_id = message.from_user.id if message.from_user else None 314 | 315 | max_lim = ADMIN_LIMIT if user_id in ADMIN_IDS else DEFAULT_LIMIT 316 | if limit > max_lim: 317 | await client.send_message(message.chat.id, f"Sorry Bro! Amount over Max limit is {max_lim} ❌") 318 | logger.warning(f"Limit exceeded: {limit} > {max_lim}") 319 | return 320 | 321 | temporary_msg = await client.send_message(message.chat.id, "Scraping In Progress") 322 | all_messages = [] 323 | tasks = [] 324 | 325 | for channel_identifier in channel_identifiers: 326 | parsed_url = urlparse(channel_identifier) 327 | channel_username = parsed_url.path.lstrip('/') if not parsed_url.scheme else channel_identifier 328 | 329 | tasks.append(scrape_messages_task(user, channel_username, limit, client, message)) 330 | 331 | results = await asyncio.gather(*tasks) 332 | for result in results: 333 | all_messages.extend(result) 334 | 335 | unique_messages, duplicates_removed = remove_duplicates(all_messages) 336 | unique_messages = unique_messages[:limit] 337 | 338 | if not unique_messages: 339 | await temporary_msg.edit_text("Sorry Bro ❌ No Credit Card Found") 340 | else: 341 | await send_results(client, temporary_msg, unique_messages, duplicates_removed, "Multiple Chats") 342 | 343 | async def scrape_messages_task(client, channel_username, limit, bot_client, message): 344 | try: 345 | chat = None 346 | if channel_username.startswith("https://t.me/+"): 347 | invite_link = channel_username 348 | temporary_msg = await bot_client.send_message(message.chat.id, "Checking Username...") 349 | joined = await join_private_chat(client, invite_link) 350 | if not joined: 351 | request_sent = await send_join_request(client, invite_link, temporary_msg) 352 | if not request_sent: 353 | return [] 354 | else: 355 | await temporary_msg.delete() 356 | chat = await client.get_chat(invite_link) 357 | else: 358 | chat = await client.get_chat(channel_username) 359 | 360 | return await scrape_messages(client, chat.id, limit) 361 | except Exception as e: 362 | await bot_client.send_message(message.chat.id, f"Hey Bro! 🥲 Incorrect username for {channel_username} ❌") 363 | logger.error(f"Failed to scrape from {channel_username}: {e}") 364 | return [] 365 | 366 | @app.on_message(filters.command("start", prefixes=["/", ".", ",", "!"]) & (filters.group | filters.private)) 367 | async def start(client, message): 368 | buttons = [ 369 | [InlineKeyboardButton("Update Channel", url="https://t.me/Modvip_rm"), InlineKeyboardButton("My Dev👨‍💻", user_id=7303810912)] 370 | ] 371 | await client.send_message(message.chat.id, START_MESSAGE, parse_mode=ParseMode.HTML, disable_web_page_preview=True, reply_markup=InlineKeyboardMarkup(buttons)) 372 | 373 | if __name__ == "__main__": 374 | setup_scr_handler(app) 375 | user.start() 376 | app.run() 377 | --------------------------------------------------------------------------------