feds.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. """
  2. MIT License
  3. Copyright (c) 2023 SI_NN_ER_LS
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated documentation files (the "Software"), to deal
  6. in the Software without restriction, including without limitation the rights
  7. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the Software is
  9. furnished to do so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. """
  20. import uuid
  21. import asyncio
  22. from wbb.utils.dbfeds import *
  23. from wbb import app, SUDOERS, LOG_GROUP_ID, BOT_ID
  24. from pyrogram import filters
  25. from pyrogram.enums import ChatMemberStatus, ChatType, ParseMode
  26. from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
  27. from wbb.utils.functions import extract_user, extract_user_and_reason
  28. from pyrogram.errors import FloodWait
  29. from wbb.core.decorators.errors import capture_err
  30. __MODULE__ = "Federation"
  31. __HELP__ = """
  32. Everything is fun, until a spammer starts entering your group, and you have to block it. Then you need to start banning more, and more, and it hurts.
  33. But then you have many groups, and you don't want this spammer to be in one of your groups - how can you deal? Do you have to manually block it, in all your groups?\n
  34. **No longer!** With Federation, you can make a ban in one chat overlap with all other chats.\n
  35. You can even designate federation admins, so your trusted admin can ban all the spammers from chats you want to protect.\n\n
  36. """
  37. SUPPORT_CHAT = "@WBBSupport"
  38. @app.on_message(filters.command("newfed"))
  39. @capture_err
  40. async def new_fed(client, message):
  41. chat = message.chat
  42. user = message.from_user
  43. if message.chat.type != ChatType.PRIVATE:
  44. await message.reply_text(
  45. "Federations can only be created by privately messaging me."
  46. )
  47. return
  48. if len(message.command) < 2:
  49. await message.reply_text("Please write the name of the federation!")
  50. return
  51. fednam = message.text.split(None, 1)[1]
  52. if not fednam == "":
  53. fed_id = str(uuid.uuid4())
  54. fed_name = fednam
  55. x = await fedsdb.update_one(
  56. {"fed_id": str(fed_id)},
  57. {
  58. "$set": {
  59. "fed_name": str(fed_name),
  60. "owner_id": int(user.id),
  61. "fadmins": [],
  62. "owner_mention": user.mention,
  63. "banned_users": [],
  64. "chat_ids": [],
  65. "log_group_id": LOG_GROUP_ID,
  66. }
  67. },
  68. upsert=True,
  69. )
  70. if not x:
  71. await message.reply_text(
  72. f"Can't federate! Please contact {SUPPORT_CHAT} if the problem persist."
  73. )
  74. return
  75. await message.reply_text(
  76. "**You have succeeded in creating a new federation!**"
  77. "\nName: `{}`"
  78. "\nID: `{}`"
  79. "\n\nUse the command below to join the federation:"
  80. "\n`/joinfed {}`".format(fed_name, fed_id, fed_id),
  81. parse_mode=ParseMode.MARKDOWN,
  82. )
  83. try:
  84. await app.send_message(
  85. LOG_GROUP_ID,
  86. "New Federation: <b>{}</b>\nID: <pre>{}</pre>".format(fed_name, fed_id),
  87. parse_mode=ParseMode.HTML,
  88. )
  89. except:
  90. log.info("Cannot send a message to EVENT_LOGS")
  91. else:
  92. await message.reply_text("Please write down the name of the federation")
  93. @app.on_message(filters.command("delfed"))
  94. @capture_err
  95. async def del_fed(client, message):
  96. chat = message.chat
  97. user = message.from_user
  98. if message.chat.type != ChatType.PRIVATE:
  99. await message.reply_text(
  100. "Federations can only be deleted by privately messaging me."
  101. )
  102. return
  103. args = message.text.split(" ", 1)
  104. if len(args) > 1:
  105. is_fed_id = args[1].strip()
  106. getinfo = await get_fed_info(is_fed_id)
  107. if getinfo is False:
  108. await message.reply_text("This federation does not exist.")
  109. return
  110. if getinfo["owner_id"] == user.id or user.id == SUDOERS:
  111. fed_id = is_fed_id
  112. else:
  113. await message.reply_text("Only federation owners can do this!")
  114. return
  115. else:
  116. await message.reply_text("What should I delete?")
  117. return
  118. is_owner = await is_user_fed_owner(fed_id, user.id)
  119. if is_owner is False:
  120. await message.reply_text("Only federation owners can do this!")
  121. return
  122. await message.reply_text(
  123. "You sure you want to delete your federation? This cannot be reverted, you will lose your entire ban list, and '{}' will be permanently lost.".format(
  124. getinfo["fed_name"]
  125. ),
  126. reply_markup=InlineKeyboardMarkup(
  127. [
  128. [
  129. InlineKeyboardButton(
  130. "⚠️ Delete Federation ⚠️",
  131. callback_data=f"rmfed_{fed_id}",
  132. )
  133. ],
  134. [InlineKeyboardButton("Cancel", callback_data="rmfed_cancel")],
  135. ]
  136. ),
  137. )
  138. @app.on_message(filters.command("fedtransfer"))
  139. @capture_err
  140. async def fedtransfer(client, message):
  141. chat = message.chat
  142. user = message.from_user
  143. if message.chat.type != ChatType.PRIVATE:
  144. await message.reply_text(
  145. "Federations can only be transferred by privately messaging me."
  146. )
  147. return
  148. is_feds = await get_feds_by_owner(int(user.id))
  149. if not is_feds:
  150. return await message.reply_text("**You haven't created any federations.**")
  151. if len(message.command) < 2:
  152. return await message.reply_text(
  153. "**You needed to specify a user or reply to their message!**"
  154. )
  155. user_id, fed_id = await extract_user_and_reason(message)
  156. if not user_id:
  157. return await message.reply_text("I can't find that user.")
  158. if not fed_id:
  159. return await message.reply(
  160. "you need to provide a Fed Id.\n\nUsage:\n/fedtransfer @usename Fed_Id."
  161. )
  162. is_owner = await is_user_fed_owner(fed_id, user.id)
  163. if is_owner is False:
  164. await message.reply_text("Only federation owners can do this!")
  165. return
  166. await message.reply_text(
  167. "**You sure you want to transfer your federation? This cannot be reverted.**",
  168. reply_markup=InlineKeyboardMarkup(
  169. [
  170. [
  171. InlineKeyboardButton(
  172. "⚠️ Transfer Federation ⚠️",
  173. callback_data=f"trfed_{user_id}|{fed_id}",
  174. )
  175. ],
  176. [InlineKeyboardButton("Cancel", callback_data="trfed_cancel")],
  177. ]
  178. ),
  179. )
  180. @app.on_message(filters.command("myfeds"))
  181. @capture_err
  182. async def myfeds(client, message):
  183. user = message.from_user
  184. is_feds = await get_feds_by_owner(int(user.id))
  185. if is_feds:
  186. response_text = "\n\n".join(
  187. [
  188. f"{i + 1}.\n**Fed Name:** {fed['fed_name']}\n**Fed Id:** `{fed['fed_id']}`"
  189. for i, fed in enumerate(is_feds)
  190. ]
  191. )
  192. await message.reply_text(
  193. f"**Here are the federations you have created:**\n\n{response_text}"
  194. )
  195. else:
  196. await message.reply_text("**You haven't created any federations.**")
  197. @app.on_message(filters.command("renamefed"))
  198. @capture_err
  199. async def rename_fed(client, message):
  200. user = message.from_user
  201. msg = message
  202. args = msg.text.split(None, 2)
  203. if len(args) < 3:
  204. return await msg.reply_text("usage: /renamefed <fed_id> <newname>")
  205. fed_id, newname = args[1], args[2]
  206. verify_fed = await get_fed_info(fed_id)
  207. if not verify_fed:
  208. return await msg.reply_text("This fed does not exist in my database!")
  209. if await is_user_fed_owner(fed_id, user.id):
  210. fedsdb.update_one(
  211. {"fed_id": str(fed_id)},
  212. {"$set": {"fed_name": str(newname), "owner_id": int(user.id)}},
  213. upsert=True,
  214. )
  215. await msg.reply_text(f"Successfully renamed your fed name to {newname}!")
  216. else:
  217. await msg.reply_text("Only federation owner can do this!")
  218. @app.on_message(filters.command(["setfedlog", "unsetfedlog"]))
  219. @capture_err
  220. async def fed_log(client, message):
  221. chat = message.chat
  222. user = message.from_user
  223. if message.chat.type == ChatType.PRIVATE:
  224. await message.reply_text(
  225. "Send this command on the chat which you need to set as fed log channel."
  226. )
  227. return
  228. member = await app.get_chat_member(chat.id, user.id)
  229. if (
  230. member.status == ChatMemberStatus.OWNER
  231. or member.status == ChatMemberStatus.ADMINISTRATOR
  232. ):
  233. if len(message.command) < 2:
  234. return await message.reply_text(
  235. "Please provide the Id of the federation with the command!"
  236. )
  237. fed_id = message.text.split(" ", 1)[1].strip()
  238. info = await get_fed_info(fed_id)
  239. if info is False:
  240. await message.reply_text("This federation does not exist.")
  241. return
  242. if await is_user_fed_owner(fed_id, user.id):
  243. if "/unsetfedlog" in message.text:
  244. log_group_id = LOG_GROUP_ID
  245. else:
  246. log_group_id = chat.id
  247. loged = await set_log_chat(fed_id, log_group_id)
  248. if "/unsetfedlog" in message.text:
  249. return await message.reply_text("log channel removed successfully.")
  250. else:
  251. await message.reply_text("log channel set successfully.")
  252. else:
  253. await message.reply_text(
  254. "You need to be the chat owner or admin to use this command."
  255. )
  256. @app.on_message(filters.command("chatfed"))
  257. @capture_err
  258. async def fed_chat(client, message):
  259. chat = message.chat
  260. user = message.from_user
  261. fed_id = await get_fed_id(chat.id)
  262. member = await app.get_chat_member(chat.id, user.id)
  263. if (
  264. member.status == ChatMemberStatus.OWNER
  265. or member.status == ChatMemberStatus.ADMINISTRATOR
  266. ):
  267. pass
  268. else:
  269. await message.reply_text("You must be an admin to execute this command")
  270. return
  271. if not fed_id:
  272. await message.reply_text("This group is not in any federation!")
  273. return
  274. info = await get_fed_info(fed_id)
  275. text = "This group is part of the following federation:"
  276. text += "\n{} (ID: <code>{}</code>)".format(info["fed_name"], fed_id)
  277. await message.reply_text(text, parse_mode=ParseMode.HTML)
  278. @app.on_message(filters.command("joinfed"))
  279. @capture_err
  280. async def join_fed(client, message):
  281. chat = message.chat
  282. user = message.from_user
  283. if message.chat.type == ChatType.PRIVATE:
  284. await message.reply_text(
  285. "This command is specific to groups, not our pm!",
  286. )
  287. return
  288. member = await app.get_chat_member(chat.id, user.id)
  289. fed_id = await get_fed_id(int(chat.id))
  290. if user.id in SUDOERS:
  291. pass
  292. else:
  293. if member.status == ChatMemberStatus.OWNER:
  294. pass
  295. else:
  296. await message.reply_text("Only group creators can use this command!")
  297. return
  298. if fed_id:
  299. await message.reply_text("You cannot join two federations from one chat")
  300. return
  301. args = message.text.split(" ", 1)
  302. if len(args) > 1:
  303. fed_id = args[1].strip()
  304. getfed = await search_fed_by_id(fed_id)
  305. if getfed is False:
  306. await message.reply_text("Please enter a valid federation ID")
  307. return
  308. x = await chat_join_fed(fed_id, chat.title, chat.id)
  309. if not x:
  310. await message.reply_text(
  311. f"Failed to join federation! Please contact {SUPPORT_CHAT} if this problem persists!"
  312. )
  313. return
  314. get_fedlog = getfed["log_group_id"]
  315. if get_fedlog:
  316. await app.send_message(
  317. get_fedlog,
  318. "Chat **{}** has joined the federation **{}**".format(
  319. chat.title, getfed["fed_name"]
  320. ),
  321. parse_mode=ParseMode.MARKDOWN,
  322. )
  323. await message.reply_text(
  324. "This group has joined the federation: {}!".format(getfed["fed_name"])
  325. )
  326. else:
  327. await message.reply_text(
  328. "You need to specify which federation you're asking about by giving me a FedID!"
  329. )
  330. @app.on_message(filters.command("leavefed"))
  331. @capture_err
  332. async def leave_fed(client, message):
  333. chat = message.chat
  334. user = message.from_user
  335. if message.chat.type == ChatType.PRIVATE:
  336. await message.reply_text(
  337. "This command is specific to groups, not our pm!",
  338. )
  339. return
  340. fed_id = await get_fed_id(int(chat.id))
  341. fed_info = await get_fed_info(fed_id)
  342. member = await app.get_chat_member(chat.id, user.id)
  343. if member.status == ChatMemberStatus.OWNER or user.id in SUDOERS:
  344. if await chat_leave_fed(int(chat.id)) is True:
  345. get_fedlog = fed_info["log_group_id"]
  346. if get_fedlog:
  347. await app.send_message(
  348. get_fedlog,
  349. "Chat **{}** has left the federation **{}**".format(
  350. chat.title, fed_info["fed_name"]
  351. ),
  352. parse_mode=ParseMode.MARKDOWN,
  353. )
  354. await message.reply_text(
  355. "This group has left the federation {}!".format(fed_info["fed_name"]),
  356. )
  357. else:
  358. await message.reply_text(
  359. "How can you leave a federation that you never joined?!"
  360. )
  361. else:
  362. await message.reply_text("Only group creators can use this command!")
  363. @app.on_message(filters.command("fedchats"))
  364. @capture_err
  365. async def fed_chat(client, message):
  366. chat = message.chat
  367. user = message.from_user
  368. if message.chat.type != ChatType.PRIVATE:
  369. await message.reply_text(
  370. "Fedchats can only be checked by privately messaging me."
  371. )
  372. return
  373. if len(message.command) < 2:
  374. await message.reply_text(
  375. "Please write the Id of the federation!\n\nUsage:\n/fedchats fed_id"
  376. )
  377. return
  378. args = message.text.split(" ", 1)
  379. if len(args) > 1:
  380. fed_id = args[1].strip()
  381. info = await get_fed_info(fed_id)
  382. if info is False:
  383. await message.reply_text("This federation does not exist.")
  384. return
  385. fed_owner = info["owner_id"]
  386. fed_admins = info["fadmins"]
  387. all_admins = [fed_owner] + fed_admins + [int(BOT_ID)]
  388. if user.id in all_admins or user.id in SUDOERS:
  389. pass
  390. else:
  391. return await message.reply_text(
  392. "You need to be a Fed Admin to use this command"
  393. )
  394. chat_ids, chat_names = await chat_id_and_names_in_fed(fed_id)
  395. if not chat_ids:
  396. return await message.reply_text("There are no chats in this federation!")
  397. text = "\n".join(
  398. [
  399. f"${chat_name} [`{chat_id}`]"
  400. for chat_id, chat_name in zip(chat_ids, chat_names)
  401. ]
  402. )
  403. await message.reply_text(
  404. f"**Here are the list of chats connected to this federation:**\n\n{text}"
  405. )
  406. @app.on_message(filters.command("fpromote"))
  407. @capture_err
  408. async def fpromote(client, message):
  409. chat = message.chat
  410. user = message.from_user
  411. msg = message
  412. if message.chat.type == ChatType.PRIVATE:
  413. await message.reply_text(
  414. "This command is specific to groups, not our pm!",
  415. )
  416. return
  417. fed_id = await get_fed_id(chat.id)
  418. if not fed_id:
  419. return await message.reply_text(
  420. "You need to add a federation to this chat first!"
  421. )
  422. if await is_user_fed_owner(fed_id, user.id) or user.id in SUDOERS:
  423. user_id = await extract_user(msg)
  424. if user_id is None:
  425. await message.reply_text("Failed to extract user from the message.")
  426. return
  427. check_user = await check_banned_user(fed_id, user_id)
  428. if check_user:
  429. user = await app.get_users(user_id)
  430. reason = check_user["reason"]
  431. date = check_user["date"]
  432. return await message.reply_text(
  433. f"**User {user.mention} was Fed Banned.\nyou can unban the user and promote.\n\nReason: {reason}.\nDate: {date}.**"
  434. )
  435. getuser = await search_user_in_fed(fed_id, user_id)
  436. info = await get_fed_info(fed_id)
  437. get_owner = info["owner_id"]
  438. if user_id == get_owner:
  439. await message.reply_text(
  440. "You do know that the user is the federation owner, right? RIGHT?"
  441. )
  442. return
  443. if getuser:
  444. await message.reply_text(
  445. "I cannot promote users who are already federation admins! Can remove them if you want!"
  446. )
  447. return
  448. if user_id == BOT_ID:
  449. await message.reply_text(
  450. "I already am a federation admin in all federations!"
  451. )
  452. return
  453. res = await user_join_fed(str(fed_id), user_id)
  454. if res:
  455. await message.reply_text("Successfully Promoted!")
  456. else:
  457. await message.reply_text("Failed to promote!")
  458. else:
  459. await message.reply_text("Only federation owners can do this!")
  460. @app.on_message(filters.command("fdemote"))
  461. @capture_err
  462. async def fdemote(client, message):
  463. chat = message.chat
  464. user = message.from_user
  465. msg = message
  466. if message.chat.type == ChatType.PRIVATE:
  467. await message.reply_text(
  468. "This command is specific to groups, not our pm!",
  469. )
  470. return
  471. fed_id = await get_fed_id(chat.id)
  472. if not fed_id:
  473. return await message.reply_text(
  474. "You need to add a federation to this chat first!"
  475. )
  476. if await is_user_fed_owner(fed_id, user.id) or user.id in SUDOERS:
  477. user_id = await extract_user(msg)
  478. if user_id is None:
  479. await message.reply_text("Failed to extract user from the message.")
  480. return
  481. if user_id == BOT_ID:
  482. update.effective_message.reply_text(
  483. "The thing you are trying to demote me from will fail to work without me! Just saying."
  484. )
  485. return
  486. if await search_user_in_fed(fed_id, user_id) is False:
  487. await message.reply_text(
  488. "I cannot demote people who are not federation admins!"
  489. )
  490. return
  491. res = await user_demote_fed(fed_id, user_id)
  492. if res is True:
  493. await message.reply_text("Demoted from a Fed Admin!")
  494. else:
  495. await message.reply_text("Demotion failed!")
  496. else:
  497. await message.reply_text("Only federation owners can do this!")
  498. return
  499. @app.on_message(filters.command(["fban", "sfban"]))
  500. @capture_err
  501. async def fban_user(client, message):
  502. chat = message.chat
  503. from_user = message.from_user
  504. if message.chat.type == ChatType.PRIVATE:
  505. await message.reply_text("This command is specific to groups, not our pm!.")
  506. return
  507. fed_id = await get_fed_id(chat.id)
  508. if not fed_id:
  509. return await message.reply_text("**This chat is not a part of any federation.")
  510. info = await get_fed_info(fed_id)
  511. fed_owner = info["owner_id"]
  512. fed_admins = info["fadmins"]
  513. all_admins = [fed_owner] + fed_admins + [int(BOT_ID)]
  514. if from_user.id in all_admins or from_user.id in SUDOERS:
  515. pass
  516. else:
  517. return await message.reply_text(
  518. "You need to be a Fed Admin to use this command"
  519. )
  520. if len(message.command) < 2:
  521. return await message.reply_text(
  522. "**You needed to specify a user or reply to their message!**"
  523. )
  524. user_id, reason = await extract_user_and_reason(message)
  525. user = await app.get_users(user_id)
  526. if not user_id:
  527. return await message.reply_text("I can't find that user.")
  528. if user_id in all_admins or user_id in SUDOERS:
  529. return await message.reply_text("I can't ban that user.")
  530. check_user = await check_banned_user(fed_id, user_id)
  531. if check_user:
  532. reason = check_user["reason"]
  533. date = check_user["date"]
  534. return await message.reply_text(
  535. f"**User {user.mention} was already Fed Banned.\n\nReason: {reason}.\nDate: {date}.**"
  536. )
  537. if not reason:
  538. return await message.reply("No reason provided.")
  539. served_chats, _ = await chat_id_and_names_in_fed(fed_id)
  540. m = await message.reply_text(
  541. f"**Fed Banning {user.mention}!**"
  542. + f" **This Action Should Take About {len(served_chats)} Seconds.**"
  543. )
  544. await add_fban_user(fed_id, user_id, reason)
  545. number_of_chats = 0
  546. for served_chat in served_chats:
  547. try:
  548. chat_member = await app.get_chat_member(served_chat, user.id)
  549. if chat_member.status == ChatMemberStatus.MEMBER:
  550. await app.ban_chat_member(served_chat, user.id)
  551. if served_chat != chat.id:
  552. if not message.text.startswith("/s"):
  553. await app.send_message(
  554. served_chat, f"**Fed Banned {user.mention} !**"
  555. )
  556. number_of_chats += 1
  557. await asyncio.sleep(1)
  558. except FloodWait as e:
  559. await asyncio.sleep(int(e.value))
  560. except Exception:
  561. pass
  562. try:
  563. await app.send_message(
  564. user.id,
  565. f"Hello, You have been fed banned by {from_user.mention},"
  566. + " You can appeal for this ban by talking to him.",
  567. )
  568. except Exception:
  569. pass
  570. await m.edit(f"Fed Banned {user.mention} !")
  571. ban_text = f"""
  572. __**New Federation Ban**__
  573. **Origin:** {message.chat.title} [`{message.chat.id}`]
  574. **Admin:** {from_user.mention}
  575. **Banned User:** {user.mention}
  576. **Banned User ID:** `{user_id}`
  577. **Reason:** __{reason}__
  578. **Chats:** `{number_of_chats}`"""
  579. try:
  580. m2 = await app.send_message(
  581. info["log_group_id"],
  582. text=ban_text,
  583. disable_web_page_preview=True,
  584. )
  585. await m.edit(
  586. f"Fed Banned {user.mention} !\nAction Log: {m2.link}",
  587. disable_web_page_preview=True,
  588. )
  589. except Exception:
  590. await message.reply_text(
  591. "User Fbanned, But This Fban Action Wasn't Logged, Add Me In LOG_GROUP"
  592. )
  593. @app.on_message(filters.command(["unfban", "sunfban"]))
  594. @capture_err
  595. async def funban_user(client, message):
  596. chat = message.chat
  597. from_user = message.from_user
  598. if message.chat.type == ChatType.PRIVATE:
  599. await message.reply_text("This command is specific to groups, not our pm!.")
  600. return
  601. fed_id = await get_fed_id(chat.id)
  602. if not fed_id:
  603. return await message.reply_text("**This chat is not a part of any federation.")
  604. info = await get_fed_info(fed_id)
  605. fed_owner = info["owner_id"]
  606. fed_admins = info["fadmins"]
  607. all_admins = [fed_owner] + fed_admins + [int(BOT_ID)]
  608. if from_user.id in all_admins or from_user.id in SUDOERS:
  609. pass
  610. else:
  611. return await message.reply_text(
  612. "You need to be a Fed Admin to use this command"
  613. )
  614. if len(message.command) < 2:
  615. return await message.reply_text(
  616. "**You needed to specify a user or reply to their message!**"
  617. )
  618. user_id, reason = await extract_user_and_reason(message)
  619. user = await app.get_users(user_id)
  620. if not user_id:
  621. return await message.reply_text("I can't find that user.")
  622. if user_id in all_admins or user_id in SUDOERS:
  623. return await message.reply_text("**How can an admin ever be banned!.**")
  624. check_user = await check_banned_user(fed_id, user_id)
  625. if not check_user:
  626. return await message.reply_text(
  627. "**I can't unban a user who was never fedbanned.**"
  628. )
  629. if not reason:
  630. return await message.reply("No reason provided.")
  631. served_chats, _ = await chat_id_and_names_in_fed(fed_id)
  632. m = await message.reply_text(
  633. f"**Fed UnBanning {user.mention}!**"
  634. + f" **This Action Should Take About {len(served_chats)} Seconds.**"
  635. )
  636. await remove_fban_user(fed_id, user_id)
  637. number_of_chats = 0
  638. for served_chat in served_chats:
  639. try:
  640. chat_member = await app.get_chat_member(served_chat, user.id)
  641. if chat_member.status == ChatMemberStatus.BANNED:
  642. await app.unban_chat_member(served_chat, user.id)
  643. if served_chat != chat.id:
  644. if not message.text.startswith("/s"):
  645. await app.send_message(
  646. served_chat, f"**Fed UnBanned {user.mention} !**"
  647. )
  648. number_of_chats += 1
  649. await asyncio.sleep(1)
  650. except FloodWait as e:
  651. await asyncio.sleep(int(e.value))
  652. except Exception:
  653. pass
  654. try:
  655. await app.send_message(
  656. user.id,
  657. f"Hello, You have been fed unbanned by {from_user.mention},"
  658. + " You can thank him for his action.",
  659. )
  660. except Exception:
  661. pass
  662. await m.edit(f"Fed UnBanned {user.mention} !")
  663. ban_text = f"""
  664. __**New Federation UnBan**__
  665. **Origin:** {message.chat.title} [`{message.chat.id}`]
  666. **Admin:** {from_user.mention}
  667. **UnBanned User:** {user.mention}
  668. **UnBanned User ID:** `{user_id}`
  669. **Reason:** __{reason}__
  670. **Chats:** `{number_of_chats}`"""
  671. try:
  672. m2 = await app.send_message(
  673. info["log_group_id"],
  674. text=ban_text,
  675. disable_web_page_preview=True,
  676. )
  677. await m.edit(
  678. f"Fed UnBanned {user.mention} !\nAction Log: {m2.link}",
  679. disable_web_page_preview=True,
  680. )
  681. except Exception:
  682. await message.reply_text(
  683. "User FUnbanned, But This Fban Action Wasn't Logged, Add Me In LOG_GROUP"
  684. )
  685. @app.on_message(filters.command("fedstat"))
  686. async def fedstat(client, message):
  687. user = message.from_user
  688. if message.chat.type != ChatType.PRIVATE:
  689. await message.reply_text(
  690. "Federation Ban status can only be checked by privately messaging me."
  691. )
  692. return
  693. if len(message.command) < 2:
  694. await message.reply_text("Please provide me the user name and Fed Id!")
  695. return
  696. user_id, fed_id = await extract_user_and_reason(message)
  697. if not user_id:
  698. user_id = message.from_user.id
  699. fed_id = message.text.split(" ", 1)[1].strip()
  700. if not fed_id:
  701. return await message.reply_text(
  702. "provide me a Fed Id along with the command to search for."
  703. )
  704. info = await get_fed_info(fed_id)
  705. if not info:
  706. await message.reply_text("Please enter a valid fed id")
  707. else:
  708. check_user = await check_banned_user(fed_id, user_id)
  709. if check_user:
  710. user = await app.get_users(user_id)
  711. reason = check_user["reason"]
  712. date = check_user["date"]
  713. return await message.reply_text(
  714. f"**User {user.mention} was Fed Banned for:\n\nReason: {reason}.\nDate: {date}.**"
  715. )
  716. else:
  717. await message.reply_text(
  718. f"**User {user.mention} is not Fed Banned in this federation.**"
  719. )
  720. @app.on_message(filters.command("fbroadcast"))
  721. @capture_err
  722. async def fbroadcast_message(client, message):
  723. chat = message.chat
  724. from_user = message.from_user
  725. reply_message = message.reply_to_message
  726. if message.chat.type == ChatType.PRIVATE:
  727. await message.reply_text("This command is specific to groups, not our pm!.")
  728. return
  729. fed_id = await get_fed_id(chat.id)
  730. if not fed_id:
  731. return await message.reply_text("**This chat is not a part of any federation.")
  732. info = await get_fed_info(fed_id)
  733. fed_owner = info["owner_id"]
  734. fed_admins = info["fadmins"]
  735. all_admins = [fed_owner] + fed_admins + [int(BOT_ID)]
  736. if from_user.id in all_admins or from_user.id in SUDOERS:
  737. pass
  738. else:
  739. return await message.reply_text(
  740. "You need to be a Fed Admin to use this command"
  741. )
  742. if not reply_message:
  743. return await message.reply_text(
  744. "**You need to reply to a text message to Broadcasted it.**"
  745. )
  746. sleep_time = 0.1
  747. if reply_message.text:
  748. text = reply_message.text.markdown
  749. else:
  750. return await message.reply_text("You can only Broadcast text messages.")
  751. reply_markup = None
  752. if reply_message.reply_markup:
  753. reply_markup = InlineKeyboardMarkup(reply_message.reply_markup.inline_keyboard)
  754. sent = 0
  755. chats, _ = await chat_id_and_names_in_fed(fed_id)
  756. m = await message.reply_text(
  757. f"Broadcast in progress, will take {len(chats) * sleep_time} seconds."
  758. )
  759. for i in chats:
  760. try:
  761. await app.send_message(
  762. i,
  763. text=text,
  764. reply_markup=reply_markup,
  765. )
  766. sent += 1
  767. await asyncio.sleep(sleep_time)
  768. except FloodWait as e:
  769. await asyncio.sleep(int(e.value))
  770. except Exception:
  771. pass
  772. await m.edit(f"**Broadcasted Message In {sent} Chats.**")
  773. @app.on_message(filters.command(["fedinfo", "fedadmins"]))
  774. async def to_do(client, message):
  775. await message.reply_text("**Feel free to use your coding skills and open a pull request.**")
  776. @app.on_callback_query(filters.regex("rmfed_(.*)"))
  777. async def del_fed_button(client, cb):
  778. query = cb.data
  779. userid = cb.message.chat.id
  780. fed_id = query.split("_")[1]
  781. if fed_id == "cancel":
  782. await cb.message.edit_text("Federation deletion cancelled")
  783. return
  784. getfed = await get_fed_info(fed_id)
  785. if getfed:
  786. delete = fedsdb.delete_one({"fed_id": str(fed_id)})
  787. if delete:
  788. await cb.message.edit_text(
  789. "You have removed your Federation! Now all the Groups that are connected with `{}` do not have a Federation.".format(
  790. getfed["fed_name"]
  791. ),
  792. parse_mode=ParseMode.MARKDOWN,
  793. )
  794. @app.on_callback_query(filters.regex("trfed_(.*)"))
  795. async def fedtransfer_button(client, cb):
  796. query = cb.data
  797. userid = cb.message.chat.id
  798. data = query.split("_")[1]
  799. if data == "cancel":
  800. await cb.message.edit_text("Federation deletion cancelled")
  801. return
  802. data2 = data.split("|", 1)
  803. new_owner_id = int(data2[0])
  804. fed_id = data2[1]
  805. transferred = await transfer_owner(fed_id, userid, new_owner_id)
  806. if transferred:
  807. await cb.message.edit_text(
  808. "**Successfully transferred ownership to new owner.**"
  809. )
  810. @app.on_callback_query(filters.regex("fed_(.*)"))
  811. async def fed_owner_help(client, cb):
  812. query = cb.data
  813. userid = cb.message.chat.id
  814. data = query.split("_")[1]
  815. if data == "owner":
  816. text = """**👑 Fed Owner Only:**
  817. • /newfed <fed_name>**:** Creates a Federation, One allowed per user
  818. • /renamefed <fed_id> <new_fed_name>**:** Renames the fed id to a new name
  819. • /delfed <fed_id>**:** Delete a Federation, and any information related to it. Will not cancel blocked users
  820. • /myfeds**:** To list the federations that you have created
  821. • /fedtransfer <new_owner> <fed_id>**:**To transfer fed ownership to another person
  822. • /fpromote <user>**:** Assigns the user as a federation admin. Enables all commands for the user under `Fed Admins`
  823. • /fdemote <user>**:** Drops the User from the admin Federation to a normal User
  824. • /setfedlog <fed_id>**:** Sets the group as a fed log report base for the federation
  825. • /unsetfedlog <fed_id>**:** Removed the group as a fed log report base for the federation
  826. • /fbroadcast **:** Broadcasts a messages to all groups that have joined your fed """
  827. elif data == "admin":
  828. text = """**🔱 Fed Admins:**
  829. • /fban <user> <reason>**:** Fed bans a user
  830. • /sfban**:** Fban a user without sending notification to chats
  831. • /unfban <user> <reason>**:** Removes a user from a fed ban
  832. • /sunfban**:** Unfban a user without sending a notification
  833. • /fedadmins**:** Show Federation admin
  834. • /fedchats <FedID>**:** Get all the chats that are connected in the Federation
  835. • /fbroadcast **:** Broadcasts a messages to all groups that have joined your fed
  836. """
  837. else:
  838. text = """**User Commands:**
  839. • /fedinfo <FedID>: Information about a federation.
  840. • /fedadmins <FedID>: List the admins in a federation.
  841. • /joinfed <FedID>: Join the current chat to a federation. A chat can only join one federation. Chat owners only.
  842. • /leavefed: Leave the current federation. Only chat owners can do this.
  843. • /fedstat <FedID>: Gives information about your ban in a federation.
  844. • /fedstat <user ID> <FedID>: Gives information about a user's ban in a federation.
  845. • /chatfed: Information about the federation the current chat is in.
  846. """
  847. await cb.message.edit(
  848. text,
  849. reply_markup=InlineKeyboardMarkup(
  850. [
  851. [
  852. InlineKeyboardButton(
  853. "Back", callback_data="help_module(federation)"
  854. ),
  855. ]
  856. ]
  857. ),
  858. parse_mode=ParseMode.MARKDOWN,
  859. )