Thaimozhi commited on
Commit
18ce7e4
·
1 Parent(s): e77de59

Fix Pyrogram PeerIdInvalid spam loop

Browse files
Files changed (1) hide show
  1. plugins/force_subs.py +51 -6
plugins/force_subs.py CHANGED
@@ -10,28 +10,64 @@ IMAGE_URL = "https://graph.org/file/a27d85469761da836337c.jpg"
10
  async def not_subscribed(_, __, message):
11
  for channel in FORCE_SUB_CHANNELS:
12
  try:
13
- user = await message._client.get_chat_member(channel, message.from_user.id)
 
 
14
  if user.status in {"kicked", "left"}:
15
  return True
16
  except UserNotParticipant:
17
  return True
 
 
 
 
18
  return False
19
 
 
 
 
20
  @Client.on_message(filters.private & filters.create(not_subscribed))
21
  async def forces_sub(client, message):
22
  not_joined_channels = []
 
23
  for channel in FORCE_SUB_CHANNELS:
24
  try:
25
- user = await client.get_chat_member(channel, message.from_user.id)
 
26
  if user.status in {"kicked", "left"}:
27
  not_joined_channels.append(channel)
28
  except UserNotParticipant:
29
  not_joined_channels.append(channel)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  buttons = [
32
  [
33
  InlineKeyboardButton(
34
- text=f"• ᴊᴏɪɴ {channel.capitalize()} •", url=f"https://t.me/{channel}"
35
  )
36
  ]
37
  for channel in not_joined_channels
@@ -56,13 +92,22 @@ async def check_subscription(client, callback_query: CallbackQuery):
56
  user_id = callback_query.from_user.id
57
  not_joined_channels = []
58
 
 
59
  for channel in FORCE_SUB_CHANNELS:
60
  try:
61
- user = await client.get_chat_member(channel, user_id)
 
62
  if user.status in {"kicked", "left"}:
63
  not_joined_channels.append(channel)
64
  except UserNotParticipant:
65
  not_joined_channels.append(channel)
 
 
 
 
 
 
 
66
 
67
  if not not_joined_channels:
68
  new_text = "**ʏᴏᴜ ʜᴀᴠᴇ ᴊᴏɪɴᴇᴅ ᴀʟʟ ᴛʜᴇ ʀᴇǫᴜɪʀᴇᴅ ᴄʜᴀɴɴᴇʟs. ᴛʜᴀɴᴋ ʏᴏᴜ! 😊 /start ɴᴏᴡ**"
@@ -77,8 +122,8 @@ async def check_subscription(client, callback_query: CallbackQuery):
77
  buttons = [
78
  [
79
  InlineKeyboardButton(
80
- text=f"• ᴊᴏɪɴ {channel.capitalize()} •",
81
- url=f"https://t.me/{channel}",
82
  )
83
  ]
84
  for channel in not_joined_channels
 
10
  async def not_subscribed(_, __, message):
11
  for channel in FORCE_SUB_CHANNELS:
12
  try:
13
+ # Handle channel IDs by ensuring they are integers if possible
14
+ peer = int(channel) if str(channel).lstrip('-').isdigit() else channel
15
+ user = await message._client.get_chat_member(peer, message.from_user.id)
16
  if user.status in {"kicked", "left"}:
17
  return True
18
  except UserNotParticipant:
19
  return True
20
+ except Exception as e:
21
+ # Any other exception (PeerIdInvalid, ChatAdminRequired, etc) is a Bot Config error.
22
+ # We must intercept it so forces_sub can explain the Pyrogram error.
23
+ return True
24
  return False
25
 
26
+ # Anti-spam cache mapping to prevent 100+ error spams when forwarding folders
27
+ force_sub_spam_cache = {}
28
+
29
  @Client.on_message(filters.private & filters.create(not_subscribed))
30
  async def forces_sub(client, message):
31
  not_joined_channels = []
32
+ admin_error = None
33
  for channel in FORCE_SUB_CHANNELS:
34
  try:
35
+ peer = int(channel) if str(channel).lstrip('-').isdigit() else channel
36
+ user = await client.get_chat_member(peer, message.from_user.id)
37
  if user.status in {"kicked", "left"}:
38
  not_joined_channels.append(channel)
39
  except UserNotParticipant:
40
  not_joined_channels.append(channel)
41
+ except Exception as e:
42
+ # Captures ANY Pyrogram validation crash (PeerIdInvalid, ChatAdminRequired, etc)
43
+ admin_error = f"[{type(e).__name__}] {str(e)}"
44
+ not_joined_channels.append(channel)
45
+
46
+ # Anti-spam logic: don't bombard user with 100 errors instantly
47
+ user_id = message.from_user.id
48
+ import time
49
+ last_sent = force_sub_spam_cache.get(user_id, 0)
50
+ if time.time() - last_sent < 15:
51
+ # Ignore this message if we already warned them within the last 15 seconds
52
+ return
53
+
54
+ force_sub_spam_cache[user_id] = time.time()
55
+
56
+ if admin_error:
57
+ text = (
58
+ "⚠️ **Bot Configuration Error!** ⚠️\n\n"
59
+ f"The bot is failing to verify the Force-Sub channel due to an API error:\n\n"
60
+ f"`{admin_error}`\n\n"
61
+ "**Fixes:**\n"
62
+ "1. Make sure the bot is an Admin.\n"
63
+ "2. If it's a private channel, you MUST forward at least 1 message from the channel to the bot so it can learn the channel ID!"
64
+ )
65
+ return await message.reply_text(text)
66
 
67
  buttons = [
68
  [
69
  InlineKeyboardButton(
70
+ text=f"• ᴊᴏɪɴ Cʜᴀɴɴᴇʟ •", url=f"https://t.me/{str(channel).replace('@', '')}" if not str(channel).lstrip('-').isdigit() else "https://t.me/codeflix_bots"
71
  )
72
  ]
73
  for channel in not_joined_channels
 
92
  user_id = callback_query.from_user.id
93
  not_joined_channels = []
94
 
95
+ admin_error = False
96
  for channel in FORCE_SUB_CHANNELS:
97
  try:
98
+ peer = int(channel) if str(channel).lstrip('-').isdigit() else channel
99
+ user = await client.get_chat_member(peer, user_id)
100
  if user.status in {"kicked", "left"}:
101
  not_joined_channels.append(channel)
102
  except UserNotParticipant:
103
  not_joined_channels.append(channel)
104
+ except Exception as e:
105
+ if "CHAT_ADMIN_REQUIRED" in str(e):
106
+ admin_error = True
107
+ not_joined_channels.append(channel)
108
+
109
+ if admin_error:
110
+ return await callback_query.answer("⚠️ The bot is not an admin in the Force Sub channel!", show_alert=True)
111
 
112
  if not not_joined_channels:
113
  new_text = "**ʏᴏᴜ ʜᴀᴠᴇ ᴊᴏɪɴᴇᴅ ᴀʟʟ ᴛʜᴇ ʀᴇǫᴜɪʀᴇᴅ ᴄʜᴀɴɴᴇʟs. ᴛʜᴀɴᴋ ʏᴏᴜ! 😊 /start ɴᴏᴡ**"
 
122
  buttons = [
123
  [
124
  InlineKeyboardButton(
125
+ text=f"• ᴊᴏɪɴ Cʜᴀɴɴᴇʟ •",
126
+ url=f"https://t.me/{str(channel).replace('@', '')}" if not str(channel).lstrip('-').isdigit() else "https://t.me/codeflix_bots",
127
  )
128
  ]
129
  for channel in not_joined_channels