diff --git a/README.md b/README.md index 2aa532d..46542d6 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ [](https://makeapullrequest.com)
-#### _A Simple, Fast, Customizable Userbot for Telegram._ +#### _A Simple, Fast, Customizable Userbot for Telegram made after Dragon-Userbot abandoned._ {
- restart
- }",
-)
-except Exception:
-pass
-app.stop()
\ No newline at end of file
+ app.start()
+ try:
+ app.send_message(
+ "me",
+ f"[{datetime.datetime.now()}] Moon-Userbot launched! \n"
+ "Channel: @moonuserbot\n"
+ "Custom modules: @moonub_modules\n"
+ "Chat [RU]: @moonub_chat\n"
+ f"For restart, enter:\n"
+ f"{restart}",
+ )
+ except Exception:
+ pass
+ app.stop()
diff --git a/install.sh b/install.sh
index 418d19b..1f74d3f 100644
--- a/install.sh
+++ b/install.sh
@@ -1,159 +1,164 @@
#!/bin/bash
if command -v termux-setup-storage; then
-echo For termux, please use https://raw.githubusercontent.com/The-MoonTg-project/Moon-Userbot/main/termux-install.sh
-exit 1
+ echo For termux, please use https://raw.githubusercontent.com/The-MoonTg-project/Moon-Userbot/main/termux-install.sh
+ exit 1
fi
-if [[$UID != 0]]; then
-echo Please run this script as root
-exit 1
+if [[ $UID != 0 ]]; then
+ echo Please run this script as root
+ exit 1
fi
apt update -y
apt install python3 python3-pip git ffmpeg wget gnupg -y || exit 2
-su -c "python3 -m pip install -U pip" $SUDO_USER
-su -c "python3 -m pip install -U wheel pillow" $SUDO_USER
+su -c "python3 -m pip install -U pip" $SUDO_USER
+su -c "python3 -m pip install -U wheel pillow" $SUDO_USER
-if [[-d "Moon-Userbot"]]; then
-cd Moon-Userbot
-elif [[-f ".env.dist"]] && [[-f "main.py"]] && [[-d "modules"]]; then
-:
+if [[ -d "Moon-Userbot" ]]; then
+ cd Moon-Userbot
+elif [[ -f ".env.dist" ]] && [[ -f "main.py" ]] && [[ -d "modules" ]]; then
+ :
else
- git clone https://github.com/The-MoonTg-project/Moon-Userbot || exit 2
-cd Moon-Userbot || exit 2
+ git clone https://github.com/The-MoonTg-project/Moon-Userbot || exit 2
+ cd Moon-Userbot || exit 2
fi
-if [[-f ".env"]] && [[-f "my_account.session"]]; then
-echo "It seems that Moon-Userbot is already installed. Exiting..."
-exit
+if [[ -f ".env" ]] && [[ -f "my_account.session" ]]; then
+ echo "It seems that Moon-Userbot is already installed. Exiting..."
+ exit
fi
-su -c "python3 -m pip install -U -r requirements.txt" $SUDO_USER || exit 2
+su -c "python3 -m pip install -U -r requirements.txt" $SUDO_USER || exit 2
echo
-echo "Enter API_ID and API_HASH"
-echo "You can get it here -> https://my.telegram.org/apps"
-echo "Leave empty to use defaults (please note that default keys significantly increases your ban chances)"
-read -r -p "API_ID > " api_id
+echo "Enter API_ID and API_HASH"
+echo "You can get it here -> https://my.telegram.org/"
+echo "Leave empty to use defaults (please note that default keys significantly increases your ban chances)"
+read -r -p "API_ID > " api_id
-if [[$api_id = ""]]; then
-api_id = "2040"
-api_hash = "b18441a1ff607e10a989891a5462e627"
+if [[ $api_id = "" ]]; then
+ api_id="2040"
+ api_hash="b18441a1ff607e10a989891a5462e627"
else
- read -r -p "API_HASH > " api_hash
+ read -r -p "API_HASH > " api_hash
fi
echo
-echo "Choose database type:"
-echo "[1] MongoDB db_url"
-echo "[2] MongoDB localhost"
-echo "[3] Sqlite (default)"
-read -r -p "> " db_type
+echo "Choose database type:"
+echo "[1] MongoDB db_url"
+echo "[2] MongoDB localhost"
+echo "[3] Sqlite (default)"
+read -r -p "> " db_type
echo
case $db_type in
- 1)
-echo "Please enter db_url"
-echo "You can get it here -> "
-read -r -p "> " db_url
-db_name = Moon_Userbot
-db_type = mongodb
-;;
-2)
-if systemctl status mongodb; then
-wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add -
-source /etc/os-release
-echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu $ {
-UBUNTU_CODENAME
-}/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list
-apt update
-apt install mongodb -y
-systemctl daemon-reload
-systemctl enable mongodb
-fi
-systemctl start mongodb
+ 1)
+ echo "Please enter db_url"
+ echo "You can get it here -> https://mongodb.com/atlas"
+ read -r -p "> " db_url
+ db_name=Moon_Userbot
+ db_type=mongodb
+ ;;
+ 2)
+ if systemctl status mongodb; then
+ wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add -
+ source /etc/os-release
+ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu ${UBUNTU_CODENAME}/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list
+ apt update
+ apt install mongodb -y
+ systemctl daemon-reload
+ systemctl enable mongodb
+ fi
+ systemctl start mongodb
-db_url = mongodb://localhost:27017
-db_name = Moon_Userbot
-db_type = mongodb
-;;
-*)
-db_name = db.sqlite3
-db_type = sqlite3
-;;
+ db_url=mongodb://localhost:27017
+ db_name=Moon_Userbot
+ db_type=mongodb
+ ;;
+ *)
+ db_name=db.sqlite3
+ db_type=sqlite3
+ ;;
esac
cat > .env << EOL
- API_ID=${api_id}
- API_HASH=${api_hash}
- # sqlite/sqlite3 or mongo/mongodb
- DATABASE_TYPE=${db_type}
- # file name for sqlite3, database name for mongodb
- DATABASE_NAME=${db_name}
- # only for mongodb
- DATABASE_URL=${db_url}
- EOL
- chown -R $SUDO_USER:$SUDO_USER .
- echo
- echo "Choose installation type:"
- echo "[1] PM2"
- echo "[2] Systemd service"
- echo "[3] Custom (default)"
- read -r -p "> " install_type
- su -c "python3 install.py ${install_type}" $SUDO_USER || exit 3
- case $install_type in
- 1)
- if ! command -v pm2; then
- curl -fsSL https://deb.nodesource.com/setup_17.x | bash
- apt install nodejs -y
- npm install pm2 -g
- su -c "pm2 startup" $SUDO_USER
- env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u $SUDO_USER --hp /home/$SUDO_USER
- fi
- su -c "pm2 start main.py --name Moon --interpreter python3" $SUDO_USER
- su -c "pm2 save" $SUDO_USER
- echo
- echo "============================"
- echo "Great! Moon-Userbot installed successfully and running now!"
- echo "Installation type: PM2"
- echo "Start with: \"pm2 start Moon\""
- echo "Stop with: \"pm2 stop Moon\""
- echo "Process name: Moon"
- echo "============================"
- ;;
- 2)
- cat > /etc/systemd/system/Moon.service << EOL
- [Unit]
- Description=Service for Moon Userbot
- [Service]
- Type=simple
- ExecStart=$(which python3) ${PWD}/main.py
- WorkingDirectory=${PWD}
- Restart=always
- User=${SUDO_USER}
- Group=${SUDO_USER}
- [Install]
- WantedBy=multi-user.target
- EOL
- systemctl daemon-reload
- systemctl start Moon
- systemctl enable Moon
- echo
- echo "============================"
- echo "Great! Moon-Userbot installed successfully and running now!"
- echo "Installation type: Systemd service"
- echo "Start with: \"sudo systemctl start Moon\""
- echo "Stop with: \"sudo systemctl stop Moon\""
- echo "============================"
- ;;
- *)
- echo
- echo "============================"
- echo "Great! Moon-Userbot installed successfully!"
- echo "Installation type: Custom"
- echo "Start with: \"python3 main.py\""
- echo "============================"
- ;;
- esac
- chown -R $SUDO_USER:$SUDO_USER .
\ No newline at end of file
+API_ID=${api_id}
+API_HASH=${api_hash}
+# sqlite/sqlite3 or mongo/mongodb
+DATABASE_TYPE=${db_type}
+# file name for sqlite3, database name for mongodb
+DATABASE_NAME=${db_name}
+# only for mongodb
+DATABASE_URL=${db_url}
+EOL
+
+chown -R $SUDO_USER:$SUDO_USER .
+
+echo
+echo "Choose installation type:"
+echo "[1] PM2"
+echo "[2] Systemd service"
+echo "[3] Custom (default)"
+read -r -p "> " install_type
+
+su -c "python3 install.py ${install_type}" $SUDO_USER || exit 3
+
+case $install_type in
+ 1)
+ if ! command -v pm2; then
+ curl -fsSL https://deb.nodesource.com/setup_17.x | bash
+ apt install nodejs -y
+ npm install pm2 -g
+ su -c "pm2 startup" $SUDO_USER
+ env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u $SUDO_USER --hp /home/$SUDO_USER
+ fi
+ su -c "pm2 start main.py --name Moon --interpreter python3" $SUDO_USER
+ su -c "pm2 save" $SUDO_USER
+
+ echo
+ echo "============================"
+ echo "Great! Moon-Userbot installed successfully and running now!"
+ echo "Installation type: PM2"
+ echo "Start with: \"pm2 start Moon\""
+ echo "Stop with: \"pm2 stop Moon\""
+ echo "Process name: Moon"
+ echo "============================"
+ ;;
+ 2)
+ cat > /etc/systemd/system/Moon.service << EOL
+[Unit]
+Description=Service for Moon Userbot
+[Service]
+Type=simple
+ExecStart=$(which python3) ${PWD}/main.py
+WorkingDirectory=${PWD}
+Restart=always
+User=${SUDO_USER}
+Group=${SUDO_USER}
+[Install]
+WantedBy=multi-user.target
+EOL
+ systemctl daemon-reload
+ systemctl start Moon
+ systemctl enable Moon
+
+ echo
+ echo "============================"
+ echo "Great! Moon-Userbot installed successfully and running now!"
+ echo "Installation type: Systemd service"
+ echo "Start with: \"sudo systemctl start Moon\""
+ echo "Stop with: \"sudo systemctl stop Moon\""
+ echo "============================"
+ ;;
+ *)
+ echo
+ echo "============================"
+ echo "Great! Moon-Userbot installed successfully!"
+ echo "Installation type: Custom"
+ echo "Start with: \"python3 main.py\""
+ echo "============================"
+ ;;
+esac
+
+chown -R $SUDO_USER:$SUDO_USER .
\ No newline at end of file
diff --git a/main.py b/main.py
index f8e3b4d..82d885b 100644
--- a/main.py
+++ b/main.py
@@ -1,18 +1,18 @@
-# Moon-Userbot - telegram userbot
-# Copyright (C) 2020-present Moon Userbot Organization
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
#
-# This program is free software: you can redistribute it and/or modify
-# it is under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see banned!"
- + f"\n{'Cause: ' + text_c.split(maxsplit=1)[1] + '' if len(text_c.split()) > 1 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- if await check_username_or_id(cause.split(" ")[1]) == "channel":
- user_to_ban = await client.get_chat(cause.split(" ")[1])
- elif await check_username_or_id(cause.split(" ")[1]) == "user":
- user_to_ban = await client.get_users(cause.split(" ")[1])
- else:
- await message.edit("Invalid user type")
- return
-
- name = (
- user_to_ban.first_name
- if getattr(user_to_ban, "first_name", None)
- else user_to_ban.title
- )
-
- try:
- channel = await client.resolve_peer(message.chat.id)
- user_id = await client.resolve_peer(user_to_ban.id)
- if (
- "report_spam" in cause.lower().split()
- and message.reply_to_message
- ):
- await client.send(
- functions.channels.ReportSpam(
- channel=channel,
- participant=user_id,
- id=[message.reply_to_message.message_id],
- )
- )
- if "delete_history" in cause.lower().split():
- await client.send(
- functions.channels.DeleteParticipantHistory(
- channel=channel, participant=user_id
- )
- )
-
- text_c = "".join(
- f" {_}"
- for _ in cause.split()
- if _.lower() not in ["delete_history", "report_spam"]
- )
-
- await client.ban_chat_member(message.chat.id, user_to_ban.id)
- await message.edit(
- f"{name} banned!"
- + f"\n{'Cause: ' + text_c.split(' ', maxsplit=2)[2] + '' if len(text_c.split()) > 2 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["unban"], prefix) & filters.me)
- async def unban_command(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- user_for_unban, name = await get_user_and_name(message)
- try:
- await client.unban_chat_member(message.chat.id, user_for_unban)
- await message.edit(
- f"{name} unbanned!"
- + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
-
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- if await check_username_or_id(cause.split(" ")[1]) == "channel":
- user_to_unban = await client.get_chat(cause.split(" ")[1])
- elif await check_username_or_id(cause.split(" ")[1]) == "user":
- user_to_unban = await client.get_users(cause.split(" ")[1])
- else:
- await message.edit("Invalid user type")
- return
-
- name = (
- user_to_unban.first_name
- if getattr(user_to_unban, "first_name", None)
- else user_to_unban.title
- )
-
- try:
- await client.unban_chat_member(message.chat.id, user_to_unban.id)
- await message.edit(
- f"{name} unbanned!"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["kick"], prefix) & filters.me)
- async def kick_command(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- if message.reply_to_message.from_user:
- try:
- await client.ban_chat_member(
- message.chat.id,
- message.reply_to_message.from_user.id,
- int(time() + 60),
- )
- channel = await client.resolve_peer(message.chat.id)
- user_id = await client.resolve_peer(
- message.reply_to_message.from_user.id
- )
- if "report_spam" in cause.lower().split() and message.reply_to_message:
- await client.send(
- functions.channels.ReportSpam(
- channel=channel,
- participant=user_id,
- id=[message.reply_to_message.message_id],
- )
- )
- if "delete_history" in cause.lower().split():
- await client.send(
- functions.channels.DeleteParticipantHistory(
- channel=channel, participant=user_id
- )
- )
- text_c = "".join(
- f" {_}"
- for _ in cause.split()
- if _.lower() not in ["delete_history", "report_spam"]
- )
-
- await message.edit(
- f"{message.reply_to_message.from_user.first_name} kicked!"
- + f"\n{'Cause: ' + text_c.split(maxsplit=1)[1] + '' if len(text_c.split()) > 1 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- else:
- await message.edit("Reply on user msg")
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- user_to_ban = await client.get_users(cause.split(" ")[1])
- try:
- channel = await client.resolve_peer(message.chat.id)
- user_id = await client.resolve_peer(user_to_ban.id)
- if (
- "report_spam" in cause.lower().split()
- and message.reply_to_message
- ):
- await client.send(
- functions.channels.ReportSpam(
- channel=channel,
- participant=user_id,
- id=[message.reply_to_message.message_id],
- )
- )
- if "delete_history" in cause.lower().split():
- await client.send(
- functions.channels.DeleteParticipantHistory(
- channel=channel, participant=user_id
- )
- )
-
- text_c = "".join(
- f" {_}"
- for _ in cause.split()
- if _.lower() not in ["delete_history", "report_spam"]
- )
-
- await client.ban_chat_member(
- message.chat.id, user_to_ban.id, int(time() + 60)
- )
- await message.edit(
- f"{user_to_ban.first_name} kicked!"
- + f"\n{'Cause: ' + text_c.split(' ', maxsplit=2)[2] + '' if len(text_c.split()) > 2 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["kickdel"], prefix) & filters.me)
- async def kickdel_cmd(_, message: Message):
- await message.edit("Kicking deleted accounts...")
- # noinspection PyTypeChecker
- values = [
- await message.chat.ban_member(user.user.id, int(time()) + 31)
- for member in await message.chat.get_members()
- if member.user.is_deleted
- ]
- await message.edit(f"Successfully kicked {len(values)} deleted account(s)")
-
-
- @Client.on_message(filters.command(["tmute"], prefix) & filters.me)
- async def tmute_command(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- user_for_tmute, name = await get_user_and_name(message)
-
- if (
- message.reply_to_message.from_user
- and message.reply_to_message.from_user.is_self
- ):
- return await message.edit("Not on yourself")
-
- tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
- if user_for_tmute not in tmuted_users:
- tmuted_users.append(user_for_tmute)
- db.set("core.ats", f"c{message.chat.id}", tmuted_users)
- await message.edit(
- f"{name} in tmute"
- + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
- else:
- await message.edit(f"{name} already in tmute")
-
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- if await check_username_or_id(cause.split(" ")[1]) == "channel":
- user_to_tmute = await client.get_chat(cause.split(" ")[1])
- elif await check_username_or_id(cause.split(" ")[1]) == "user":
- user_to_tmute = await client.get_users(cause.split(" ")[1])
- if user_to_tmute.is_self:
- return await message.edit("Not on yourself")
- else:
- await message.edit("Invalid user type")
- return
-
- name = (
- user_to_tmute.first_name
- if getattr(user_to_tmute, "first_name", None)
- else user_to_tmute.title
- )
-
- tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
- if user_to_tmute.id not in tmuted_users:
- tmuted_users.append(user_to_tmute.id)
- db.set("core.ats", f"c{message.chat.id}", tmuted_users)
- await message.edit(
- f"{name} in tmute"
- + f"\n{'Cause: ' + cause.split(maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- else:
- await message.edit(f"{name} already in tmute")
-
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
- update_cache()
-
-
- @Client.on_message(filters.command(["tunmute"], prefix) & filters.me)
- async def tunmute_command(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- user_for_tunmute, name = await get_user_and_name(message)
-
- tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
- if user_for_tunmute not in tmuted_users:
- await message.edit(f"{name} not in tmute")
- else:
- tmuted_users.remove(user_for_tunmute)
- db.set("core.ats", f"c{message.chat.id}", tmuted_users)
- await message.edit(
- f"{name} tunmuted"
- + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
-
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- if await check_username_or_id(cause.split(" ")[1]) == "channel":
- user_to_tunmute = await client.get_chat(cause.split(" ")[1])
- elif await check_username_or_id(cause.split(" ")[1]) == "user":
- user_to_tunmute = await client.get_users(cause.split(" ")[1])
- if user_to_tunmute.is_self:
- return await message.edit("Not on yourself")
- else:
- await message.edit("Invalid user type")
- return
-
- name = (
- user_to_tunmute.first_name
- if getattr(user_to_tunmute, "first_name", None)
- else user_to_tunmute.title
- )
-
- tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
- if user_to_tunmute.id not in tmuted_users:
- await message.edit(f"{name} not in tmute")
- else:
- tmuted_users.remove(user_to_tunmute.id)
- db.set("core.ats", f"c{message.chat.id}", tmuted_users)
- await message.edit(
- f"{name} tunmuted"
- + f"\n{'Cause: ' + cause.split(maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
- update_cache()
-
-
- @Client.on_message(filters.command(["tmute_users"], prefix) & filters.me)
- async def tunmute_users_command(client: Client, message: Message):
- if message.chat.type not in ["private", "channel"]:
- text = f"All users {message.chat.title} who are now in tmute\n\n"
- count = 0
- tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
- for user in tmuted_users:
- try:
- _name_ = await client.get_chat(user)
- count += 1
- if await check_username_or_id(_name_.id) == "channel":
- channel = await client.send(
- functions.channels.GetChannels(
- id=[
- types.InputChannel(
- channel_id=get_channel_id(_name_.id),
- access_hash=0,
- )
- ]
- )
- )
- name = channel.chats[0].title
- elif await check_username_or_id(_name_.id) == "user":
- user = await client.get_users(_name_.id)
- name = user.first_name
- else:
- # invalid user type
- continue
- text += f"{count}. {name}\n"
- except PeerIdInvalid:
- pass
- if count == 0:
- await message.edit("No users in tmute")
- else:
- text += f"\nTotal users in tmute {count}"
- await message.edit(text)
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["unmute"], prefix) & filters.me)
- async def unmute_command(client, message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- u_p = message.chat.permissions
- if message.reply_to_message.from_user:
- try:
- await client.restrict_chat_member(
- message.chat.id,
- message.reply_to_message.from_user.id,
- u_p,
- int(time() + 30),
- )
- await message.edit(
- f"{message.reply_to_message.from_user.first_name} unmuted"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- else:
- await message.edit("Reply on user msg")
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- u_p = message.chat.permissions
- if len(cause.split()) > 1:
- try:
- user_to_unmute = await client.get_users(cause.split(" ")[1])
- try:
- await client.restrict_chat_member(
- message.chat.id, user_to_unmute.id, u_p, int(time() + 30)
- )
- await message.edit(
- f"{user_to_unmute.first_name} unmuted!"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["mute"], prefix) & filters.me)
- async def mute_command(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- mute_seconds: int = 0
- for character in "mhdw":
- match = re.search(rf"(\d+|(\d+\.\d+)){character}", message.text)
- if match:
- if character == "m":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1]) * 60 // 1
- )
- if character == "h":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1]) * 3600 // 1
- )
- if character == "d":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1])
- * 86400
- // 1
- )
- if character == "w":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1])
- * 604800
- // 1
- )
- try:
- if mute_seconds > 30:
- await client.restrict_chat_member(
- message.chat.id,
- message.reply_to_message.from_user.id,
- ChatPermissions(),
- int(time()) + mute_seconds,
- )
- from_user = message.reply_to_message.from_user
- mute_time: Dict[str, int] = {
- "days": mute_seconds // 86400,
- "hours": mute_seconds % 86400 // 3600,
- "minutes": mute_seconds % 86400 % 3600 // 60,
- }
- message_text = (
- f"{from_user.first_name} was muted for"
- f" {((str(mute_time['days']) + ' day') if mute_time['days'] > 0 else '') + ('s' if mute_time['days'] > 1 else '')}"
- f" {((str(mute_time['hours']) + ' hour') if mute_time['hours'] > 0 else '') + ('s' if mute_time['hours'] > 1 else '')}"
- f" {((str(mute_time['minutes']) + ' minute') if mute_time['minutes'] > 0 else '') + ('s' if mute_time['minutes'] > 1 else '')}"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- while " " in message_text:
- message_text = message_text.replace(" ", " ")
- else:
- await client.restrict_chat_member(
- message.chat.id,
- message.reply_to_message.from_user.id,
- ChatPermissions(),
- )
- message_text = (
- f"{message.reply_to_message.from_user.first_name} was muted indefinitely"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
- await message.edit(message_text)
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- user_to_unmute = await client.get_users(cause.split(" ")[1])
- mute_seconds: int = 0
- for character in "mhdw":
- match = re.search(rf"(\d+|(\d+\.\d+)){character}", message.text)
- if match:
- if character == "m":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1])
- * 60
- // 1
- )
- if character == "h":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1])
- * 3600
- // 1
- )
- if character == "d":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1])
- * 86400
- // 1
- )
- if character == "w":
- mute_seconds += int(
- float(match.string[match.start() : match.end() - 1])
- * 604800
- // 1
- )
- try:
- if mute_seconds > 30:
- await client.restrict_chat_member(
- message.chat.id,
- user_to_unmute.id,
- ChatPermissions(),
- int(time()) + mute_seconds,
- )
- mute_time: Dict[str, int] = {
- "days": mute_seconds // 86400,
- "hours": mute_seconds % 86400 // 3600,
- "minutes": mute_seconds % 86400 % 3600 // 60,
- }
- message_text = (
- f"{user_to_unmute.first_name} was muted for"
- f" {((str(mute_time['days']) + ' day') if mute_time['days'] > 0 else '') + ('s' if mute_time['days'] > 1 else '')}"
- f" {((str(mute_time['hours']) + ' hour') if mute_time['hours'] > 0 else '') + ('s' if mute_time['hours'] > 1 else '')}"
- f" {((str(mute_time['minutes']) + ' minute') if mute_time['minutes'] > 0 else '') + ('s' if mute_time['minutes'] > 1 else '')}"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=3)[3] + '' if len(cause.split()) > 3 else ''}"
- )
- while " " in message_text:
- message_text = message_text.replace(" ", " ")
- else:
- await client.restrict_chat_member(
- message.chat.id, user_to_unmute.id, ChatPermissions()
- )
- message_text = (
- f"{user_to_unmute.first_name} was muted indefinitely"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- await message.edit(message_text)
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["demote"], prefix) & filters.me)
- async def demote_command(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- if message.reply_to_message.from_user:
- try:
- await client.promote_chat_member(
- message.chat.id,
- message.reply_to_message.from_user.id,
- is_anonymous=False,
- can_manage_chat=False,
- can_change_info=False,
- can_post_messages=False,
- can_edit_messages=False,
- can_delete_messages=False,
- can_restrict_members=False,
- can_invite_users=False,
- can_pin_messages=False,
- can_promote_members=False,
- can_manage_voice_chats=False,
- )
- await message.edit(
- f"{message.reply_to_message.from_user.first_name} demoted!"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- promote_user = await client.get_users(cause.split(" ")[1])
- try:
- await client.promote_chat_member(
- message.chat.id,
- promote_user.id,
- is_anonymous=False,
- can_manage_chat=False,
- can_change_info=False,
- can_post_messages=False,
- can_edit_messages=False,
- can_delete_messages=False,
- can_restrict_members=False,
- can_invite_users=False,
- can_pin_messages=False,
- can_promote_members=False,
- can_manage_voice_chats=False,
- )
- await message.edit(
- f"{promote_user.first_name} demoted!"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["promote"], prefix) & filters.me)
- async def promote_command(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- if message.reply_to_message.from_user:
- try:
- await client.promote_chat_member(
- message.chat.id,
- message.reply_to_message.from_user.id,
- can_delete_messages=True,
- can_restrict_members=True,
- can_invite_users=True,
- can_pin_messages=True,
- )
- if len(cause.split()) > 1:
- await client.set_administrator_title(
- message.chat.id,
- message.reply_to_message.from_user.id,
- cause.split(maxsplit=1)[1],
- )
- await message.edit(
- f"{message.reply_to_message.from_user.first_name} promoted!"
- + f"\n{'Prefix: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- promote_user = await client.get_users(cause.split(" ")[1])
- try:
- await client.promote_chat_member(
- message.chat.id,
- promote_user.id,
- can_delete_messages=True,
- can_restrict_members=True,
- can_invite_users=True,
- can_pin_messages=True,
- )
- if len(cause.split()) > 1:
- await client.set_administrator_title(
- message.chat.id,
- promote_user.id,
- f"\n{cause.split(' ', maxsplit=2)[2] if len(cause.split()) > 2 else None}",
- )
- await message.edit(
- f"{promote_user.first_name} promoted!"
- + f"\n{'Prefix: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["antich"], prefix))
- async def anti_channels(client: Client, message: Message):
- if message.chat.type != "supergroup":
- await message.edit("Not supported in non-supergroup chats")
- return
-
- if len(message.command) == 1:
- if db.get("core.ats", f"antich{message.chat.id}", False):
- await message.edit(
- "Blocking channels in this chat is enabled.\n"
- f"Disable with: {prefix}antich disable"
- )
- else:
- await message.edit(
- "Blocking channels in this chat is disabled.\n"
- f"Enable with: {prefix}antich enable"
- )
- elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
- db.set("core.ats", f"antich{message.chat.id}", True)
- group = await client.get_chat(message.chat.id)
- if group.linked_chat:
- db.set("core.ats", f"linked{message.chat.id}", group.linked_chat.id)
- else:
- db.set("core.ats", f"linked{message.chat.id}", 0)
- await message.edit("Blocking channels in this chat enabled.")
- elif message.command[1] in ["disable", "off", "0", "no", "false"]:
- db.set("core.ats", f"antich{message.chat.id}", False)
- await message.edit("Blocking channels in this chat disabled.")
- else:
- await message.edit(f"Usage: {prefix}antich [enable|disable]")
-
- update_cache()
-
-
- @Client.on_message(filters.command(["delete_history", "dh"], prefix))
- async def delete_history(client: Client, message: Message):
- cause = text(message)
- if message.reply_to_message and message.chat.type not in ["private", "channel"]:
- if message.reply_to_message.from_user:
- try:
- user_for_delete, name = await get_user_and_name(message)
- channel = await client.resolve_peer(message.chat.id)
- user_id = await client.resolve_peer(user_for_delete)
- await client.send(
- functions.channels.DeleteParticipantHistory(
- channel=channel, participant=user_id
- )
- )
-
- await message.edit(
- f"History from {name} was deleted!"
- + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- else:
- await message.edit("Reply on user msg")
- elif not message.reply_to_message and message.chat.type not in [
- "private",
- "channel",
- ]:
- if len(cause.split()) > 1:
- try:
- if await check_username_or_id(cause.split(" ")[1]) == "channel":
- user_to_delete = await client.get_chat(cause.split(" ")[1])
- elif await check_username_or_id(cause.split(" ")[1]) == "user":
- user_to_delete = await client.get_users(cause.split(" ")[1])
- else:
- await message.edit("Invalid user type")
- return
-
- name = (
- user_to_delete.first_name
- if getattr(user_to_delete, "first_name", None)
- else user_to_delete.title
- )
-
- try:
- channel = await client.resolve_peer(message.chat.id)
- user_id = await client.resolve_peer(user_to_delete.id)
- await client.send(
- functions.channels.DeleteParticipantHistory(
- channel=channel, participant=user_id
- )
- )
- await message.edit(
- f"History from {name} was deleted!"
- + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
- )
- except UserAdminInvalid:
- await message.edit("No rights")
- except ChatAdminRequired:
- await message.edit("No rights")
- except Exception as e:
- await message.edit(format_exc(e))
- except PeerIdInvalid:
- await message.edit("User is not found")
- except UsernameInvalid:
- await message.edit("User is not found")
- except IndexError:
- await message.edit("User is not found")
- else:
- await message.edit("user_id or username")
- else:
- await message.edit("Unsupported")
-
-
- @Client.on_message(filters.command(["report_spam", "rs"], prefix))
- @with_reply
- async def report_spam(client: Client, message: Message):
- try:
- channel = await client.resolve_peer(message.chat.id)
-
- user_id, name = await get_user_and_name(message)
- peer = await client.resolve_peer(user_id)
- await client.send(
- functions.channels.ReportSpam(
- channel=channel,
- participant=peer,
- id=[message.reply_to_message.message_id],
- )
- )
- except Exception as e:
- await message.edit(format_exc(e))
- else:
- await message.edit(f"Message from {name} was reported")
-
-
- @Client.on_message(filters.command("pin", prefix) & filters.me)
- @with_reply
- async def pin(_, message: Message):
- try:
- await message.reply_to_message.pin()
- await message.edit("Pinned!")
- except Exception as e:
- await message.edit(format_exc(e))
-
-
- @Client.on_message(filters.command("unpin", prefix) & filters.me)
- @with_reply
- async def unpin(_, message: Message):
- try:
- await message.reply_to_message.unpin()
- await message.edit("Unpinned!")
- except Exception as e:
- await message.edit(format_exc(e))
-
-
- @Client.on_message(filters.command("ro", prefix) & filters.me)
- async def ro(client: Client, message: Message):
- if message.chat.type != "supergroup":
- await message.edit("Invalid chat type")
- return
-
- try:
- perms = message.chat.permissions
- perms_list = [
- perms.can_send_messages,
- perms.can_send_media_messages,
- perms.can_send_other_messages,
- perms.can_send_polls,
- perms.can_add_web_page_previews,
- perms.can_change_info,
- perms.can_invite_users,
- perms.can_pin_messages,
- ]
- db.set("core.ats", f"ro{message.chat.id}", perms_list)
-
- try:
- await client.set_chat_permissions(message.chat.id, ChatPermissions())
- except (UserAdminInvalid, ChatAdminRequired):
- await message.edit("No rights")
- else:
- await message.edit(
- "Read-only mode activated!\n"
- f"Turn off with:{prefix}unro"
- )
- except Exception as e:
- await message.edit(format_exc(e))
-
-
- @Client.on_message(filters.command("unro", prefix) & filters.me)
- async def unro(client: Client, message: Message):
- if message.chat.type != "supergroup":
- await message.edit("Invalid chat type")
- return
-
- try:
- perms_list = db.get(
- "core.ats",
- f"ro{message.chat.id}",
- [True, True, True, False, False, False, False, False],
- )
- perms = ChatPermissions(
- can_send_messages=perms_list[0],
- can_send_media_messages=perms_list[1],
- can_send_other_messages=perms_list[2],
- can_send_polls=perms_list[3],
- can_add_web_page_previews=perms_list[4],
- can_change_info=perms_list[5],
- can_invite_users=perms_list[6],
- can_pin_messages=perms_list[7],
- )
-
- try:
- await client.set_chat_permissions(message.chat.id, perms)
- except (UserAdminInvalid, ChatAdminRequired):
- await message.edit("No rights")
- else:
- await message.edit("Read-only mode disabled!")
- except Exception as e:
- await message.edit(format_exc(e))
-
-
- @Client.on_message(filters.command("antiraid", prefix) & filters.me)
- async def antiraid(client: Client, message: Message):
- if message.chat.type != "supergroup":
- await message.edit("Not supported in non-supergroup chats")
- return
-
- if len(message.command) > 1 and message.command[1] == "on":
- db.set("core.ats", f"antiraid{message.chat.id}", True)
- group = await client.get_chat(message.chat.id)
- if group.linked_chat:
- db.set("core.ats", f"linked{message.chat.id}", group.linked_chat.id)
- else:
- db.set("core.ats", f"linked{message.chat.id}", 0)
- await message.edit(
- "Anti-raid mode enabled!\n"
- f"Disable with: {prefix}antiraid off"
- )
- elif len(message.command) > 1 and message.command[1] == "off":
- db.set("core.ats", f"antiraid{message.chat.id}", False)
- await message.edit("Anti-raid mode disabled")
- else:
- # toggle
- if db.get("core.ats", f"antiraid{message.chat.id}", False):
- db.set("core.ats", f"antiraid{message.chat.id}", False)
- await message.edit("Anti-raid mode disabled")
- else:
- db.set("core.ats", f"antiraid{message.chat.id}", True)
- group = await client.get_chat(message.chat.id)
- if group.linked_chat:
- db.set("core.ats", f"linked{message.chat.id}", group.linked_chat.id)
- else:
- db.set("core.ats", f"linked{message.chat.id}", 0)
- await message.edit(
- "Anti-raid mode enabled!\n"
- f"Disable with: {prefix}antiraid off"
- )
-
- update_cache()
-
-
- @Client.on_message(filters.command(["welcome", "wc"], prefix) & filters.me)
- async def welcome(_, message: Message):
- if message.chat.type != "supergroup":
- return await message.edit("Unsupported chat type")
-
- if len(message.command) > 1:
- text = message.text.split(maxsplit=1)[1]
- db.set("core.ats", f"welcome_enabled{message.chat.id}", True)
- db.set("core.ats", f"welcome_text{message.chat.id}", text)
-
- await message.edit(
- f"Welcome enabled in this chat\nText: {text}"
- )
- else:
- db.set("core.ats", f"welcome_enabled{message.chat.id}", False)
- await message.edit("Welcome disabled in this chat")
-
- update_cache()
-
-
- modules_help["admintool"] = {
- "ban [reply]/[username/id]* [reason] [report_spam] [delete_history]": "ban user in chat",
- "unban [reply]/[username/id]* [reason]": "unban user in chat",
- "kick [reply]/[userid]* [reason] [report_spam] [delete_history]": "kick user out of chat",
- "mute [reply]/[userid]* [reason] [1m]/[1h]/[1d]/[1w]": "mute user in chat",
- "unmute [reply]/[userid]* [reason]": "unmute user in chat",
- "promote [reply]/[userid]* [prefix]": "promote user in chat",
- "demote [reply]/[userid]* [reason]": "demote user in chat",
- "tmute [reply]/[username/id]* [reason]": "delete all new messages from user in chat",
- "tunmute [reply]/[username/id]* [reason]": "stop deleting all messages from user in chat",
- "tmute_users": "list of tmuted (.tmute) users",
- "antich [enable/disable]": "turn on/off blocking channels in this chat",
- "delete_history [reply]/[username/id]* [reason]": "delete history from member in chat",
- "report_spam [reply]*": "report spam message in chat",
- "pin [reply]*": "Pin replied message",
- "unpin [reply]*": "Unpin replied message",
- "ro": "enable read-only mode",
- "unro": "disable read-only mode",
- "antiraid [on|off]": "when enabled, anyone who writes message will be blocked. Useful in raids. "
- "Running without arguments equals to toggling state",
- "welcome [text]*": "enable auto-welcome to new users in groups. "
- "Running without text equals to disable",
- "kickdel": "Kick all deleted accounts",
- }
\ No newline at end of file
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see banned!"
+ + f"\n{'Cause: ' + text_c.split(maxsplit=1)[1] + '' if len(text_c.split()) > 1 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ if await check_username_or_id(cause.split(" ")[1]) == "channel":
+ user_to_ban = await client.get_chat(cause.split(" ")[1])
+ elif await check_username_or_id(cause.split(" ")[1]) == "user":
+ user_to_ban = await client.get_users(cause.split(" ")[1])
+ else:
+ await message.edit("Invalid user type")
+ return
+
+ name = (
+ user_to_ban.first_name
+ if getattr(user_to_ban, "first_name", None)
+ else user_to_ban.title
+ )
+
+ try:
+ channel = await client.resolve_peer(message.chat.id)
+ user_id = await client.resolve_peer(user_to_ban.id)
+ if (
+ "report_spam" in cause.lower().split()
+ and message.reply_to_message
+ ):
+ await client.send(
+ functions.channels.ReportSpam(
+ channel=channel,
+ participant=user_id,
+ id=[message.reply_to_message.message_id],
+ )
+ )
+ if "delete_history" in cause.lower().split():
+ await client.send(
+ functions.channels.DeleteParticipantHistory(
+ channel=channel, participant=user_id
+ )
+ )
+
+ text_c = "".join(
+ f" {_}"
+ for _ in cause.split()
+ if _.lower() not in ["delete_history", "report_spam"]
+ )
+
+ await client.ban_chat_member(message.chat.id, user_to_ban.id)
+ await message.edit(
+ f"{name} banned!"
+ + f"\n{'Cause: ' + text_c.split(' ', maxsplit=2)[2] + '' if len(text_c.split()) > 2 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["unban"], prefix) & filters.me)
+async def unban_command(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ user_for_unban, name = await get_user_and_name(message)
+ try:
+ await client.unban_chat_member(message.chat.id, user_for_unban)
+ await message.edit(
+ f"{name} unbanned!"
+ + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ if await check_username_or_id(cause.split(" ")[1]) == "channel":
+ user_to_unban = await client.get_chat(cause.split(" ")[1])
+ elif await check_username_or_id(cause.split(" ")[1]) == "user":
+ user_to_unban = await client.get_users(cause.split(" ")[1])
+ else:
+ await message.edit("Invalid user type")
+ return
+
+ name = (
+ user_to_unban.first_name
+ if getattr(user_to_unban, "first_name", None)
+ else user_to_unban.title
+ )
+
+ try:
+ await client.unban_chat_member(message.chat.id, user_to_unban.id)
+ await message.edit(
+ f"{name} unbanned!"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["kick"], prefix) & filters.me)
+async def kick_command(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ if message.reply_to_message.from_user:
+ try:
+ await client.ban_chat_member(
+ message.chat.id,
+ message.reply_to_message.from_user.id,
+ int(time() + 60),
+ )
+ channel = await client.resolve_peer(message.chat.id)
+ user_id = await client.resolve_peer(
+ message.reply_to_message.from_user.id
+ )
+ if "report_spam" in cause.lower().split() and message.reply_to_message:
+ await client.send(
+ functions.channels.ReportSpam(
+ channel=channel,
+ participant=user_id,
+ id=[message.reply_to_message.message_id],
+ )
+ )
+ if "delete_history" in cause.lower().split():
+ await client.send(
+ functions.channels.DeleteParticipantHistory(
+ channel=channel, participant=user_id
+ )
+ )
+ text_c = "".join(
+ f" {_}"
+ for _ in cause.split()
+ if _.lower() not in ["delete_history", "report_spam"]
+ )
+
+ await message.edit(
+ f"{message.reply_to_message.from_user.first_name} kicked!"
+ + f"\n{'Cause: ' + text_c.split(maxsplit=1)[1] + '' if len(text_c.split()) > 1 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ else:
+ await message.edit("Reply on user msg")
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ user_to_ban = await client.get_users(cause.split(" ")[1])
+ try:
+ channel = await client.resolve_peer(message.chat.id)
+ user_id = await client.resolve_peer(user_to_ban.id)
+ if (
+ "report_spam" in cause.lower().split()
+ and message.reply_to_message
+ ):
+ await client.send(
+ functions.channels.ReportSpam(
+ channel=channel,
+ participant=user_id,
+ id=[message.reply_to_message.message_id],
+ )
+ )
+ if "delete_history" in cause.lower().split():
+ await client.send(
+ functions.channels.DeleteParticipantHistory(
+ channel=channel, participant=user_id
+ )
+ )
+
+ text_c = "".join(
+ f" {_}"
+ for _ in cause.split()
+ if _.lower() not in ["delete_history", "report_spam"]
+ )
+
+ await client.ban_chat_member(
+ message.chat.id, user_to_ban.id, int(time() + 60)
+ )
+ await message.edit(
+ f"{user_to_ban.first_name} kicked!"
+ + f"\n{'Cause: ' + text_c.split(' ', maxsplit=2)[2] + '' if len(text_c.split()) > 2 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["kickdel"], prefix) & filters.me)
+async def kickdel_cmd(_, message: Message):
+ await message.edit("Kicking deleted accounts...")
+ # noinspection PyTypeChecker
+ values = [
+ await message.chat.ban_member(user.user.id, int(time()) + 31)
+ for member in await message.chat.get_members()
+ if member.user.is_deleted
+ ]
+ await message.edit(f"Successfully kicked {len(values)} deleted account(s)")
+
+
+@Client.on_message(filters.command(["tmute"], prefix) & filters.me)
+async def tmute_command(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ user_for_tmute, name = await get_user_and_name(message)
+
+ if (
+ message.reply_to_message.from_user
+ and message.reply_to_message.from_user.is_self
+ ):
+ return await message.edit("Not on yourself")
+
+ tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
+ if user_for_tmute not in tmuted_users:
+ tmuted_users.append(user_for_tmute)
+ db.set("core.ats", f"c{message.chat.id}", tmuted_users)
+ await message.edit(
+ f"{name} in tmute"
+ + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+ else:
+ await message.edit(f"{name} already in tmute")
+
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ if await check_username_or_id(cause.split(" ")[1]) == "channel":
+ user_to_tmute = await client.get_chat(cause.split(" ")[1])
+ elif await check_username_or_id(cause.split(" ")[1]) == "user":
+ user_to_tmute = await client.get_users(cause.split(" ")[1])
+ if user_to_tmute.is_self:
+ return await message.edit("Not on yourself")
+ else:
+ await message.edit("Invalid user type")
+ return
+
+ name = (
+ user_to_tmute.first_name
+ if getattr(user_to_tmute, "first_name", None)
+ else user_to_tmute.title
+ )
+
+ tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
+ if user_to_tmute.id not in tmuted_users:
+ tmuted_users.append(user_to_tmute.id)
+ db.set("core.ats", f"c{message.chat.id}", tmuted_users)
+ await message.edit(
+ f"{name} in tmute"
+ + f"\n{'Cause: ' + cause.split(maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ else:
+ await message.edit(f"{name} already in tmute")
+
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+ update_cache()
+
+
+@Client.on_message(filters.command(["tunmute"], prefix) & filters.me)
+async def tunmute_command(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ user_for_tunmute, name = await get_user_and_name(message)
+
+ tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
+ if user_for_tunmute not in tmuted_users:
+ await message.edit(f"{name} not in tmute")
+ else:
+ tmuted_users.remove(user_for_tunmute)
+ db.set("core.ats", f"c{message.chat.id}", tmuted_users)
+ await message.edit(
+ f"{name} tunmuted"
+ + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ if await check_username_or_id(cause.split(" ")[1]) == "channel":
+ user_to_tunmute = await client.get_chat(cause.split(" ")[1])
+ elif await check_username_or_id(cause.split(" ")[1]) == "user":
+ user_to_tunmute = await client.get_users(cause.split(" ")[1])
+ if user_to_tunmute.is_self:
+ return await message.edit("Not on yourself")
+ else:
+ await message.edit("Invalid user type")
+ return
+
+ name = (
+ user_to_tunmute.first_name
+ if getattr(user_to_tunmute, "first_name", None)
+ else user_to_tunmute.title
+ )
+
+ tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
+ if user_to_tunmute.id not in tmuted_users:
+ await message.edit(f"{name} not in tmute")
+ else:
+ tmuted_users.remove(user_to_tunmute.id)
+ db.set("core.ats", f"c{message.chat.id}", tmuted_users)
+ await message.edit(
+ f"{name} tunmuted"
+ + f"\n{'Cause: ' + cause.split(maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+ update_cache()
+
+
+@Client.on_message(filters.command(["tmute_users"], prefix) & filters.me)
+async def tunmute_users_command(client: Client, message: Message):
+ if message.chat.type not in ["private", "channel"]:
+ text = f"All users {message.chat.title} who are now in tmute\n\n"
+ count = 0
+ tmuted_users = db.get("core.ats", f"c{message.chat.id}", [])
+ for user in tmuted_users:
+ try:
+ _name_ = await client.get_chat(user)
+ count += 1
+ if await check_username_or_id(_name_.id) == "channel":
+ channel = await client.send(
+ functions.channels.GetChannels(
+ id=[
+ types.InputChannel(
+ channel_id=get_channel_id(_name_.id),
+ access_hash=0,
+ )
+ ]
+ )
+ )
+ name = channel.chats[0].title
+ elif await check_username_or_id(_name_.id) == "user":
+ user = await client.get_users(_name_.id)
+ name = user.first_name
+ else:
+ # invalid user type
+ continue
+ text += f"{count}. {name}\n"
+ except PeerIdInvalid:
+ pass
+ if count == 0:
+ await message.edit("No users in tmute")
+ else:
+ text += f"\nTotal users in tmute {count}"
+ await message.edit(text)
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["unmute"], prefix) & filters.me)
+async def unmute_command(client, message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ u_p = message.chat.permissions
+ if message.reply_to_message.from_user:
+ try:
+ await client.restrict_chat_member(
+ message.chat.id,
+ message.reply_to_message.from_user.id,
+ u_p,
+ int(time() + 30),
+ )
+ await message.edit(
+ f"{message.reply_to_message.from_user.first_name} unmuted"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ else:
+ await message.edit("Reply on user msg")
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ u_p = message.chat.permissions
+ if len(cause.split()) > 1:
+ try:
+ user_to_unmute = await client.get_users(cause.split(" ")[1])
+ try:
+ await client.restrict_chat_member(
+ message.chat.id, user_to_unmute.id, u_p, int(
+ time() + 30)
+ )
+ await message.edit(
+ f"{user_to_unmute.first_name} unmuted!"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["mute"], prefix) & filters.me)
+async def mute_command(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ mute_seconds: int = 0
+ for character in "mhdw":
+ match = re.search(rf"(\d+|(\d+\.\d+)){character}", message.text)
+ if match:
+ if character == "m":
+ mute_seconds += int(
+ float(match.string[match.start()
+ : match.end() - 1]) * 60 // 1
+ )
+ if character == "h":
+ mute_seconds += int(
+ float(match.string[match.start()
+ : match.end() - 1]) * 3600 // 1
+ )
+ if character == "d":
+ mute_seconds += int(
+ float(match.string[match.start(): match.end() - 1])
+ * 86400
+ // 1
+ )
+ if character == "w":
+ mute_seconds += int(
+ float(match.string[match.start(): match.end() - 1])
+ * 604800
+ // 1
+ )
+ try:
+ if mute_seconds > 30:
+ await client.restrict_chat_member(
+ message.chat.id,
+ message.reply_to_message.from_user.id,
+ ChatPermissions(),
+ int(time()) + mute_seconds,
+ )
+ from_user = message.reply_to_message.from_user
+ mute_time: Dict[str, int] = {
+ "days": mute_seconds // 86400,
+ "hours": mute_seconds % 86400 // 3600,
+ "minutes": mute_seconds % 86400 % 3600 // 60,
+ }
+ message_text = (
+ f"{from_user.first_name} was muted for"
+ f" {((str(mute_time['days']) + ' day') if mute_time['days'] > 0 else '') + ('s' if mute_time['days'] > 1 else '')}"
+ f" {((str(mute_time['hours']) + ' hour') if mute_time['hours'] > 0 else '') + ('s' if mute_time['hours'] > 1 else '')}"
+ f" {((str(mute_time['minutes']) + ' minute') if mute_time['minutes'] > 0 else '') + ('s' if mute_time['minutes'] > 1 else '')}"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ while " " in message_text:
+ message_text = message_text.replace(" ", " ")
+ else:
+ await client.restrict_chat_member(
+ message.chat.id,
+ message.reply_to_message.from_user.id,
+ ChatPermissions(),
+ )
+ message_text = (
+ f"{message.reply_to_message.from_user.first_name} was muted indefinitely"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+ await message.edit(message_text)
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ user_to_unmute = await client.get_users(cause.split(" ")[1])
+ mute_seconds: int = 0
+ for character in "mhdw":
+ match = re.search(
+ rf"(\d+|(\d+\.\d+)){character}", message.text)
+ if match:
+ if character == "m":
+ mute_seconds += int(
+ float(
+ match.string[match.start(): match.end() - 1])
+ * 60
+ // 1
+ )
+ if character == "h":
+ mute_seconds += int(
+ float(
+ match.string[match.start(): match.end() - 1])
+ * 3600
+ // 1
+ )
+ if character == "d":
+ mute_seconds += int(
+ float(
+ match.string[match.start(): match.end() - 1])
+ * 86400
+ // 1
+ )
+ if character == "w":
+ mute_seconds += int(
+ float(
+ match.string[match.start(): match.end() - 1])
+ * 604800
+ // 1
+ )
+ try:
+ if mute_seconds > 30:
+ await client.restrict_chat_member(
+ message.chat.id,
+ user_to_unmute.id,
+ ChatPermissions(),
+ int(time()) + mute_seconds,
+ )
+ mute_time: Dict[str, int] = {
+ "days": mute_seconds // 86400,
+ "hours": mute_seconds % 86400 // 3600,
+ "minutes": mute_seconds % 86400 % 3600 // 60,
+ }
+ message_text = (
+ f"{user_to_unmute.first_name} was muted for"
+ f" {((str(mute_time['days']) + ' day') if mute_time['days'] > 0 else '') + ('s' if mute_time['days'] > 1 else '')}"
+ f" {((str(mute_time['hours']) + ' hour') if mute_time['hours'] > 0 else '') + ('s' if mute_time['hours'] > 1 else '')}"
+ f" {((str(mute_time['minutes']) + ' minute') if mute_time['minutes'] > 0 else '') + ('s' if mute_time['minutes'] > 1 else '')}"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=3)[3] + '' if len(cause.split()) > 3 else ''}"
+ )
+ while " " in message_text:
+ message_text = message_text.replace(" ", " ")
+ else:
+ await client.restrict_chat_member(
+ message.chat.id, user_to_unmute.id, ChatPermissions()
+ )
+ message_text = (
+ f"{user_to_unmute.first_name} was muted indefinitely"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ await message.edit(message_text)
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["demote"], prefix) & filters.me)
+async def demote_command(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ if message.reply_to_message.from_user:
+ try:
+ await client.promote_chat_member(
+ message.chat.id,
+ message.reply_to_message.from_user.id,
+ is_anonymous=False,
+ can_manage_chat=False,
+ can_change_info=False,
+ can_post_messages=False,
+ can_edit_messages=False,
+ can_delete_messages=False,
+ can_restrict_members=False,
+ can_invite_users=False,
+ can_pin_messages=False,
+ can_promote_members=False,
+ can_manage_voice_chats=False,
+ )
+ await message.edit(
+ f"{message.reply_to_message.from_user.first_name} demoted!"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ promote_user = await client.get_users(cause.split(" ")[1])
+ try:
+ await client.promote_chat_member(
+ message.chat.id,
+ promote_user.id,
+ is_anonymous=False,
+ can_manage_chat=False,
+ can_change_info=False,
+ can_post_messages=False,
+ can_edit_messages=False,
+ can_delete_messages=False,
+ can_restrict_members=False,
+ can_invite_users=False,
+ can_pin_messages=False,
+ can_promote_members=False,
+ can_manage_voice_chats=False,
+ )
+ await message.edit(
+ f"{promote_user.first_name} demoted!"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["promote"], prefix) & filters.me)
+async def promote_command(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ if message.reply_to_message.from_user:
+ try:
+ await client.promote_chat_member(
+ message.chat.id,
+ message.reply_to_message.from_user.id,
+ can_delete_messages=True,
+ can_restrict_members=True,
+ can_invite_users=True,
+ can_pin_messages=True,
+ )
+ if len(cause.split()) > 1:
+ await client.set_administrator_title(
+ message.chat.id,
+ message.reply_to_message.from_user.id,
+ cause.split(maxsplit=1)[1],
+ )
+ await message.edit(
+ f"{message.reply_to_message.from_user.first_name} promoted!"
+ + f"\n{'Prefix: ' + cause.split(' ', maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ promote_user = await client.get_users(cause.split(" ")[1])
+ try:
+ await client.promote_chat_member(
+ message.chat.id,
+ promote_user.id,
+ can_delete_messages=True,
+ can_restrict_members=True,
+ can_invite_users=True,
+ can_pin_messages=True,
+ )
+ if len(cause.split()) > 1:
+ await client.set_administrator_title(
+ message.chat.id,
+ promote_user.id,
+ f"\n{cause.split(' ', maxsplit=2)[2] if len(cause.split()) > 2 else None}",
+ )
+ await message.edit(
+ f"{promote_user.first_name} promoted!"
+ + f"\n{'Prefix: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["antich"], prefix))
+async def anti_channels(client: Client, message: Message):
+ if message.chat.type != "supergroup":
+ await message.edit("Not supported in non-supergroup chats")
+ return
+
+ if len(message.command) == 1:
+ if db.get("core.ats", f"antich{message.chat.id}", False):
+ await message.edit(
+ "Blocking channels in this chat is enabled.\n"
+ f"Disable with: {prefix}antich disable"
+ )
+ else:
+ await message.edit(
+ "Blocking channels in this chat is disabled.\n"
+ f"Enable with: {prefix}antich enable"
+ )
+ elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
+ db.set("core.ats", f"antich{message.chat.id}", True)
+ group = await client.get_chat(message.chat.id)
+ if group.linked_chat:
+ db.set(
+ "core.ats", f"linked{message.chat.id}", group.linked_chat.id)
+ else:
+ db.set("core.ats", f"linked{message.chat.id}", 0)
+ await message.edit("Blocking channels in this chat enabled.")
+ elif message.command[1] in ["disable", "off", "0", "no", "false"]:
+ db.set("core.ats", f"antich{message.chat.id}", False)
+ await message.edit("Blocking channels in this chat disabled.")
+ else:
+ await message.edit(f"Usage: {prefix}antich [enable|disable]")
+
+ update_cache()
+
+
+@Client.on_message(filters.command(["delete_history", "dh"], prefix))
+async def delete_history(client: Client, message: Message):
+ cause = text(message)
+ if message.reply_to_message and message.chat.type not in ["private", "channel"]:
+ if message.reply_to_message.from_user:
+ try:
+ user_for_delete, name = await get_user_and_name(message)
+ channel = await client.resolve_peer(message.chat.id)
+ user_id = await client.resolve_peer(user_for_delete)
+ await client.send(
+ functions.channels.DeleteParticipantHistory(
+ channel=channel, participant=user_id
+ )
+ )
+
+ await message.edit(
+ f"History from {name} was deleted!"
+ + f"\n{'Cause: ' + cause.split(maxsplit=1)[1] + '' if len(cause.split()) > 1 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ else:
+ await message.edit("Reply on user msg")
+ elif not message.reply_to_message and message.chat.type not in [
+ "private",
+ "channel",
+ ]:
+ if len(cause.split()) > 1:
+ try:
+ if await check_username_or_id(cause.split(" ")[1]) == "channel":
+ user_to_delete = await client.get_chat(cause.split(" ")[1])
+ elif await check_username_or_id(cause.split(" ")[1]) == "user":
+ user_to_delete = await client.get_users(cause.split(" ")[1])
+ else:
+ await message.edit("Invalid user type")
+ return
+
+ name = (
+ user_to_delete.first_name
+ if getattr(user_to_delete, "first_name", None)
+ else user_to_delete.title
+ )
+
+ try:
+ channel = await client.resolve_peer(message.chat.id)
+ user_id = await client.resolve_peer(user_to_delete.id)
+ await client.send(
+ functions.channels.DeleteParticipantHistory(
+ channel=channel, participant=user_id
+ )
+ )
+ await message.edit(
+ f"History from {name} was deleted!"
+ + f"\n{'Cause: ' + cause.split(' ', maxsplit=2)[2] + '' if len(cause.split()) > 2 else ''}"
+ )
+ except UserAdminInvalid:
+ await message.edit("No rights")
+ except ChatAdminRequired:
+ await message.edit("No rights")
+ except Exception as e:
+ await message.edit(format_exc(e))
+ except PeerIdInvalid:
+ await message.edit("User is not found")
+ except UsernameInvalid:
+ await message.edit("User is not found")
+ except IndexError:
+ await message.edit("User is not found")
+ else:
+ await message.edit("user_id or username")
+ else:
+ await message.edit("Unsupported")
+
+
+@Client.on_message(filters.command(["report_spam", "rs"], prefix))
+@with_reply
+async def report_spam(client: Client, message: Message):
+ try:
+ channel = await client.resolve_peer(message.chat.id)
+
+ user_id, name = await get_user_and_name(message)
+ peer = await client.resolve_peer(user_id)
+ await client.send(
+ functions.channels.ReportSpam(
+ channel=channel,
+ participant=peer,
+ id=[message.reply_to_message.message_id],
+ )
+ )
+ except Exception as e:
+ await message.edit(format_exc(e))
+ else:
+ await message.edit(f"Message from {name} was reported")
+
+
+@Client.on_message(filters.command("pin", prefix) & filters.me)
+@with_reply
+async def pin(_, message: Message):
+ try:
+ await message.reply_to_message.pin()
+ await message.edit("Pinned!")
+ except Exception as e:
+ await message.edit(format_exc(e))
+
+
+@Client.on_message(filters.command("unpin", prefix) & filters.me)
+@with_reply
+async def unpin(_, message: Message):
+ try:
+ await message.reply_to_message.unpin()
+ await message.edit("Unpinned!")
+ except Exception as e:
+ await message.edit(format_exc(e))
+
+
+@Client.on_message(filters.command("ro", prefix) & filters.me)
+async def ro(client: Client, message: Message):
+ if message.chat.type != "supergroup":
+ await message.edit("Invalid chat type")
+ return
+
+ try:
+ perms = message.chat.permissions
+ perms_list = [
+ perms.can_send_messages,
+ perms.can_send_media_messages,
+ perms.can_send_other_messages,
+ perms.can_send_polls,
+ perms.can_add_web_page_previews,
+ perms.can_change_info,
+ perms.can_invite_users,
+ perms.can_pin_messages,
+ ]
+ db.set("core.ats", f"ro{message.chat.id}", perms_list)
+
+ try:
+ await client.set_chat_permissions(message.chat.id, ChatPermissions())
+ except (UserAdminInvalid, ChatAdminRequired):
+ await message.edit("No rights")
+ else:
+ await message.edit(
+ "Read-only mode activated!\n"
+ f"Turn off with:{prefix}unro"
+ )
+ except Exception as e:
+ await message.edit(format_exc(e))
+
+
+@Client.on_message(filters.command("unro", prefix) & filters.me)
+async def unro(client: Client, message: Message):
+ if message.chat.type != "supergroup":
+ await message.edit("Invalid chat type")
+ return
+
+ try:
+ perms_list = db.get(
+ "core.ats",
+ f"ro{message.chat.id}",
+ [True, True, True, False, False, False, False, False],
+ )
+ perms = ChatPermissions(
+ can_send_messages=perms_list[0],
+ can_send_media_messages=perms_list[1],
+ can_send_other_messages=perms_list[2],
+ can_send_polls=perms_list[3],
+ can_add_web_page_previews=perms_list[4],
+ can_change_info=perms_list[5],
+ can_invite_users=perms_list[6],
+ can_pin_messages=perms_list[7],
+ )
+
+ try:
+ await client.set_chat_permissions(message.chat.id, perms)
+ except (UserAdminInvalid, ChatAdminRequired):
+ await message.edit("No rights")
+ else:
+ await message.edit("Read-only mode disabled!")
+ except Exception as e:
+ await message.edit(format_exc(e))
+
+
+@Client.on_message(filters.command("antiraid", prefix) & filters.me)
+async def antiraid(client: Client, message: Message):
+ if message.chat.type != "supergroup":
+ await message.edit("Not supported in non-supergroup chats")
+ return
+
+ if len(message.command) > 1 and message.command[1] == "on":
+ db.set("core.ats", f"antiraid{message.chat.id}", True)
+ group = await client.get_chat(message.chat.id)
+ if group.linked_chat:
+ db.set(
+ "core.ats", f"linked{message.chat.id}", group.linked_chat.id)
+ else:
+ db.set("core.ats", f"linked{message.chat.id}", 0)
+ await message.edit(
+ "Anti-raid mode enabled!\n"
+ f"Disable with: {prefix}antiraid off"
+ )
+ elif len(message.command) > 1 and message.command[1] == "off":
+ db.set("core.ats", f"antiraid{message.chat.id}", False)
+ await message.edit("Anti-raid mode disabled")
+ else:
+ # toggle
+ if db.get("core.ats", f"antiraid{message.chat.id}", False):
+ db.set("core.ats", f"antiraid{message.chat.id}", False)
+ await message.edit("Anti-raid mode disabled")
+ else:
+ db.set("core.ats", f"antiraid{message.chat.id}", True)
+ group = await client.get_chat(message.chat.id)
+ if group.linked_chat:
+ db.set(
+ "core.ats", f"linked{message.chat.id}", group.linked_chat.id)
+ else:
+ db.set("core.ats", f"linked{message.chat.id}", 0)
+ await message.edit(
+ "Anti-raid mode enabled!\n"
+ f"Disable with: {prefix}antiraid off"
+ )
+
+ update_cache()
+
+
+@Client.on_message(filters.command(["welcome", "wc"], prefix) & filters.me)
+async def welcome(_, message: Message):
+ if message.chat.type != "supergroup":
+ return await message.edit("Unsupported chat type")
+
+ if len(message.command) > 1:
+ text = message.text.split(maxsplit=1)[1]
+ db.set("core.ats", f"welcome_enabled{message.chat.id}", True)
+ db.set("core.ats", f"welcome_text{message.chat.id}", text)
+
+ await message.edit(
+ f"Welcome enabled in this chat\nText: {text}"
+ )
+ else:
+ db.set("core.ats", f"welcome_enabled{message.chat.id}", False)
+ await message.edit("Welcome disabled in this chat")
+
+ update_cache()
+
+
+modules_help["admintool"] = {
+ "ban [reply]/[username/id]* [reason] [report_spam] [delete_history]": "ban user in chat",
+ "unban [reply]/[username/id]* [reason]": "unban user in chat",
+ "kick [reply]/[userid]* [reason] [report_spam] [delete_history]": "kick user out of chat",
+ "mute [reply]/[userid]* [reason] [1m]/[1h]/[1d]/[1w]": "mute user in chat",
+ "unmute [reply]/[userid]* [reason]": "unmute user in chat",
+ "promote [reply]/[userid]* [prefix]": "promote user in chat",
+ "demote [reply]/[userid]* [reason]": "demote user in chat",
+ "tmute [reply]/[username/id]* [reason]": "delete all new messages from user in chat",
+ "tunmute [reply]/[username/id]* [reason]": "stop deleting all messages from user in chat",
+ "tmute_users": "list of tmuted (.tmute) users",
+ "antich [enable/disable]": "turn on/off blocking channels in this chat",
+ "delete_history [reply]/[username/id]* [reason]": "delete history from member in chat",
+ "report_spam [reply]*": "report spam message in chat",
+ "pin [reply]*": "Pin replied message",
+ "unpin [reply]*": "Unpin replied message",
+ "ro": "enable read-only mode",
+ "unro": "disable read-only mode",
+ "antiraid [on|off]": "when enabled, anyone who writes message will be blocked. Useful in raids. "
+ "Running without arguments equals to toggling state",
+ "welcome [text]*": "enable auto-welcome to new users in groups. "
+ "Running without text equals to disable",
+ "kickdel": "Kick all deleted accounts",
+}
diff --git a/modules/admlist.py b/modules/admlist.py
index 9199dd5..8e9bf65 100644
--- a/modules/admlist.py
+++ b/modules/admlist.py
@@ -1,129 +1,129 @@
-# Moon-Userbot - telegram userbot
- # Copyright (C) 2020-present Moon Userbot Organization
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
-
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
-
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see {prefix}admlist"
- )
-
-
- @Client.on_message(filters.command("admlist", prefix) & filters.me)
- async def admlist(client: Client, message: Message):
- await message.edit("Retrieving information... (it'll take some time)")
-
- start = perf_counter()
- try:
- response = await client.send(GetAllChats(except_ids=[]))
- chats = response["chats"]
-
- adminned_chats = []
- owned_chats = []
- owned_usernamed_chats = []
-
- for chat in chats:
- if getattr(chat, "migrated_to", None) is not None:
- continue
- if chat.creator and getattr(chat, "username", None):
- owned_usernamed_chats.append(chat)
- elif chat.creator:
- owned_chats.append(chat)
- elif getattr(chat, "admin_rights", None):
- adminned_chats.append(chat)
-
- text = "Adminned chats:\n"
- for index, chat in enumerate(adminned_chats):
- text += (
- f"{index + 1}. {chat.title}\n"
- )
-
- text += "\nOwned chats:\n"
- for index, chat in enumerate(owned_chats):
- text += (
- f"{index + 1}. {chat.title}\n"
- )
-
- text += "\nOwned chats with username:\n"
- for index, chat in enumerate(owned_usernamed_chats):
- text += (
- f"{index + 1}. {chat.title}\n"
- )
-
- stop = perf_counter()
- total_count = (
- len(adminned_chats) + len(owned_chats) + len(owned_usernamed_chats)
- )
- await message.edit(
- text + "\n"
- f"Total: {total_count}"
- f"\nAdminned chats: {len(adminned_chats)}\n"
- f"Owned chats: {len(owned_chats)}\n"
- f"Owned chats with username: {len(owned_usernamed_chats)}\n\n"
- f"Done at {round(stop - start, 3)} seconds."
- )
- except Exception as e:
- await message.edit(format_exc(e))
- return
-
-
- modules_help["admlist"] = {
- "admcount": "Get count of adminned and owned chats",
- "admlist": "Get list of adminned and owned chats",
- }
\ No newline at end of file
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see {prefix}admlist"
+ )
+
+
+@Client.on_message(filters.command("admlist", prefix) & filters.me)
+async def admlist(client: Client, message: Message):
+ await message.edit("Retrieving information... (it'll take some time)")
+
+ start = perf_counter()
+ try:
+ response = await client.send(GetAllChats(except_ids=[]))
+ chats = response["chats"]
+
+ adminned_chats = []
+ owned_chats = []
+ owned_usernamed_chats = []
+
+ for chat in chats:
+ if getattr(chat, "migrated_to", None) is not None:
+ continue
+ if chat.creator and getattr(chat, "username", None):
+ owned_usernamed_chats.append(chat)
+ elif chat.creator:
+ owned_chats.append(chat)
+ elif getattr(chat, "admin_rights", None):
+ adminned_chats.append(chat)
+
+ text = "Adminned chats:\n"
+ for index, chat in enumerate(adminned_chats):
+ text += (
+ f"{index + 1}. {chat.title}\n"
+ )
+
+ text += "\nOwned chats:\n"
+ for index, chat in enumerate(owned_chats):
+ text += (
+ f"{index + 1}. {chat.title}\n"
+ )
+
+ text += "\nOwned chats with username:\n"
+ for index, chat in enumerate(owned_usernamed_chats):
+ text += (
+ f"{index + 1}. {chat.title}\n"
+ )
+
+ stop = perf_counter()
+ total_count = (
+ len(adminned_chats) + len(owned_chats) + len(owned_usernamed_chats)
+ )
+ await message.edit(
+ text + "\n"
+ f"Total: {total_count}"
+ f"\nAdminned chats: {len(adminned_chats)}\n"
+ f"Owned chats: {len(owned_chats)}\n"
+ f"Owned chats with username: {len(owned_usernamed_chats)}\n\n"
+ f"Done at {round(stop - start, 3)} seconds."
+ )
+ except Exception as e:
+ await message.edit(format_exc(e))
+ return
+
+
+modules_help["admlist"] = {
+ "admcount": "Get count of adminned and owned chats",
+ "admlist": "Get list of adminned and owned chats",
+}
diff --git a/modules/afk.py b/modules/afk.py
index 567dfcf..4c8dbec 100644
--- a/modules/afk.py
+++ b/modules/afk.py
@@ -1,85 +1,86 @@
-# Moon-Userbot - telegram userbot
- # Copyright (C) 2020-present Moon Userbot Organization
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
-
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
-
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see {prefix}antipm disable"
- )
- else:
- await message.edit(
- "Anti-PM status: disabled\n"
- f"Enable with: {prefix}antipm enable"
- )
- elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
- db.set("core.antipm", "status", True)
- await message.edit("Anti-PM enabled!")
- elif message.command[1] in ["disable", "off", "0", "no", "false"]:
- db.set("core.antipm", "status", False)
- await message.edit("Anti-PM disabled!")
- else:
- await message.edit(f"Usage: {prefix}antipm [enable|disable]")
-
-
- @Client.on_message(filters.command(["antipm_report"], prefix) & filters.me)
- async def antipm_report(_, message: Message):
- if len(message.command) == 1:
- if db.get("core.antipm", "spamrep", False):
- await message.edit(
- "Spam-reporting enabled.\n"
- f"Disable with: {prefix}antipm_report disable"
- )
- else:
- await message.edit(
- "Spam-reporting disabled.\n"
- f"Enable with: {prefix}antipm_report enable"
- )
- elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
- db.set("core.antipm", "spamrep", True)
- await message.edit("Spam-reporting enabled!")
- elif message.command[1] in ["disable", "off", "0", "no", "false"]:
- db.set("core.antipm", "spamrep", False)
- await message.edit("Spam-reporting disabled!")
- else:
- await message.edit(f"Usage: {prefix}antipm_report [enable|disable]")
-
-
- @Client.on_message(filters.command(["antipm_block"], prefix) & filters.me)
- async def antipm_block(_, message: Message):
- if len(message.command) == 1:
- if db.get("core.antipm", "block", False):
- await message.edit(
- "Blocking users enabled.\n"
- f"Disable with: {prefix}antipm_block disable"
- )
- else:
- await message.edit(
- "Blocking users disabled.\n"
- f"Enable with: {prefix}antipm_block enable"
- )
- elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
- db.set("core.antipm", "block", True)
- await message.edit("Blocking users enabled!")
- elif message.command[1] in ["disable", "off", "0", "no", "false"]:
- db.set("core.antipm", "block", False)
- await message.edit("Blocking users disabled!")
- else:
- await message.edit(f"Usage: {prefix}antipm_block [enable|disable]")
-
-
- modules_help["antipm"] = {
- "antipm [enable|disable]*": "When enabled, deletes all messages from users who are not in the contact book",
- "antipm_report [enable|disable]*": "Enable spam reporting",
- "antipm_block [enable|disable]*": "Enable user blocking",
- }
\ No newline at end of file
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see {prefix}antipm disable"
+ )
+ else:
+ await message.edit(
+ "Anti-PM status: disabled\n"
+ f"Enable with: {prefix}antipm enable"
+ )
+ elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
+ db.set("core.antipm", "status", True)
+ await message.edit("Anti-PM enabled!")
+ elif message.command[1] in ["disable", "off", "0", "no", "false"]:
+ db.set("core.antipm", "status", False)
+ await message.edit("Anti-PM disabled!")
+ else:
+ await message.edit(f"Usage: {prefix}antipm [enable|disable]")
+
+
+@Client.on_message(filters.command(["antipm_report"], prefix) & filters.me)
+async def antipm_report(_, message: Message):
+ if len(message.command) == 1:
+ if db.get("core.antipm", "spamrep", False):
+ await message.edit(
+ "Spam-reporting enabled.\n"
+ f"Disable with: {prefix}antipm_report disable"
+ )
+ else:
+ await message.edit(
+ "Spam-reporting disabled.\n"
+ f"Enable with: {prefix}antipm_report enable"
+ )
+ elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
+ db.set("core.antipm", "spamrep", True)
+ await message.edit("Spam-reporting enabled!")
+ elif message.command[1] in ["disable", "off", "0", "no", "false"]:
+ db.set("core.antipm", "spamrep", False)
+ await message.edit("Spam-reporting disabled!")
+ else:
+ await message.edit(f"Usage: {prefix}antipm_report [enable|disable]")
+
+
+@Client.on_message(filters.command(["antipm_block"], prefix) & filters.me)
+async def antipm_block(_, message: Message):
+ if len(message.command) == 1:
+ if db.get("core.antipm", "block", False):
+ await message.edit(
+ "Blocking users enabled.\n"
+ f"Disable with: {prefix}antipm_block disable"
+ )
+ else:
+ await message.edit(
+ "Blocking users disabled.\n"
+ f"Enable with: {prefix}antipm_block enable"
+ )
+ elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
+ db.set("core.antipm", "block", True)
+ await message.edit("Blocking users enabled!")
+ elif message.command[1] in ["disable", "off", "0", "no", "false"]:
+ db.set("core.antipm", "block", False)
+ await message.edit("Blocking users disabled!")
+ else:
+ await message.edit(f"Usage: {prefix}antipm_block [enable|disable]")
+
+
+modules_help["antipm"] = {
+ "antipm [enable|disable]*": "When enabled, deletes all messages from users who are not in the contact book",
+ "antipm_report [enable|disable]*": "Enable spam reporting",
+ "antipm_block [enable|disable]*": "Enable user blocking",
+}
diff --git a/modules/clear_notifs.py b/modules/clear_notifs.py
index 8f5d254..195c5b1 100644
--- a/modules/clear_notifs.py
+++ b/modules/clear_notifs.py
@@ -1,72 +1,88 @@
-from pyrogram import Client, filters
- from pyrogram.errors import FloodWait
- from pyrogram.raw import functions, types
- from pyrogram.types import Message
-
- from utils.misc import modules_help, prefix
-
-
- @Client.on_message(filters.command(["clear_@"], prefix) & filters.me)
- async def solo_mention_clear(client: Client, message: Message):
- await message.delete()
- peer = await client.resolve_peer(message.chat.id)
- request = functions.messages.ReadMentions(peer=peer)
- await client.send(request)
-
-
- @Client.on_message(filters.command(["clear_all_@"], prefix) & filters.me)
- async def global_mention_clear(client: Client, message: Message):
- request = functions.messages.GetAllChats(except_ids=[])
- try:
- result = await client.send(request)
- except FloodWait as e:
- await message.edit_text(
- f"FloodWait received. Wait {e.x} seconds before trying again"
- )
- return
- await message.delete()
- for chat in result.chats:
- if type(chat) is types.Chat:
- peer_id = -chat.id
- elif type(chat) is types.Channel:
- peer_id = int(f"-100{chat.id}")
- peer = await client.resolve_peer(peer_id)
- request = functions.messages.ReadMentions(peer=peer)
- await client.send(request)
-
-
- @Client.on_message(filters.command(["clear_reacts"], prefix) & filters.me)
- async def solo_reaction_clear(client: Client, message: Message):
- await message.delete()
- peer = await client.resolve_peer(message.chat.id)
- request = functions.messages.ReadReactions(peer=peer)
- await client.send(request)
-
-
- @Client.on_message(filters.command(["clear_all_reacts"], prefix) & filters.me)
- async def global_reaction_clear(client: Client, message: Message):
- request = functions.messages.GetAllChats(except_ids=[])
- try:
- result = await client.send(request)
- except FloodWait as e:
- await message.edit_text(
- f"FloodWait received. Wait {e.x} seconds before trying again"
- )
- return
- await message.delete()
- for chat in result.chats:
- if type(chat) is types.Chat:
- peer_id = -chat.id
- elif type(chat) is types.Channel:
- peer_id = int(f"-100{chat.id}")
- peer = await client.resolve_peer(peer_id)
- request = functions.messages.ReadReactions(peer=peer)
- await client.send(request)
-
-
- modules_help["clear_notifs"] = {
- "clear_@": "clear all mentions in this chat",
- "clear_all_@": "clear all mentions in all chats",
- "clear_reacts": "clear all reactions in this chat",
- "clear_all_reacts": "clear all reactions in all chats (except private chats)",
- }
\ No newline at end of file
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see FloodWait received. Wait {e.x} seconds before trying again"
+ )
+ return
+ await message.delete()
+ for chat in result.chats:
+ if type(chat) is types.Chat:
+ peer_id = -chat.id
+ elif type(chat) is types.Channel:
+ peer_id = int(f"-100{chat.id}")
+ peer = await client.resolve_peer(peer_id)
+ request = functions.messages.ReadMentions(peer=peer)
+ await client.send(request)
+
+
+@Client.on_message(filters.command(["clear_reacts"], prefix) & filters.me)
+async def solo_reaction_clear(client: Client, message: Message):
+ await message.delete()
+ peer = await client.resolve_peer(message.chat.id)
+ request = functions.messages.ReadReactions(peer=peer)
+ await client.send(request)
+
+
+@Client.on_message(filters.command(["clear_all_reacts"], prefix) & filters.me)
+async def global_reaction_clear(client: Client, message: Message):
+ request = functions.messages.GetAllChats(except_ids=[])
+ try:
+ result = await client.send(request)
+ except FloodWait as e:
+ await message.edit_text(
+ f"FloodWait received. Wait {e.x} seconds before trying again"
+ )
+ return
+ await message.delete()
+ for chat in result.chats:
+ if type(chat) is types.Chat:
+ peer_id = -chat.id
+ elif type(chat) is types.Channel:
+ peer_id = int(f"-100{chat.id}")
+ peer = await client.resolve_peer(peer_id)
+ request = functions.messages.ReadReactions(peer=peer)
+ await client.send(request)
+
+
+modules_help["clear_notifs"] = {
+ "clear_@": "clear all mentions in this chat",
+ "clear_all_@": "clear all mentions in all chats",
+ "clear_reacts": "clear all reactions in this chat",
+ "clear_all_reacts": "clear all reactions in all chats (except private chats)",
+}
diff --git a/modules/example.py b/modules/example.py
index 32e6528..5dbdeb6 100644
--- a/modules/example.py
+++ b/modules/example.py
@@ -1,53 +1,53 @@
-# Moon-Userbot - telegram userbot
- # Copyright (C) 2020-present Moon Userbot Organization
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
-
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
-
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see This is an example module")
-
-
- @Client.on_message(filters.command("example_send", prefix) & filters.me)
- async def example_send(client: Client, message: Message):
- await client.send_message(message.chat.id, "This is an example module")
-
-
- # This adds instructions for your module
- modules_help["example"] = {
- "example_send": "example send",
- "example_edit": "example edit",
- }
-
- # modules_help["example"] = { "example_send [text]": "example send" }
- # | | | |
- # | | | └─ command description
- # module_name command_name └─ optional command arguments
- # (only snake_case) (only snake_case too)
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see This is an example module")
+
+
+@Client.on_message(filters.command("example_send", prefix) & filters.me)
+async def example_send(client: Client, message: Message):
+ await client.send_message(message.chat.id, "This is an example module")
+
+
+# This adds instructions for your module
+modules_help["example"] = {
+ "example_send": "example send",
+ "example_edit": "example edit",
+}
+
+# modules_help["example"] = { "example_send [text]": "example send" }
+# | | | |
+# | | | └─ command description
+# module_name command_name └─ optional command arguments
+# (only snake_case) (only snake_case too)
diff --git a/modules/filters.py b/modules/filters.py
index 18f26d4..69f5d0a 100644
--- a/modules/filters.py
+++ b/modules/filters.py
@@ -1,3 +1,19 @@
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see {
- prefix
-}filter [name] (Reply required)"
-)
-name = message.text.split(maxsplit = 1)[1].lower()
-chat_filters = get_filters_chat(message.chat.id)
-if name in chat_filters.keys():
-return await message.edit(
-f"Filter {
- name
-} already exists."
-)
-if not message.reply_to_message:
-return await message.edit("Reply to message please.")
+ try:
+ if len(message.text.split()) < 2:
+ return await message.edit(
+ f"Usage: {prefix}filter [name] (Reply required)"
+ )
+ name = message.text.split(maxsplit=1)[1].lower()
+ chat_filters = get_filters_chat(message.chat.id)
+ if name in chat_filters.keys():
+ return await message.edit(
+ f"Filter {name} already exists."
+ )
+ if not message.reply_to_message:
+ return await message.edit("Reply to message please.")
-try:
-chat = await client.get_chat(db.get("core.notes", "chat_id", 0))
-except (errors.RPCError, ValueError, KeyError):
-# group is not accessible or isn't created
-chat = await client.create_supergroup(
- "Moon_Userbot_Notes_Filters", "Don't touch this group, please"
-)
-db.set("core.notes", "chat_id", chat.id)
+ try:
+ chat = await client.get_chat(db.get("core.notes", "chat_id", 0))
+ except (errors.RPCError, ValueError, KeyError):
+ # group is not accessible or isn't created
+ chat = await client.create_supergroup(
+ "Moon_Userbot_Notes_Filters", "Don't touch this group, please"
+ )
+ db.set("core.notes", "chat_id", chat.id)
-chat_id = chat.id
+ chat_id = chat.id
-if message.reply_to_message.media_group_id:
-get_media_group = [
- _.message_id
- for _ in await client.get_media_group(
- message.chat.id, message.reply_to_message.message_id
- )
-]
-try:
-message_id = await client.forward_messages(
- chat_id, message.chat.id, get_media_group
-)
-except errors.ChatForwardsRestricted:
-await message.edit(
- "Forwarding messages is restricted by chat admins"
-)
-return
-filter_ = {
- "MESSAGE_ID": str(message_id[1].message_id),
- "MEDIA_GROUP": True,
- "CHAT_ID": str(chat_id),
-} else :
-try:
-message_id = await message.reply_to_message.forward(chat_id)
-except errors.ChatForwardsRestricted:
-if message.reply_to_message.text:
-# manual copy
-message_id = await client.send_message(
- chat_id, message.reply_to_message.text
-)
-else :
-await message.edit(
- "Forwarding messages is restricted by chat admins"
-)
-return
-filter_ = {
- "MEDIA_GROUP": False,
- "MESSAGE_ID": str(message_id.message_id),
- "CHAT_ID": str(chat_id),
-}
+ if message.reply_to_message.media_group_id:
+ get_media_group = [
+ _.message_id
+ for _ in await client.get_media_group(
+ message.chat.id, message.reply_to_message.message_id
+ )
+ ]
+ try:
+ message_id = await client.forward_messages(
+ chat_id, message.chat.id, get_media_group
+ )
+ except errors.ChatForwardsRestricted:
+ await message.edit(
+ "Forwarding messages is restricted by chat admins"
+ )
+ return
+ filter_ = {
+ "MESSAGE_ID": str(message_id[1].message_id),
+ "MEDIA_GROUP": True,
+ "CHAT_ID": str(chat_id),
+ }
+ else:
+ try:
+ message_id = await message.reply_to_message.forward(chat_id)
+ except errors.ChatForwardsRestricted:
+ if message.reply_to_message.text:
+ # manual copy
+ message_id = await client.send_message(
+ chat_id, message.reply_to_message.text
+ )
+ else:
+ await message.edit(
+ "Forwarding messages is restricted by chat admins"
+ )
+ return
+ filter_ = {
+ "MEDIA_GROUP": False,
+ "MESSAGE_ID": str(message_id.message_id),
+ "CHAT_ID": str(chat_id),
+ }
-chat_filters.update({
- name: filter_
-})
+ chat_filters.update({name: filter_})
-set_filters_chat(message.chat.id, chat_filters)
-return await message.edit(f"Filter {
- name
-} has been added.")
-except Exception as e:
-return await message.edit(format_exc(e))
+ set_filters_chat(message.chat.id, chat_filters)
+ return await message.edit(f"Filter {name} has been added.")
+ except Exception as e:
+ return await message.edit(format_exc(e))
@Client.on_message(filters.command(["filters"], prefix) & filters.me)
async def filters_handler(client: Client, message: Message):
-try:
-text = ""
-for index, a in enumerate(get_filters_chat(message.chat.id).items(), start = 1):
-key, item = a
-key = key.replace("<", "").replace(">", "")
-text += f" {
- index
-}. {
- key
-}\n"
-text = f"Your filters in current chat:\n\n" f" {
- text
-}"
-text = text[:4096]
-return await message.edit(text)
-except Exception as e:
-return await message.edit(format_exc(e))
+ try:
+ text = ""
+ for index, a in enumerate(get_filters_chat(message.chat.id).items(), start=1):
+ key, item = a
+ key = key.replace("<", "").replace(">", "")
+ text += f"{index}. {key}\n"
+ text = f"Your filters in current chat:\n\n" f"{text}"
+ text = text[:4096]
+ return await message.edit(text)
+ except Exception as e:
+ return await message.edit(format_exc(e))
@Client.on_message(
filters.command(["delfilter", "filterdel", "fdel"], prefix) & filters.me
)
async def filter_del_handler(client: Client, message: Message):
-try:
-if len(message.text.split()) < 2:
-return await message.edit(f"Usage: {
- prefix
-}fdel [name]")
-name = message.text.split(maxsplit = 1)[1].lower()
-chat_filters = get_filters_chat(message.chat.id)
-if name not in chat_filters.keys():
-return await message.edit(
-f"Filter {
- name
-} doesn't exists."
-)
-del chat_filters[name]
-set_filters_chat(message.chat.id, chat_filters)
-return await message.edit(
-f"Filter {
- name
-} has been deleted."
-)
-except Exception as e:
-return await message.edit(format_exc(e))
+ try:
+ if len(message.text.split()) < 2:
+ return await message.edit(f"Usage: {prefix}fdel [name]")
+ name = message.text.split(maxsplit=1)[1].lower()
+ chat_filters = get_filters_chat(message.chat.id)
+ if name not in chat_filters.keys():
+ return await message.edit(
+ f"Filter {name} doesn't exists."
+ )
+ del chat_filters[name]
+ set_filters_chat(message.chat.id, chat_filters)
+ return await message.edit(
+ f"Filter {name} has been deleted."
+ )
+ except Exception as e:
+ return await message.edit(format_exc(e))
@Client.on_message(filters.command(["fsearch"], prefix) & filters.me)
async def filter_search_handler(client: Client, message: Message):
-try:
-if len(message.text.split()) < 2:
-return await message.edit(
-f"Usage: {
- prefix
-}fsearch [name]"
-)
-name = message.text.split(maxsplit = 1)[1].lower()
-chat_filters = get_filters_chat(message.chat.id)
-if name not in chat_filters.keys():
-return await message.edit(
-f"Filter {
- name
-} doesn't exists."
-)
-return await message.edit(
-f"Trigger:\n {
- name
-}\nAnswer:\n {
- chat_filters[name]}"
-)
-except Exception as e:
-return await message.edit(format_exc(e))
+ try:
+ if len(message.text.split()) < 2:
+ return await message.edit(
+ f"Usage: {prefix}fsearch [name]"
+ )
+ name = message.text.split(maxsplit=1)[1].lower()
+ chat_filters = get_filters_chat(message.chat.id)
+ if name not in chat_filters.keys():
+ return await message.edit(
+ f"Filter {name} doesn't exists."
+ )
+ return await message.edit(
+ f"Trigger:\n{name}\nAnswer:\n{chat_filters[name]}"
+ )
+ except Exception as e:
+ return await message.edit(format_exc(e))
modules_help["filters"] = {
- "filter [name]": "Create filter (Reply required)",
- "filters": "List of all triggers",
- "fdel [name]": "Delete filter by name",
- "fsearch [name]": "Info filter by name",
-}
\ No newline at end of file
+ "filter [name]": "Create filter (Reply required)",
+ "filters": "List of all triggers",
+ "fdel [name]": "Delete filter by name",
+ "fsearch [name]": "Info filter by name",
+}
diff --git a/modules/help.py b/modules/help.py
index 9b5ddda..2bce099 100644
--- a/modules/help.py
+++ b/modules/help.py
@@ -1,18 +1,18 @@
-# Moon-Userbot - telegram userbot
-# Copyright (C) 2020-present Moon Userbot Organization
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see {
- prefix
- }help [module]\n\n"
- "Available Modules:\n"
-)
+ if len(message.command) == 1:
+ msg_edited = False
+ text = (
+ "Help for Moon-Userbot\n"
+ f"For more help on how to use a command, type {prefix}help [module]\n\n"
+ "Available Modules:\n"
+ )
-for module_name, module_commands in modules_help.items():
-text += "• {}: {}\n".format(
- module_name.title(),
- " ".join(
- [
-f" {
- prefix + cmd_name.split()[0]}"
- for cmd_name in module_commands.keys()
- ]
- ),
-)
-if len(text) >= 2048:
-text += ""
-if msg_edited:
-await message.reply(text, disable_web_page_preview = True)
-else :
-await message.edit(text, disable_web_page_preview = True)
-msg_edited = True
-text = ""
+ for module_name, module_commands in modules_help.items():
+ text += "• {}: {}\n".format(
+ module_name.title(),
+ " ".join(
+ [
+ f"{prefix + cmd_name.split()[0]}"
+ for cmd_name in module_commands.keys()
+ ]
+ ),
+ )
+ if len(text) >= 2048:
+ text += ""
+ if msg_edited:
+ await message.reply(text, disable_web_page_preview=True)
+ else:
+ await message.edit(text, disable_web_page_preview=True)
+ msg_edited = True
+ text = ""
-text += f"\nThe number of modules in the userbot: {
- len(modules_help) / 1
-}"
+ text += f"\nThe number of modules in the userbot: {len(modules_help) / 1}"
-if msg_edited:
-await message.reply(text, disable_web_page_preview = True)
-else :
-await message.edit(text, disable_web_page_preview = True)
-elif message.command[1].lower() in modules_help:
-await message.edit(format_module_help(message.command[1].lower()))
-else :
-# TODO: refactor this cringe
-command_name = message.command[1].lower()
-for name, commands in modules_help.items():
-for command in commands.keys():
-if command.split()[0] == command_name:
-cmd = command.split(maxsplit = 1)
-cmd_desc = commands[command]
-return await message.edit(
-f"Help for command {
- prefix
-} {
- command_name
-}\n"
-f"Module: {
- name
-} ( {
- prefix
-}help {
- name
-})\n\n"
-f" {
- prefix
-} {
- cmd[0]}"
-f" {
- ' ' + cmd[1] + '' if len(cmd) > 1 else ''
-}"
-f" — {
- cmd_desc
-}"
-)
-await message.edit(f"Module {
- command_name
-} not found")
+ if msg_edited:
+ await message.reply(text, disable_web_page_preview=True)
+ else:
+ await message.edit(text, disable_web_page_preview=True)
+ elif message.command[1].lower() in modules_help:
+ await message.edit(format_module_help(message.command[1].lower()))
+ else:
+ # TODO: refactor this cringe
+ command_name = message.command[1].lower()
+ for name, commands in modules_help.items():
+ for command in commands.keys():
+ if command.split()[0] == command_name:
+ cmd = command.split(maxsplit=1)
+ cmd_desc = commands[command]
+ return await message.edit(
+ f"Help for command {prefix}{command_name}\n"
+ f"Module: {name} ({prefix}help {name})\n\n"
+ f"{prefix}{cmd[0]}"
+ f"{' ' + cmd[1] + '' if len(cmd) > 1 else ''}"
+ f" — {cmd_desc}"
+ )
+ await message.edit(f"Module {command_name} not found")
modules_help["help"] = {
- "help [module/command name]": "Get common/module/command help"
-}
\ No newline at end of file
+ "help [module/command name]": "Get common/module/command help"}
diff --git a/modules/loader.py b/modules/loader.py
index 93498ce..a4a3115 100644
--- a/modules/loader.py
+++ b/modules/loader.py
@@ -1,225 +1,225 @@
-# Moon-Userbot - telegram userbot
- # Copyright (C) 2020-present Moon Userbot Organization
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
-
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
-
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see {url}"
- )
- return
-
- await message.edit(
- f"Module hash: {hashlib.sha256(resp.content).hexdigest()}\n"
- f"Link: {url}\nFile: {url.split('/')[-1]}"
- )
-
-
- @Client.on_message(filters.command(["loadmod", "lm"], prefix) & filters.me)
- async def loadmod(_, message: Message):
- if (
- not (
- message.reply_to_message
- and message.reply_to_message.document
- and message.reply_to_message.document.file_name.endswith(".py")
- )
- and len(message.command) == 1
- ):
- await message.edit("Specify module to download")
- return
-
- if len(message.command) > 1:
- url = message.command[1].lower()
-
- if url.startswith(
- "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
- ):
- module_name = url.split("/")[-1].split(".")[0]
- elif "/" not in url and "." not in url:
- module_name = url.lower()
- url = f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}.py"
- else:
- modules_hashes = requests.get(
- "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
- ).text
- resp = requests.get(url)
-
- if not resp.ok:
- await message.edit(
- f"Troubleshooting with downloading module {url}"
- )
- return
-
- if hashlib.sha256(resp.content).hexdigest() not in modules_hashes:
- return await message.edit(
- "Only "
- "verified modules or from the official "
- ""
- "custom_modules repository are supported!",
- disable_web_page_preview=True,
- )
-
- module_name = url.split("/")[-1].split(".")[0]
-
- resp = requests.get(url)
- if not resp.ok:
- await message.edit(f"Module {module_name} is not found")
- return
-
- if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
- os.mkdir(f"{BASE_PATH}/modules/custom_modules")
-
- with open(f"./modules/custom_modules/{module_name}.py", "wb") as f:
- f.write(resp.content)
- else:
- file_name = await message.reply_to_message.download()
- module_name = message.reply_to_message.document.file_name[:-3]
-
- with open(file_name, "rb") as f:
- content = f.read()
-
- modules_hashes = requests.get(
- "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
- ).text
-
- if hashlib.sha256(content).hexdigest() not in modules_hashes:
- os.remove(file_name)
- return await message.edit(
- "Only "
- "verified modules or from the official "
- ""
- "custom_modules repository are supported!",
- disable_web_page_preview=True,
- )
- else:
- os.rename(file_name, f"./modules/custom_modules/{module_name}.py")
-
- await message.edit(f"The module {module_name} is loaded!")
- restart()
-
-
- @Client.on_message(filters.command(["unloadmod", "ulm"], prefix) & filters.me)
- async def unload_mods(_, message: Message):
- if len(message.command) <= 1:
- return
-
- module_name = message.command[1].lower()
-
- if module_name.startswith(
- "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
- ):
- module_name = module_name.split("/")[-1].split(".")[0]
-
- if os.path.exists(f"{BASE_PATH}/modules/custom_modules/{module_name}.py"):
- os.remove(f"{BASE_PATH}/modules/custom_modules/{module_name}.py")
- await message.edit(f"The module {module_name} removed!")
- restart()
- elif os.path.exists(f"{BASE_PATH}/modules/{module_name}.py"):
- await message.edit(
- "It is forbidden to remove built-in modules, it will disrupt the updater"
- )
- else:
- await message.edit(f"Module {module_name} is not found")
-
-
- @Client.on_message(filters.command(["loadallmods"], prefix) & filters.me)
- async def load_all_mods(_, message: Message):
- await message.edit("Fetching info...")
-
- if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
- os.mkdir(f"{BASE_PATH}/modules/custom_modules")
-
- modules_list = requests.get(
- "https://api.github.com/repos/The-MoonTg-project/custom_modules/contents/"
- ).json()
-
- new_modules = {}
- for module_info in modules_list:
- if not module_info["name"].endswith(".py"):
- continue
- if os.path.exists(f'{BASE_PATH}/modules/custom_modules/{module_info["name"]}'):
- continue
- new_modules[module_info["name"][:-3]] = module_info["download_url"]
- if not new_modules:
- return await message.edit("All modules already loaded")
-
- await message.edit(f'Loading new modules: {" ".join(new_modules.keys())}')
- for name, url in new_modules.items():
- with open(f"./modules/custom_modules/{name}.py", "wb") as f:
- f.write(requests.get(url).content)
-
- await message.edit(
- f'Successfully loaded new modules: {" ".join(new_modules.keys())}'
- )
- restart()
-
-
- @Client.on_message(filters.command(["updateallmods"], prefix) & filters.me)
- async def updateallmods(_, message: Message):
- await message.edit("Updating modules...")
-
- if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
- os.mkdir(f"{BASE_PATH}/modules/custom_modules")
-
- modules_installed = list(os.walk("modules/custom_modules"))[0][2]
-
- if not modules_installed:
- return await message.edit("You don't have any modules installed")
-
- for module_name in modules_installed:
- if not module_name.endswith(".py"):
- continue
-
- resp = requests.get(
- f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}"
- )
- if not resp.ok:
- modules_installed.remove(module_name)
- continue
-
- with open(f"./modules/custom_modules/{module_name}", "wb") as f:
- f.write(resp.content)
-
- await message.edit(f"Successfully updated {len(modules_installed)} modules")
-
-
- modules_help["loader"] = {
- "loadmod [module_name]*": "Download module.\n"
- "Only modules from the official custom_modules repository and proven "
- "modules whose hashes are in modules_hashes.txt are supported",
- "unloadmod [module_name]*": "Delete module",
- "modhash [link]*": "Get module hash by link",
- "loadallmods": "Load all custom modules (use it at your own risk)",
- "updateallmods": "Update all custom modules",
- }
\ No newline at end of file
+# Moon-Userbot - telegram userbot
+# Copyright (C) 2020-present Moon Userbot Organization
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see {url}"
+ )
+ return
+
+ await message.edit(
+ f"Module hash: {hashlib.sha256(resp.content).hexdigest()}\n"
+ f"Link: {url}\nFile: {url.split('/')[-1]}"
+ )
+
+
+@Client.on_message(filters.command(["loadmod", "lm"], prefix) & filters.me)
+async def loadmod(_, message: Message):
+ if (
+ not (
+ message.reply_to_message
+ and message.reply_to_message.document
+ and message.reply_to_message.document.file_name.endswith(".py")
+ )
+ and len(message.command) == 1
+ ):
+ await message.edit("Specify module to download")
+ return
+
+ if len(message.command) > 1:
+ url = message.command[1].lower()
+
+ if url.startswith(
+ "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
+ ):
+ module_name = url.split("/")[-1].split(".")[0]
+ elif "/" not in url and "." not in url:
+ module_name = url.lower()
+ url = f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}.py"
+ else:
+ modules_hashes = requests.get(
+ "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
+ ).text
+ resp = requests.get(url)
+
+ if not resp.ok:
+ await message.edit(
+ f"Troubleshooting with downloading module {url}"
+ )
+ return
+
+ if hashlib.sha256(resp.content).hexdigest() not in modules_hashes:
+ return await message.edit(
+ "Only "
+ "verified modules or from the official "
+ ""
+ "custom_modules repository are supported!",
+ disable_web_page_preview=True,
+ )
+
+ module_name = url.split("/")[-1].split(".")[0]
+
+ resp = requests.get(url)
+ if not resp.ok:
+ await message.edit(f"Module {module_name} is not found")
+ return
+
+ if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
+ os.mkdir(f"{BASE_PATH}/modules/custom_modules")
+
+ with open(f"./modules/custom_modules/{module_name}.py", "wb") as f:
+ f.write(resp.content)
+ else:
+ file_name = await message.reply_to_message.download()
+ module_name = message.reply_to_message.document.file_name[:-3]
+
+ with open(file_name, "rb") as f:
+ content = f.read()
+
+ modules_hashes = requests.get(
+ "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
+ ).text
+
+ if hashlib.sha256(content).hexdigest() not in modules_hashes:
+ os.remove(file_name)
+ return await message.edit(
+ "Only "
+ "verified modules or from the official "
+ ""
+ "custom_modules repository are supported!",
+ disable_web_page_preview=True,
+ )
+ else:
+ os.rename(file_name, f"./modules/custom_modules/{module_name}.py")
+
+ await message.edit(f"The module {module_name} is loaded!")
+ restart()
+
+
+@Client.on_message(filters.command(["unloadmod", "ulm"], prefix) & filters.me)
+async def unload_mods(_, message: Message):
+ if len(message.command) <= 1:
+ return
+
+ module_name = message.command[1].lower()
+
+ if module_name.startswith(
+ "https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
+ ):
+ module_name = module_name.split("/")[-1].split(".")[0]
+
+ if os.path.exists(f"{BASE_PATH}/modules/custom_modules/{module_name}.py"):
+ os.remove(f"{BASE_PATH}/modules/custom_modules/{module_name}.py")
+ await message.edit(f"The module {module_name} removed!")
+ restart()
+ elif os.path.exists(f"{BASE_PATH}/modules/{module_name}.py"):
+ await message.edit(
+ "It is forbidden to remove built-in modules, it will disrupt the updater"
+ )
+ else:
+ await message.edit(f"Module {module_name} is not found")
+
+
+@Client.on_message(filters.command(["loadallmods"], prefix) & filters.me)
+async def load_all_mods(_, message: Message):
+ await message.edit("Fetching info...")
+
+ if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
+ os.mkdir(f"{BASE_PATH}/modules/custom_modules")
+
+ modules_list = requests.get(
+ "https://api.github.com/repos/The-MoonTg-project/custom_modules/contents/"
+ ).json()
+
+ new_modules = {}
+ for module_info in modules_list:
+ if not module_info["name"].endswith(".py"):
+ continue
+ if os.path.exists(f'{BASE_PATH}/modules/custom_modules/{module_info["name"]}'):
+ continue
+ new_modules[module_info["name"][:-3]] = module_info["download_url"]
+ if not new_modules:
+ return await message.edit("All modules already loaded")
+
+ await message.edit(f'Loading new modules: {" ".join(new_modules.keys())}')
+ for name, url in new_modules.items():
+ with open(f"./modules/custom_modules/{name}.py", "wb") as f:
+ f.write(requests.get(url).content)
+
+ await message.edit(
+ f'Successfully loaded new modules: {" ".join(new_modules.keys())}'
+ )
+ restart()
+
+
+@Client.on_message(filters.command(["updateallmods"], prefix) & filters.me)
+async def updateallmods(_, message: Message):
+ await message.edit("Updating modules...")
+
+ if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
+ os.mkdir(f"{BASE_PATH}/modules/custom_modules")
+
+ modules_installed = list(os.walk("modules/custom_modules"))[0][2]
+
+ if not modules_installed:
+ return await message.edit("You don't have any modules installed")
+
+ for module_name in modules_installed:
+ if not module_name.endswith(".py"):
+ continue
+
+ resp = requests.get(
+ f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}"
+ )
+ if not resp.ok:
+ modules_installed.remove(module_name)
+ continue
+
+ with open(f"./modules/custom_modules/{module_name}", "wb") as f:
+ f.write(resp.content)
+
+ await message.edit(f"Successfully updated {len(modules_installed)} modules")
+
+
+modules_help["loader"] = {
+ "loadmod [module_name]*": "Download module.\n"
+ "Only modules from the official custom_modules repository and proven "
+ "modules whose hashes are in modules_hashes.txt are supported",
+ "unloadmod [module_name]*": "Delete module",
+ "modhash [link]*": "Get module hash by link",
+ "loadallmods": "Load all custom modules (use it at your own risk)",
+ "updateallmods": "Update all custom modules",
+}
diff --git a/termux-install.sh b/termux-install.sh
index 08ec188..666fce7 100644
--- a/termux-install.sh
+++ b/termux-install.sh
@@ -29,7 +29,7 @@ if ! command -v termux-setup-storage; then
echo
echo "Enter API_ID and API_HASH"
- echo "You can get it here -> https://my.telegram.org/apps"
+ echo "You can get it here -> https://my.telegram.org/"
echo "Leave empty to use defaults (please note that default keys significantly increases your ban chances)"
read -r -p "API_ID > " api_id
diff --git a/utils/db.py b/utils/db.py
index 7ce5dd8..0787aa1 100644
--- a/utils/db.py
+++ b/utils/db.py
@@ -1,170 +1,170 @@
-# Moon-Userbot - telegram userbot
- # Copyright (C) 2020-present Moon Userbot Organization
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
-
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
-
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see [ {
- e.CODE
-} {
- e.ID or e.NAME
-}] - {
- e.MESSAGE
-}"
-)
-else :
-if hint:
-hint_text = f"\n\nHint: {
- hint
-}"
-else :
-hint_text = ""
-return (
-f"Error!\n" f" {
- e.__class__.__name__
-}: {
- e
-}" + hint_text
-)
+ traceback.print_exc()
+ if isinstance(e, errors.RPCError):
+ return (
+ f"Telegram API error!\n"
+ f"[{e.CODE} {e.ID or e.NAME}] - {e.MESSAGE}"
+ )
+ else:
+ if hint:
+ hint_text = f"\n\nHint: {hint}"
+ else:
+ hint_text = ""
+ return (
+ f"Error!\n" f"{e.__class__.__name__}: {e}" + hint_text
+ )
def with_reply(func):
-async def wrapped(client: Client, message: types.Message):
-if not message.reply_to_message:
-await message.edit("Reply to message is required")
-else :
-return await func(client, message)
+ async def wrapped(client: Client, message: types.Message):
+ if not message.reply_to_message:
+ await message.edit("Reply to message is required")
+ else:
+ return await func(client, message)
-return wrapped
+ return wrapped
async def interact_with(message: types.Message) -> types.Message:
-"""
- Check history with bot and return bot's response
- Example:
- .. code-block:: python
- bot_msg = await interact_with(await bot.send_message("@BotFather", "/start"))
- :param message: already sent message to bot
- :return: bot's response
- """
+ """
+ Check history with bot and return bot's response
+ Example:
+ .. code-block:: python
+ bot_msg = await interact_with(await bot.send_message("@BotFather", "/start"))
+ :param message: already sent message to bot
+ :return: bot's response
+ """
-await asyncio.sleep(1)
-# noinspection PyProtectedMember
-response = await message._client.get_history(message.chat.id, limit = 1)
-seconds_waiting = 0
+ await asyncio.sleep(1)
+ # noinspection PyProtectedMember
+ response = await message._client.get_history(message.chat.id, limit=1)
+ seconds_waiting = 0
-while response[0].from_user.is_self:
-seconds_waiting += 1
-if seconds_waiting >= 5:
-raise RuntimeError("bot didn't answer in 5 seconds")
+ while response[0].from_user.is_self:
+ seconds_waiting += 1
+ if seconds_waiting >= 5:
+ raise RuntimeError("bot didn't answer in 5 seconds")
-await asyncio.sleep(1)
-# noinspection PyProtectedMember
-response = await message._client.get_history(message.chat.id, limit = 1)
+ await asyncio.sleep(1)
+ # noinspection PyProtectedMember
+ response = await message._client.get_history(message.chat.id, limit=1)
-interact_with_to_delete.append(message.message_id)
-interact_with_to_delete.append(response[0].message_id)
+ interact_with_to_delete.append(message.message_id)
+ interact_with_to_delete.append(response[0].message_id)
-return response[0]
+ return response[0]
interact_with_to_delete = []
def format_module_help(module_name: str):
-commands = modules_help[module_name]
+ commands = modules_help[module_name]
-help_text = f"Help for | {
- module_name
-}|\n\nUsage:\n"
+ help_text = f"Help for |{module_name}|\n\nUsage:\n"
-for command, desc in commands.items():
-cmd = command.split(maxsplit = 1)
-args = " " + cmd[1] + "" if len(cmd) > 1 else ""
-help_text += f" {
- prefix
-} {
- cmd[0]} {
- args
-} — {
- desc
-}\n"
+ for command, desc in commands.items():
+ cmd = command.split(maxsplit=1)
+ args = " " + cmd[1] + "" if len(cmd) > 1 else ""
+ help_text += f"{prefix}{cmd[0]}{args} — {desc}\n"
-return help_text
+ return help_text
def format_small_module_help(module_name: str):
-commands = modules_help[module_name]
+ commands = modules_help[module_name]
-help_text = f"Help for | {
- module_name
-}|\n\nCommands list:\n"
-for command, desc in commands.items():
-cmd = command.split(maxsplit = 1)
-args = " " + cmd[1] + "" if len(cmd) > 1 else ""
-help_text += f" {
- prefix
-} {
- cmd[0]} {
- args
-}\n"
-help_text += f"\nGet full usage: {
- prefix
-}help {
- module_name
-}"
+ help_text = f"Help for |{module_name}|\n\nCommands list:\n"
+ for command, desc in commands.items():
+ cmd = command.split(maxsplit=1)
+ args = " " + cmd[1] + "" if len(cmd) > 1 else ""
+ help_text += f"{prefix}{cmd[0]}{args}\n"
+ help_text += f"\nGet full usage: {prefix}help {module_name}"
-return help_text
+ return help_text
def import_library(library_name: str, package_name: str = None):
-"""
- Loads a library, or installs it in ImportError case
- :param library_name: library name (import example...)
- :param package_name: package name in PyPi (pip install example)
- :return: loaded module
- """
-if package_name is None:
-package_name = library_name
-requirements_list.append(package_name)
+ """
+ Loads a library, or installs it in ImportError case
+ :param library_name: library name (import example...)
+ :param package_name: package name in PyPi (pip install example)
+ :return: loaded module
+ """
+ if package_name is None:
+ package_name = library_name
+ requirements_list.append(package_name)
-try:
-return importlib.import_module(library_name)
-except ImportError:
-completed = subprocess.run(["python3", "-m", "pip", "install", package_name])
-if completed.returncode != 0:
-raise AssertionError(
-f"Failed to install library {
- package_name
-} (pip exited with code {
- completed.returncode
-})"
-)
-return importlib.import_module(library_name)
+ try:
+ return importlib.import_module(library_name)
+ except ImportError:
+ completed = subprocess.run(
+ ["python3", "-m", "pip", "install", package_name])
+ if completed.returncode != 0:
+ raise AssertionError(
+ f"Failed to install library {package_name} (pip exited with code {completed.returncode})"
+ )
+ return importlib.import_module(library_name)
-def resize_image(input_img, output = None, img_type = "PNG"):
-if output is None:
-output = BytesIO()
-output.name = f"sticker. {
- img_type.lower()}"
+def resize_image(input_img, output=None, img_type="PNG"):
+ if output is None:
+ output = BytesIO()
+ output.name = f"sticker.{img_type.lower()}"
-with Image.open(input_img) as img:
-# We used to use thumbnail(size) here, but it returns with a *max* dimension of 512,512
-# rather than making one side exactly 512 so we have to calculate dimensions manually :(
-if img.width == img.height:
-size = (512, 512)
-elif img.width < img.height:
-size = (max(512 * img.width // img.height, 1), 512)
-else :
-size = (512, max(512 * img.height // img.width, 1))
+ with Image.open(input_img) as img:
+ # We used to use thumbnail(size) here, but it returns with a *max* dimension of 512,512
+ # rather than making one side exactly 512 so we have to calculate dimensions manually :(
+ if img.width == img.height:
+ size = (512, 512)
+ elif img.width < img.height:
+ size = (max(512 * img.width // img.height, 1), 512)
+ else:
+ size = (512, max(512 * img.height // img.width, 1))
-img.resize(size).save(output, img_type)
+ img.resize(size).save(output, img_type)
-return output
\ No newline at end of file
+ return output