File size: 7,020 Bytes
db78256 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
from asyncio import sleep
from time import time
from secrets import token_hex
from pyrogram.errors import FloodWait, InputUserDeactivated, UserIsBlocked
from ..core.config_manager import Config
from ..core.tg_client import TgClient
from ..helper.ext_utils.bot_utils import new_task
from ..helper.ext_utils.db_handler import database
from ..helper.ext_utils.status_utils import get_readable_time
from ..helper.telegram_helper.message_utils import (
edit_message,
send_message,
)
bc_cache = {}
async def delete_broadcast(bc_id, message):
"""Delete broadcasted messages based on the broadcast ID."""
if bc_id not in bc_cache:
return await send_message(message, "Invalid Broadcast ID!")
temp_wait = await send_message(
message, "<i>Deleting the Broadcasted Message! Please Wait ...</i>"
)
total, success, failed = 0, 0, 0
msgs = bc_cache.get(bc_id, [])
for uid, msg_id in msgs:
try:
await (await TgClient.bot.get_messages(uid, msg_id)).delete()
success += 1
except FloodWait as e:
await sleep(e.value)
await (await TgClient.bot.get_messages(uid, msg_id)).delete()
success += 1
except Exception as e:
print(f"Error deleting message for user {uid}: {e}")
failed += 1
total += 1
return await edit_message(
temp_wait,
f"""⌬ <b><i>Broadcast Deleted Stats :</i></b>
┠ <b>Total Users:</b> <code>{total}</code>
┠ <b>Success:</b> <code>{success}</code>
┖ <b>Failed Attempts:</b> <code>{failed}</code>
<b>Broadcast ID:</b> <code>{bc_id}</code>""",
)
async def edit_broadcast(bc_id, message, rply):
"""Edit broadcasted messages based on the broadcast ID."""
if bc_id not in bc_cache:
return await send_message(message, "Invalid Broadcast ID!")
temp_wait = await send_message(
message, "<i>Editing the Broadcasted Message! Please Wait ...</i>"
)
total, success, failed = 0, 0, 0
for uid, msg_id in bc_cache[bc_id]:
msg = await TgClient.bot.get_messages(uid, msg_id)
if hasattr(msg, "forward_from"):
return await edit_message(
temp_wait,
"<i>Forwarded Messages can't be Edited, Only can be Deleted!</i>",
)
try:
await msg.edit(
text=rply.text,
entities=rply.entities,
reply_markup=rply.reply_markup,
)
await sleep(0.3)
success += 1
except FloodWait as e:
await sleep(e.value)
await msg.edit(
text=rply.text,
entities=rply.entities,
reply_markup=rply.reply_markup,
)
success += 1
except Exception as e:
print(f"Error editing message for user {uid}: {e}")
failed += 1
total += 1
return await edit_message(
temp_wait,
f"""⌬ <b><i>Broadcast Edited Stats :</i></b>
┠ <b>Total Users:</b> <code>{total}</code>
┠ <b>Success:</b> <code>{success}</code>
┖ <b>Failed Attempts:</b> <code>{failed}</code>
<b>Broadcast ID:</b> <code>{bc_id}</code>""",
)
@new_task
async def broadcast(_, message):
"""Handle different broadcast actions: send, edit, delete, or forward."""
bc_id, forwarded, quietly, deleted, edited = "", False, False, False, False
if not Config.DATABASE_URL:
return await send_message(
message, "DATABASE_URL not provided to fetch PM Users!"
)
rply = message.reply_to_message
if len(message.command) > 1:
if not message.command[1].startswith("-"):
bc_id = (
message.command[1] if bc_cache.get(message.command[1], False) else ""
)
if not bc_id:
return await send_message(
message,
"<i>Broadcast ID not found! After Restart, you can't edit or delete broadcasted messages...</i>",
)
for arg in message.command:
if arg in ["-f", "-forward"] and rply:
forwarded = True
if arg in ["-q", "-quiet"] and rply:
quietly = True
elif arg in ["-d", "-delete"] and bc_id:
deleted = True
elif arg in ["-e", "-edit"] and bc_id and rply:
edited = True
if not bc_id and not rply:
return await send_message(
message,
"""<b>By replying to msg to Broadcast:</b>
/broadcast bc_id -d -e -f -q
<b>Forward Broadcast with Tag:</b> -f or -forward
/cmd [reply_msg] -f
<b>Quietly Broadcast msg:</b> -q or -quiet
/cmd [reply_msg] -q -f
<b>Edit Broadcast msg:</b> -e or -edit
/cmd [reply_edited_msg] broadcast_id -e
<b>Delete Broadcast msg:</b> -d or -delete
/bc broadcast_id -d
<b>Notes:</b>
1. Broadcast msgs can be only edited or deleted until restart.
2. Forwarded msgs can't be Edited""",
)
if deleted:
return await delete_broadcast(bc_id, message)
elif edited:
return await edit_broadcast(bc_id, message, rply)
# Broadcasting logic
start_time = time()
status = """⌬ <b><i>Broadcast Stats :</i></b>
┠ <b>Total Users:</b> <code>{t}</code>
┠ <b>Success:</b> <code>{s}</code>
┠ <b>Blocked Users:</b> <code>{b}</code>
┠ <b>Deleted Accounts:</b> <code>{d}</code>
┖ <b>Unsuccess Attempt:</b> <code>{u}</code>"""
updater = time()
bc_hash, bc_msgs = token_hex(5), []
pls_wait = await send_message(message, status.format(t=0, s=0, b=0, d=0, u=0))
t, s, b, d, u = 0, 0, 0, 0, 0
for uid in await database.get_pm_uids():
try:
bc_msg = (
await rply.forward(uid, disable_notification=quietly)
if forwarded
else await rply.copy(uid, disable_notification=quietly)
)
s += 1
except FloodWait as e:
await sleep(e.value * 1.1)
bc_msg = (
await rply.forward(uid, disable_notification=quietly)
if forwarded
else await rply.copy(uid, disable_notification=quietly)
)
s += 1
except UserIsBlocked:
await database.rm_pm_user(uid)
b += 1
except InputUserDeactivated:
await database.rm_pm_user(uid)
d += 1
except Exception as e:
print(f"Error broadcasting message to user {uid}: {e}")
u += 1
if bc_msg:
bc_msgs.append((uid, bc_msg.id))
t += 1
if (time() - updater) > 10:
await edit_message(pls_wait, status.format(t=t, s=s, b=b, d=d, u=u))
updater = time()
bc_cache[bc_hash] = bc_msgs
await edit_message(
pls_wait,
f"{status.format(t=t, s=s, b=b, d=d, u=u)}\n\n<b>Elapsed Time:</b> <code>{get_readable_time(time() - start_time)}</code>\n<b>Broadcast ID:</b> <code>{bc_hash}</code>",
)
|