diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 0000000..25bc3d7 --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,8 @@ +version = 1 + +[[analyzers]] +name = "python" +enabled = true + + [analyzers.meta] + runtime_version = "3.x.x" diff --git a/README.md b/README.md index 11c4244..c7e5d9b 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,29 @@ # Feedback-Bot - Hey, This Is [Feedback Bot](https://telegram.dog/HeimanSupportsBot/) Made By Using Python And Pyrogram Framework - This is enovation of [HeimanCreation](https://github.com/HeimanPictures/HeimanPictures/) šŸ˜‡. + Hey, This Is [Feedback Bot](/) Made By Using Python And Pyrogram Framework + This is enovation of [AkKiL](https://github.com/HeimanPictures/HeimanPictures/) šŸ˜‡. This Bot Works Like Independent @LivegramBot, But With Extra Command And Even Logs Of The User Who Have Used Start Command Of The Bot... - I Have Not Yet Added Any Database And Ban And UnBan Feature In This Repo. If You Need That Commands And Features Just Request Us [@HeimanSupport](https://telegram.dog/HeimanSupport/). We Will Try To Add It Soon.. ## Installation ### Direct #### You can also tap the Deploy To Heroku button below to deploy straight to Heroku! -[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/HeimanPictures/Feedback-Bot/tree/Heroku/) +

Deploy To Heroku

-### DF Way +#### You can also tap the Deploy To Railway button below to deploy straight to Railway! + + +

Deploy To Railway

+ + +### Local Deploy #### Terminal Or Some VPS Use This Way Of Deploy.. šŸ˜‡ ``` -git clone https://github.com/HeimanPictures/Feedback-bot/tree/Heroku +git clone https://github.com/HeimanPictures/Feedback-bot/ cd Feedback-bot virtualenv -p python3 VENV . ./VENV/bin/activate @@ -30,9 +35,88 @@ python bot.py ## To-Do -- Database -- Broadcast & No. Of Users -- Ban & Unban +- None + + +## Config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BOT_TOKENYour Bots Token from Bot Father.
API_IDYour Telegram API ID from Telegram API ID.
API_HASHYour Bots Token from Telegram API HASH.
AUTH_USERSProvide AUTH User ID to use admin function
BROADCAST_AS_COPYSIf you provide value False then it will Forward with tag and if you give value as True then without tag. As True or False
LOG_CHANNELMake a channel add the bot as admin and get the id of the channel using @googleimgbot
DB_URLProvided Mongodb Database link from mongodb.com
DB_NAMEProvide name for DB to make session (anything)
UPDATE_CHANNELYour Channel Link
SUPPORT_GROUPYour Group Link
DONATE_LINKYour Donation Link
DONATE_TEXTYour Donate Text as a string.
OWNER_IDYour ID Or Who need is going to handle this bot.
START_TEXTYour Start message as a string & There Is default Of 'Hello '.
HELP_TEXTYour Help Text as a string.
+ +## Commands for this Bot + +```command +start - To Start +help - To get help +donate - To get donate +about - To Know About me +settings - To get settings +stats - To get stats +ban_user - To ban user +unban_user - To unban user +banned_users - To get banned user +broadcast - To Broadcast [Admin] +``` ## Note Kangers Keep Some Distance.. @@ -46,4 +130,4 @@ python bot.py ## Credits -- Thanks To [Heiman Creation](https://telegram.dog/HeimanCreation/) +- Thanks To [AkKiL](https://telegram.dog/HeimanCreation/) diff --git a/app.json b/app.json index 3e9f310..7465469 100644 --- a/app.json +++ b/app.json @@ -7,7 +7,7 @@ "feedback", "bot" ], - "success_url": "https://telegram.dog//", + "success_url": "/", "website": "https://github.com/HeimanPictures/HeimanPictures/", "repository": "https://github.com/HeimanPictures/Feedback-bot/", "env": { @@ -21,7 +21,7 @@ }, "OWNER_ID": { "description": "Your ID Or Who need is going to handle this bot", - "value": "" + "value": "1428968542" }, "DONATE_TEXT": { "description": "Your Donate Text as a string.", @@ -50,6 +50,26 @@ "API_HASH": { "description": "Get this value from https://my.telegram.org", "value": "" + }, + "DB_URL": { + "description": "Provided Mongodb Database link from mongodb.com", + "value": "" + }, + "DB_NAME": { + "description": "Provide name for DB to make session", + "value": "Feedback-Bot" + }, + "LOG_CHANNEL": { + "description": "Make a channel add the bot as admin and get the id of the channel using @googleimgbot", + "value": "" + }, + "BROADCAST_AS_COPY": { + "description": "If you provide value False then it will Forward with tag and if you give value as True then without tag", + "value": "True" + }, + "AUTH_USERS": { + "description": "Provide AUTH User ID to use admin function", + "value": "1428968542" } }, "addons": [ diff --git a/bot.py b/bot.py index c36515a..1913897 100644 --- a/bot.py +++ b/bot.py @@ -22,6 +22,7 @@ from pyrogram import Client, filters import logging + from configs import Config as C @@ -31,7 +32,20 @@ logging.getLogger("pyrogram").setLevel(logging.WARNING) # Import From Framework -from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton +# from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery + +from pyrogram.types import * + +from database.broadcast import broadcast +from database.verifier import handle_user_status +from database.database import Database + +LOG_CHANNEL = C.LOG_CHANNEL +AUTH_USERS = C.AUTH_USERS +DB_URL = C.DB_URL +DB_NAME = C.DB_NAME + +db = Database(DB_URL, DB_NAME) # Don't Change Anything, Except If You Want To Add Value bot = Client('Feedback bot', @@ -49,8 +63,66 @@ IF_CONTENT = "Message from: {} \nName: {}" -@bot.on_message(filters.command('start') & filters.private) +# Callback +@bot.on_callback_query() +async def callback_handlers(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + if "closeMeh" in cb.data: + await cb.message.delete(True) + elif "notifon" in cb.data: + notif = await db.get_notif(cb.from_user.id) + if notif is True: + # + await db.set_notif(user_id, notif=False) + else: + # + await db.set_notif(user_id, notif=True) + await cb.message.edit( + f"`Here You Can Set Your Settings:`\n\nSuccessfully setted notifications to **{await db.get_notif(user_id)}**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + f"NOTIFICATION {'šŸ””' if ((await db.get_notif(user_id)) is True) else 'šŸ”•'}", + callback_data="notifon", + ) + ], + [InlineKeyboardButton("CLOSE", callback_data="closeMeh")], + ] + ), + ) + await cb.answer( + f"Successfully setted notifications to {await db.get_notif(user_id)}" + ) + + +@bot.on_message((filters.private | filters.group)) +async def _(bot, cmd): + await handle_user_status(bot, cmd) + +@bot.on_message(filters.command('start') & (filters.private | filters.group)) async def start(bot, message): + chat_id = message.from_user.id + # Adding to DB + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) + return + + # + ban_status = await db.get_ban_status(chat_id) + is_banned = ban_status['is_banned'] + ban_duration = ban_status['ban_duration'] + ban_reason = ban_status['ban_reason'] + if is_banned is True: + await message.reply_text(f"You are Banned šŸš« to use this bot for **{ban_duration}** day(s) for the reason __{ban_reason}__ \n\n**Message from the admin šŸ¤ **") + return + await bot.send_message( chat_id=owner_id, text=LOG_TEXT.format(message.chat.id,message.chat.id,message.chat.first_name,message.chat.last_name,message.chat.dc_id), @@ -63,9 +135,26 @@ async def start(bot, message): ]) ) - -@bot.on_message(filters.command('help') & filters.private) +@bot.on_message(filters.command('help') & (filters.group | filters.private)) async def help(bot, message): + chat_id = message.from_user.id + # Adding to DB + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) + ban_status = await db.get_ban_status(chat_id) + is_banned = ban_status['is_banned'] + ban_duration = ban_status['ban_duration'] + ban_reason = ban_status['ban_reason'] + if is_banned is True: + await message.reply_text(f"You are Banned šŸš« to use this bot for **{ban_duration}** day(s) for the reason __{ban_reason}__ \n\n**Message from the admin šŸ¤ **") + return + await message.reply_text( text=C.HELP, reply_markup=InlineKeyboardMarkup([ @@ -74,8 +163,27 @@ async def help(bot, message): ) -@bot.on_message(filters.command('donate') & filters.private) +@bot.on_message(filters.command('donate') & (filters.group | filters.private)) async def donate(bot, message): + chat_id = message.from_user.id + # Adding to DB + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) + + ban_status = await db.get_ban_status(chat_id) + is_banned = ban_status['is_banned'] + ban_duration = ban_status['ban_duration'] + ban_reason = ban_status['ban_reason'] + if is_banned is True: + await message.reply_text(f"You are Banned šŸš« to use this bot for **{ban_duration}** day(s) for the reason __{ban_reason}__ \n\n**Message from the admin šŸ¤ **") + return + await message.reply_text( text=C.DONATE + "If You Liked This Bot You Can Also Donate Creator through BTC `3AKE4bNwb9TsgaofLQxHAGCR9w2ftwFs2R`", reply_markup=InlineKeyboardMarkup([ @@ -84,8 +192,181 @@ async def donate(bot, message): ) -@bot.on_message(filters.private & filters.text) + +@bot.on_message(filters.command("settings") & filters.private) +async def opensettings(bot, cmd): + user_id = cmd.from_user.id + # Adding to DB + if not await db.is_user_exist(user_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(user_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) + try: + await cmd.reply_text( + text=f"āš™ `Here You Can Set Your Settings:` āš™\n\nSuccessfully setted notifications to **{await db.get_notif(user_id)}**", + reply_markup=InlineKeyboardMarkup( + [ + [InlineKeyboardButton(text=f"NOTIFICATION {'šŸ””' if ((await db.get_notif(user_id)) is True) else 'šŸ”•'}",callback_data="notifon")], + [InlineKeyboardButton(text="CLOSE", callback_data="closeMeh")], + ] + ) + ) + except Exception as e: + await cmd.reply_text(e) + + +@bot.on_message(filters.private & filters.command("broadcast")) +async def broadcast_handler_open(_, m): + if m.from_user.id not in AUTH_USERS: + await m.delete() + return + if m.reply_to_message is None: + await m.delete() + return + await broadcast(m, db) + + +@bot.on_message((filters.group | filters.private) & filters.command("stats")) +async def sts(c, m): + if m.from_user.id not in AUTH_USERS: + await m.delete() + return + await m.reply_text( + text=f"**Total Users in Database šŸ“‚:** `{await db.total_users_count()}`\n\n**Total Users with Notification Enabled šŸ”” :** `{await db.total_notif_users_count()}`", + parse_mode="Markdown", + quote=True, + ) + + +@bot.on_message(filters.private & filters.command("ban_user")) +async def ban(c, m): + if m.from_user.id not in AUTH_USERS: + await m.delete() + return + if len(m.command) == 1: + await m.reply_text( + f"Use this command to ban šŸ›‘ any user from the bot šŸ¤–.\n\nUsage:\n\n`/ban_user user_id ban_duration ban_reason`\n\nEg: `/ban_user 1234567 28 You misused me.`\n This will ban user with id `1234567` for `28` days for the reason `You misused me`.", + quote=True, + ) + return + + try: + user_id = int(m.command[1]) + ban_duration = int(m.command[2]) + ban_reason = " ".join(m.command[3:]) + ban_log_text = f"Banning user {user_id} for {ban_duration} days for the reason {ban_reason}." + + if user_id == owner_id: + await message.reply_text("**You can Ban The Owner Vro") + return + try: + await c.send_message( + user_id, + f"You are Banned šŸš« to use this bot for **{ban_duration}** day(s) for the reason __{ban_reason}__ \n\n**Message from the admin šŸ¤ **", + ) + ban_log_text += "\n\nUser notified successfully!" + except BaseException: + traceback.print_exc() + ban_log_text += ( + f"\n\n āš ļø User notification failed! āš ļø \n\n`{traceback.format_exc()}`" + ) + await db.ban_user(user_id, ban_duration, ban_reason) + print(ban_log_text) + await m.reply_text(ban_log_text, quote=True) + except BaseException: + traceback.print_exc() + await m.reply_text( + f"Error occoured āš ļø! Traceback given below\n\n`{traceback.format_exc()}`", + quote=True, + ) + + +@bot.on_message((filters.group | filters.private) & filters.command("unban_user")) +async def unban(c, m): + if m.from_user.id not in AUTH_USERS: + await m.delete() + return + if len(m.command) == 1: + await m.reply_text( + f"Use this command to unban šŸ˜ƒ any user.\n\nUsage:\n\n`/unban_user user_id`\n\nEg: `/unban_user 1234567`\n This will unban user with id `1234567`.", + quote=True, + ) + return + + try: + user_id = int(m.command[1]) + unban_log_text = f"Unbanning user šŸ¤Ŗ {user_id}" + + try: + await c.send_message(user_id, f"Your ban was lifted!") + unban_log_text += "\n\nāœ… User notified successfully! āœ…" + except BaseException: + traceback.print_exc() + unban_log_text += ( + f"\n\nāš ļø User notification failed! āš ļø\n\n`{traceback.format_exc()}`" + ) + await db.remove_ban(user_id) + print(unban_log_text) + await m.reply_text(unban_log_text, quote=True) + except BaseException: + traceback.print_exc() + await m.reply_text( + f"āš ļø Error occoured āš ļø! Traceback given below\n\n`{traceback.format_exc()}`", + quote=True, + ) + + +@bot.on_message((filters.group | filters.private) & filters.command("banned_users")) +async def _banned_usrs(c, m): + if m.from_user.id not in AUTH_USERS: + await m.delete() + return + all_banned_users = await db.get_all_banned_users() + banned_usr_count = 0 + text = "" + async for banned_user in all_banned_users: + user_id = banned_user["id"] + ban_duration = banned_user["ban_status"]["ban_duration"] + banned_on = banned_user["ban_status"]["banned_on"] + ban_reason = banned_user["ban_status"]["ban_reason"] + banned_usr_count += 1 + text += f"> **User_id**: `{user_id}`, **Ban Duration**: `{ban_duration}`, **Banned on**: `{banned_on}`, **Reason**: `{ban_reason}`\n\n" + reply_text = f"Total banned user(s) šŸ¤­: `{banned_usr_count}`\n\n{text}" + if len(reply_text) > 4096: + with open("banned-users.txt", "w") as f: + f.write(reply_text) + await m.reply_document("banned-users.txt", True) + os.remove("banned-users.txt") + return + await m.reply_text(reply_text, True) + + return + + +@bot.on_message((filters.group | filters.private) & filters.text) async def pm_text(bot, message): + chat_id = message.from_user.id + # Adding to DB + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) + ban_status = await db.get_ban_status(chat_id) + is_banned = ban_status['is_banned'] + ban_duration = ban_status['ban_duration'] + ban_reason = ban_status['ban_reason'] + if is_banned is True: + await message.reply_text(f"You are Banned šŸš« to use this bot for **{ban_duration}** day(s) for the reason __{ban_reason}__ \n\n**Message from the admin šŸ¤ **") + return + if message.from_user.id == owner_id: await reply_text(bot, message) return @@ -98,8 +379,26 @@ async def pm_text(bot, message): ) -@bot.on_message(filters.private & filters.media) +@bot.on_message((filters.group | filters.private) & filters.media) async def pm_media(bot, message): + chat_id = message.from_user.id + # Adding to DB + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) + ban_status = await db.get_ban_status(chat_id) + is_banned = ban_status['is_banned'] + ban_duration = ban_status['ban_duration'] + ban_reason = ban_status['ban_reason'] + if is_banned is True: + await message.reply_text(f"You are Banned šŸš« to use this bot for **{ban_duration}** day(s) for the reason __{ban_reason}__ \n\n**Message from the admin šŸ¤ **") + return + if message.from_user.id == owner_id: await replay_media(bot, message) return @@ -116,6 +415,17 @@ async def pm_media(bot, message): @bot.on_message(filters.user(owner_id) & filters.text) async def reply_text(bot, message): + chat_id = message.from_user.id + # Adding to DB + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) + reference_id = True if message.reply_to_message is not None: file = message.reply_to_message @@ -128,13 +438,25 @@ async def reply_text(bot, message): except Exception: pass await bot.send_message( - text=message.text, - chat_id=int(reference_id) + chat_id=int(reference_id), + #from_chat_id=message.chat.id, + #message_id=message.message_id, + text=message.text ) @bot.on_message(filters.user(owner_id) & filters.media) async def replay_media(bot, message): + chat_id = message.from_user.id + # Adding to DB + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) started @{BOT_USERNAME} !!", + ) reference_id = True if message.reply_to_message is not None: file = message.reply_to_message diff --git a/configs.py b/configs.py index 0a75fbd..36e9b92 100644 --- a/configs.py +++ b/configs.py @@ -10,6 +10,8 @@ class Config(object): OWNER_ID = int(os.environ.get("OWNER_ID", 1428968542)) + AUTH_USERS = set(int(x) for x in os.environ.get("AUTH_USERS", "").split()) + START = str(os.environ.get("START_TEXT", "")) HELP = str(os.environ.get("HELP_TEXT", "")) @@ -22,3 +24,11 @@ class Config(object): SUPPORT_GROUP = str(os.environ.get("SUPPORT_GROUP", "")) + DB_URL = str(os.environ.get("DB_URL", "")) + + DB_NAME = str(os.environ.get("DB_NAME", "")) + + LOG_CHANNEL = int(os.environ.get("LOG_CHANNEL", "")) + + BROADCAST_AS_COPY = bool(os.environ.get("BROADCAST_AS_COPY", True)) + diff --git a/database/broadcast.py b/database/broadcast.py new file mode 100644 index 0000000..39e2543 --- /dev/null +++ b/database/broadcast.py @@ -0,0 +1,99 @@ +# (c) Abir Hasan & HeimanPictures + + +import asyncio +import datetime +import os +import random +import string +import time +import traceback + +import aiofiles +from pyrogram.errors import ( + FloodWait, + InputUserDeactivated, + PeerIdInvalid, + UserIsBlocked, +) + +from configs import Config + +broadcast_ids = {} + +BROADCAST_AS_COPY = Config.BROADCAST_AS_COPY + + +async def send_msg(user_id, message): + try: + if BROADCAST_AS_COPY is False: + await message.forward(chat_id=user_id) + elif BROADCAST_AS_COPY is True: + await message.copy(chat_id=user_id) + return 200, None + except FloodWait as e: + await asyncio.sleep(e.x) + return send_msg(user_id, message) + except InputUserDeactivated: + return 400, f"{user_id} : deactivated\n" + except UserIsBlocked: + return 400, f"{user_id} : blocked the bot\n" + except PeerIdInvalid: + return 400, f"{user_id} : user id invalid\n" + except Exception: + return 500, f"{user_id} : {traceback.format_exc()}\n" + + +async def broadcast(m, db): + all_users = await db.get_all_notif_user() + broadcast_msg = m.reply_to_message + while True: + broadcast_id = "".join([random.choice(string.ascii_letters) for i in range(3)]) + if not broadcast_ids.get(broadcast_id): + break + out = await m.reply_text( + text=f"Broadcast Started! You will be notified with log file when all the users are notified." + ) + start_time = time.time() + total_users = await db.total_users_count() + done = 0 + failed = 0 + success = 0 + broadcast_ids[broadcast_id] = dict( + total=total_users, current=done, failed=failed, success=success + ) + async with aiofiles.open("broadcast.txt", "w") as broadcast_log_file: + async for user in all_users: + sts, msg = await send_msg(user_id=int(user["id"]), message=broadcast_msg) + if msg is not None: + await broadcast_log_file.write(msg) + if sts == 200: + success += 1 + else: + failed += 1 + if sts == 400: + await db.delete_user(user["id"]) + done += 1 + if broadcast_ids.get(broadcast_id) is None: + break + else: + broadcast_ids[broadcast_id].update( + dict(current=done, failed=failed, success=success) + ) + if broadcast_ids.get(broadcast_id): + broadcast_ids.pop(broadcast_id) + completed_in = datetime.timedelta(seconds=int(time.time() - start_time)) + await asyncio.sleep(3) + await out.delete() + if failed == 0: + await m.reply_text( + text=f"broadcast completed in `{completed_in}`\n\nTotal users {total_users}.\nTotal done {done}, {success} success and {failed} failed.", + quote=True, + ) + else: + await m.reply_document( + document="broadcast.txt", + caption=f"broadcast completed in `{completed_in}`\n\nTotal users {total_users}.\nTotal done {done}, {success} success and {failed} failed.", + quote=True, + ) + os.remove("broadcast.txt") diff --git a/database/database.py b/database/database.py new file mode 100644 index 0000000..00ea54f --- /dev/null +++ b/database/database.py @@ -0,0 +1,92 @@ +# (c) Heiman Pictures + + +import datetime + +import motor.motor_asyncio + + +class Database: + def __init__(self, uri, database_name): + self._client = motor.motor_asyncio.AsyncIOMotorClient(uri) + self.db = self._client[database_name] + self.col = self.db.users + + def new_user(self, id): + return dict( + id=id, + join_date=datetime.date.today().isoformat(), + notif=True, + ban_status=dict( + is_banned=False, + ban_duration=0, + banned_on=datetime.date.max.isoformat(), + ban_reason="", + ), + ) + + async def add_user(self, id): + user = self.new_user(id) + await self.col.insert_one(user) + + async def is_user_exist(self, id): + user = await self.col.find_one({"id": int(id)}) + return True if user else False + + async def total_users_count(self): + count = await self.col.count_documents({}) + return count + + async def get_all_users(self): + all_users = self.col.find({}) + return all_users + + async def delete_user(self, user_id): + await self.col.delete_many({"id": int(user_id)}) + + async def remove_ban(self, id): + ban_status = dict( + is_banned=False, + ban_duration=0, + banned_on=datetime.date.max.isoformat(), + ban_reason="", + ) + await self.col.update_one({"id": id}, {"$set": {"ban_status": ban_status}}) + + async def ban_user(self, user_id, ban_duration, ban_reason): + ban_status = dict( + is_banned=True, + ban_duration=ban_duration, + banned_on=datetime.date.today().isoformat(), + ban_reason=ban_reason, + ) + await self.col.update_one({"id": user_id}, {"$set": {"ban_status": ban_status}}) + + async def get_ban_status(self, id): + default = dict( + is_banned=False, + ban_duration=0, + banned_on=datetime.date.max.isoformat(), + ban_reason="", + ) + user = await self.col.find_one({"id": int(id)}) + return user.get("ban_status", default) + + async def get_all_banned_users(self): + banned_users = self.col.find({"ban_status.is_banned": True}) + return banned_users + + async def set_notif(self, id, notif): + await self.col.update_one({"id": id}, {"$set": {"notif": notif}}) + + async def get_notif(self, id): + user = await self.col.find_one({"id": int(id)}) + return user.get("notif", False) + + async def get_all_notif_user(self): + notif_users = self.col.find({"notif": True}) + return notif_users + + async def total_notif_users_count(self): + count = await self.col.count_documents({"notif": True}) + return count diff --git a/database/verifier.py b/database/verifier.py new file mode 100644 index 0000000..9e75fb4 --- /dev/null +++ b/database/verifier.py @@ -0,0 +1,34 @@ + +import datetime + +from configs import Config +from database.database import Database + +DB_URL = Config.DB_URL +DB_NAME = Config.DB_NAME +LOG_CHANNEL = Config.LOG_CHANNEL + +db = Database(DB_URL, DB_NAME) + + +async def handle_user_status(bot, cmd): + chat_id = cmd.from_user.id + if not await db.is_user_exist(chat_id): + data = await bot.get_me() + BOT_USERNAME = data.username + await db.add_user(chat_id) + await bot.send_message( + LOG_CHANNEL, + f"#NEWUSER: \n\nNew User [{cmd.from_user.first_name}](tg://user?id={cmd.from_user.id}) started @{BOT_USERNAME} !!", + ) + + ban_status = await db.get_ban_status(chat_id) + if ban_status["is_banned"]: + if ( + datetime.date.today() - datetime.date.fromisoformat(ban_status["banned_on"]) + ).days > ban_status["ban_duration"]: + await db.remove_ban(chat_id) + else: + await cmd.reply_text("You are Banned to Use This Bot ", quote=True) + return + await cmd.continue_propagation() diff --git a/requirements.txt b/requirements.txt index a5c924d..d014823 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,5 @@ pyrogram -tgcrypto \ No newline at end of file +tgcrypto +aiofiles +motor +dnspython