├── LICENSE ├── Procfile ├── README.md ├── Script.py ├── app.py ├── bot.py ├── config.py ├── plugins ├── TechifyBots.txt ├── broadcast.py ├── callback.py ├── commands.py ├── db.py ├── fsub.py └── main.py ├── requirements.txt ├── run cmd.txt └── runtime.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Techify Bots 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: python3 bot.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
🩷 Thanks for Being Here 🩷
6 | 7 | 8 | 9 | ### 🥰 FEATURES 10 | 11 |ᴍᴀɪɴᴛᴀɪɴᴇᴅ ʙʏ : ʀᴀʜᴜʟ""" 11 | 12 | LOG = """#New_User 13 | 14 | User: {} 15 | ID: {}""" 16 | 17 | ABOUT = """📜 Cʜᴇᴄᴋ Aʙᴏᴜᴛ: 18 | 19 | Lɪʙʀᴀʀʏ: Pʏʀᴏɢʀᴀᴍ 📚 20 | Lᴀɴɢᴜᴀɢᴇ: Pʏᴛʜᴏɴ 🐍 21 | Sᴇʀᴠᴇʀ: Rᴇɴᴅᴇʀ 🌐 22 | Bᴜɪʟᴅ Sᴛᴀᴛᴜs: V1.3 🚀 23 | Sᴏᴜʀᴄᴇ Cᴏᴅᴇ: Aᴠᴀɪʟᴀʙʟᴇ (Fʀᴇᴇ) 💻 24 | 25 |
ᴍᴀɪɴᴛᴀɪɴᴇᴅ ʙʏ : ʀᴀʜᴜʟ""" 26 | 27 | HELP = """✨ --ᴜsᴇs ᴏꜰ ᴄᴏᴍᴍᴀɴᴅs-- 28 | 29 | • /ask - ɪꜰ ʏᴏᴜ ᴀʀᴇ ᴜsɪɴɢ ᴛʜɪs ʙᴏᴛ ɪɴ ɢʀᴏᴜᴘ ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴛᴏ ᴀsᴋ ᴀɴʏᴛʜɪɴɢ 30 | 31 | ᴇx: `/ask what is AI?` 32 | 33 | ɴᴏᴛᴇ : ɪɴ ᴘʀɪᴠᴀᴛᴇ ʏᴏᴜ ᴅᴏɴ'ᴛ ɴᴇᴇᴅ ᴛᴏ ᴜsᴇ ᴛʜɪs""" 34 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def hello_world(): 6 | return 'TechifyBots' 7 | 8 | 9 | if __name__ == "__main__": 10 | app.run() 11 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pyrogram import Client 3 | from aiohttp import web 4 | from config import API_ID, API_HASH, BOT_TOKEN 5 | 6 | r = web.RouteTableDef() 7 | 8 | @r.get("/", allow_head=True) 9 | async def root_route_handler(request): 10 | return web.Response(text='
{len(users_list)}
\n✅ Successful: {completed}
\n🤯 Failed: {failed}
",
74 | reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🎭 Close", callback_data="close")]])
75 | )
--------------------------------------------------------------------------------
/plugins/callback.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client
2 | from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
3 | from Script import text
4 |
5 | @Client.on_callback_query()
6 | async def callback_query_handler(client, query: CallbackQuery):
7 | if query.data == "start":
8 | await query.message.edit_text(
9 | text.START.format(query.from_user.mention),
10 | disable_web_page_preview=True,
11 | reply_markup=InlineKeyboardMarkup([
12 | [InlineKeyboardButton("ᴀʙᴏᴜᴛ", callback_data="about"),
13 | InlineKeyboardButton("ʜᴇʟᴘ", callback_data="help")],
14 | [InlineKeyboardButton("♻ ᴅᴇᴠᴇʟᴏᴘᴇʀ ♻", url="https://telegram.me/TechifyRahul")]
15 | ])
16 | )
17 |
18 | elif query.data == "help":
19 | await query.message.edit_text(
20 | text.HELP,
21 | disable_web_page_preview=True,
22 | reply_markup=InlineKeyboardMarkup([
23 | [InlineKeyboardButton("ᴜᴩᴅᴀᴛᴇꜱ", url="https://telegram.me/Techifybots"),
24 | InlineKeyboardButton("ꜱᴜᴩᴩᴏʀᴛ", url="https://telegram.me/TechifySupport")],
25 | [InlineKeyboardButton("ʙᴀᴄᴋ", callback_data="start"),
26 | InlineKeyboardButton("ᴄʟᴏꜱᴇ", callback_data="close")]
27 | ])
28 | )
29 |
30 | elif query.data == "about":
31 | await query.message.edit_text(
32 | text.ABOUT,
33 | disable_web_page_preview=True,
34 | reply_markup=InlineKeyboardMarkup([
35 | [InlineKeyboardButton("💥 ʀᴇᴘᴏ", url="https://github.com/TechifyBots/AI-Bot"),
36 | InlineKeyboardButton("👨💻 ᴏᴡɴᴇʀ", url="https://telegram.me/TechifyRahul")],
37 | [InlineKeyboardButton("ʙᴀᴄᴋ", callback_data="start"),
38 | InlineKeyboardButton("ᴄʟᴏꜱᴇ", callback_data="close")]
39 | ])
40 | )
41 |
42 | elif query.data == "close":
43 | await query.message.delete()
--------------------------------------------------------------------------------
/plugins/commands.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters
2 | from pyrogram.errors import *
3 | from pyrogram.types import Message, InlineKeyboardButton, InlineKeyboardMarkup
4 | from config import *
5 | import asyncio
6 | from Script import text
7 | from .db import tb
8 | from .fsub import get_fsub
9 |
10 | @Client.on_message(filters.command("start"))
11 | async def start_cmd(client, message):
12 | if await tb.get_user(message.from_user.id) is None:
13 | await tb.add_user(message.from_user.id, message.from_user.first_name)
14 | await client.send_message(
15 | LOG_CHANNEL,
16 | text.LOG.format(message.from_user.mention, message.from_user.id)
17 | )
18 | if IS_FSUB and not await get_fsub(client, message):return
19 | await message.reply_text(
20 | text.START.format(message.from_user.mention),
21 | reply_markup=InlineKeyboardMarkup([
22 | [InlineKeyboardButton('ᴀʙᴏᴜᴛ', callback_data='about'),
23 | InlineKeyboardButton('ʜᴇʟᴘ', callback_data='help')],
24 | [InlineKeyboardButton('♻ ᴅᴇᴠᴇʟᴏᴘᴇʀ ♻', url='https://telegram.me/TechifyRahul')]
25 | ]),
26 | disable_web_page_preview=True
27 | )
28 |
29 | @Client.on_message(filters.command("stats") & filters.private & filters.user(ADMIN))
30 | async def total_users(client, message):
31 | try:
32 | users = await tb.get_all_users()
33 | await message.reply(f"👥 **Total Users:** {len(users)}",reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🎭 Close", callback_data="close")]]))
34 | except Exception as e:
35 | r=await message.reply(f"❌ *Error:* `{str(e)}`")
36 | await asyncio.sleep(30)
37 | await r.delete()
--------------------------------------------------------------------------------
/plugins/db.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 | from config import DB_URI, DB_NAME
3 | from motor import motor_asyncio
4 |
5 | client: motor_asyncio.AsyncIOMotorClient[Any] = motor_asyncio.AsyncIOMotorClient(DB_URI)
6 | db = client[DB_NAME]
7 |
8 | class Techifybots:
9 | def __init__(self):
10 | self.users = db["users"]
11 | self.cache: dict[int, dict[str, Any]] = {}
12 |
13 | async def add_user(self, user_id: int, name: str) -> dict[str, Any] | None:
14 | try:
15 | user: dict[str, Any] = {"user_id": user_id, "name": name}
16 | await self.users.insert_one(user)
17 | self.cache[user_id] = user
18 | return user
19 | except Exception as e:
20 | print("Error in addUser: ", e)
21 |
22 | async def get_user(self, user_id: int) -> dict[str, Any] | None:
23 | try:
24 | if user_id in self.cache:
25 | return self.cache[user_id]
26 | user = await self.users.find_one({"user_id": user_id})
27 | return user
28 | except Exception as e:
29 | print("Error in getUser: ", e)
30 | return None
31 |
32 | async def get_all_users(self) -> list[dict[str, Any]]:
33 | try:
34 | users: list[dict[str, Any]] = []
35 | async for user in self.users.find():
36 | users.append(user)
37 | return users
38 | except Exception as e:
39 | print("Error in getAllUsers: ", e)
40 | return []
41 |
42 | async def delete_user(self, user_id: int) -> bool:
43 | try:
44 | result = await self.users.delete_one({"user_id": user_id})
45 | self.cache.pop(user_id, None)
46 | return result.deleted_count > 0
47 | except Exception as e:
48 | print("Error in delete_user: ", e)
49 | return False
50 |
51 | tb = Techifybots()
--------------------------------------------------------------------------------
/plugins/fsub.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
2 | from config import AUTH_CHANNELS
3 | from pyrogram import Client
4 | from pyrogram.types import Message
5 | from typing import List
6 | from pyrogram.errors import UserNotParticipant
7 |
8 | async def get_fsub(bot: Client, message: Message) -> bool:
9 | tb = await bot.get_me()
10 | user_id = message.from_user.id
11 | not_joined_channels = []
12 | for channel_id in AUTH_CHANNELS:
13 | try:
14 | await bot.get_chat_member(channel_id, user_id)
15 | except UserNotParticipant:
16 | chat = await bot.get_chat(channel_id)
17 | invite_link = chat.invite_link or await bot.export_chat_invite_link(channel_id)
18 | not_joined_channels.append((chat.title, invite_link))
19 | if not_joined_channels:
20 | join_buttons = []
21 | for i in range(0, len(not_joined_channels), 2):
22 | row = []
23 | for j in range(2):
24 | if i + j < len(not_joined_channels):
25 | title, link = not_joined_channels[i + j]
26 | button_text = f"{i + j + 1}. {title}"
27 | row.append(InlineKeyboardButton(button_text, url=link))
28 | join_buttons.append(row)
29 | join_buttons.append([InlineKeyboardButton("🔄 Try Again", url=f"https://telegram.me/{tb.username}?start=start")])
30 | await message.reply(f"**🎭 {message.from_user.mention}, As I see, you haven’t joined my channel yet.\nPlease join by clicking the button below.**", reply_markup=InlineKeyboardMarkup(join_buttons))
31 | return False
32 | return True
--------------------------------------------------------------------------------
/plugins/main.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters
2 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
3 | import requests
4 | from config import *
5 | import google.generativeai as genai
6 | import asyncio
7 |
8 | genai.configure(api_key=GOOGLE_API_KEY)
9 |
10 | responses_dict = {}
11 |
12 | @Client.on_message(filters.private & filters.command("ask"))
13 | async def askcmd(client, message):
14 | await message.reply_text(
15 | text="**You don't need to use this command here. Ask me directly.\n\nEx:** `Who Is Lord Shiva?`\n**Ok ?? Let's Try 😏**"
16 | )
17 |
18 | @Client.on_message(filters.command("ask") & filters.group)
19 | async def group_ai_reply(client, message):
20 | if len(message.command) == 1:
21 | return await message.reply_text(
22 | "⚠️ **Please provide a query after the command.**\n\nExample: `/ask What is AI?`",
23 | quote=True
24 | )
25 | await handle_gemini_mode(client, message)
26 |
27 | @Client.on_message(filters.private & filters.text & ~filters.command(["start", "ask"]))
28 | async def handle_ai_query(client, message):
29 | await handle_gemini_mode(client, message)
30 |
31 | async def handle_gemini_mode(client, message):
32 | user_input = message.text.strip()
33 | s = await message.reply_sticker("CAACAgQAAxkBAAIFqGc04PwJshM42NKq2lOFn-q5lQtqAAJuDwAC4eqxUNoxB5joJxGiHgQ")
34 |
35 | generation_config = {
36 | "temperature": 0.9,
37 | "top_p": 1,
38 | "top_k": 1,
39 | "max_output_tokens": 2048,
40 | }
41 |
42 | safety_settings = [
43 | {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
44 | {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
45 | {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
46 | {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
47 | ]
48 |
49 | model = genai.GenerativeModel(
50 | model_name="gemini-2.0-flash-lite",
51 | generation_config=generation_config,
52 | safety_settings=safety_settings
53 | )
54 |
55 | try:
56 | prompt_parts = [user_input]
57 | response = model.generate_content(prompt_parts)
58 |
59 | if hasattr(response, 'text') and response.text:
60 | await client.send_message(
61 | LOG_CHANNEL,
62 | text=f"👤 {message.from_user.mention} (`{message.from_user.id}`)\n\n"
63 | f"**Query:** `{user_input}`\n\n**AI Generated Response (Gemini):**\n{response.text}",
64 | reply_markup=InlineKeyboardMarkup(
65 | [[InlineKeyboardButton('Close', callback_data='close')]]
66 | )
67 | )
68 | ai_message = await message.reply_text(
69 | f"**{message.from_user.mention},** {response.text}",
70 | reply_markup=InlineKeyboardMarkup(
71 | [[InlineKeyboardButton("ʟᴇᴀʀɴ ᴄᴏᴅɪɴɢ 👨💻", url="https://techifybots.blogspot.com")]]
72 | )
73 | )
74 |
75 | # Delete the sticker immediately after the bot sends the message
76 | await s.delete()
77 |
78 | # Wait for 5 minutes before deleting both the user and bot messages
79 | await asyncio.sleep(300) # Sleep for 5 minutes (300 seconds)
80 | await message.delete() # Delete the user's message
81 | await ai_message.delete() # Delete the bot's reply
82 |
83 | else:
84 | await message.reply_text("⚠️ The AI model couldn't generate a response. Please try again.")
85 | except Exception as e:
86 | await message.reply_text("⚠️ An error occurred while processing your query. Please try again.")
87 | print(f"Error in Gemini Mode: {e}")
88 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pyrofork>=2.3.58
2 | tgcrypto
3 | motor
4 | requests
5 | google-generativeai
6 | aiohttp
7 |
8 | # For Web Deployable
9 | Flask==1.1.2
10 | gunicorn==20.1.0
11 | Jinja2==3.0.3
12 | werkzeug==2.0.2
13 | itsdangerous==2.0.1
14 |
--------------------------------------------------------------------------------
/run cmd.txt:
--------------------------------------------------------------------------------
1 | gunicorn app:app & python3 bot.py
2 |
--------------------------------------------------------------------------------
/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.13.1
--------------------------------------------------------------------------------