├── .example.env
├── .gitignore
├── LICENSE
├── Procfile
├── app.json
├── app.py
├── bot.py
├── info.py
├── plugins
├── ai_chat.py
├── db.py
├── fsub.py
└── utils.py
├── readme.md
├── requirements.txt
└── run cmd.txt
/.example.env:
--------------------------------------------------------------------------------
1 | API_ID=11366789
2 | API_HASH=46fbdc6hihihihi8899b951
3 | BOT_TOKEN=6806603957:AAE1hughhkjhgydFmzjF8QeVP3Sv8mO0w
4 | ADMIN=539767467
5 | CHAT_GROUP=-10017989747469
6 | LOG_CHANNEL=-1008777665444
7 | MONGO_URL=mongodb://localhost:27017/
8 |
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 | .plugins\__pycache__
3 | plugins\__pycache__
4 | plugins\*.pyc
5 | plugins\*.pyo
6 | .venv
7 | venv
8 | .__pycache__
9 | test.py
10 | .vscode
11 | plugins/__pycache__/ai_chat.cpython-312.pyc
12 | plugins/__pycache__/db.cpython-312.pyc
13 | plugins/__pycache__/fsub.cpython-312.pyc
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Biisal
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: python bot.py
2 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "biisal",
3 | "description": "A Pyrogram Telegram Ai-Chat-bot,api not required to use 😎. @biisal",
4 | "keywords": [
5 | "telegram",
6 | "pyrogram",
7 | "python",
8 | "plugin",
9 | "modular",
10 | "media",
11 | "bot"
12 | ],
13 | "repository": "https://github.com/biisal/biisal-gpt-bot/",
14 | "success_url": "/",
15 | "logo": "https://i.postimg.cc/cJk8XMMc/photo-6120885699327671985-c.jpg",
16 | "website": "https://bit.ly/bisal",
17 | "env": {
18 | "API_ID": {
19 | "description": "Get this value from https://my.telegram.org"
20 | },
21 | "API_HASH": {
22 | "description": "Get this value from https://my.telegram.org"
23 | },
24 | "BOT_TOKEN": {
25 | "description": "Get this value from @BotFather"
26 | },
27 | "LOG_CHANNEL": {
28 | "description": "The LOG Channel ID. To get new users log"
29 | },
30 | "MONGO_URL": {
31 | "description": "MongoDB URI for saving User IDs when they first Start the Bot. We will use that for Broadcasting to them. I will try to add more features related with Database."
32 | },
33 | "BOT_NAME": {
34 | "description": "Give your Ai a cool name"
35 | },
36 | "CHAT_GROUP": {
37 | "description": "Give your GROUP ID.Bot will be able to talk in that group using /bol command"
38 | },
39 | "ADMIN": {
40 | "description": "Give your User ID."
41 | },
42 | "ADMIN_NAME": {
43 | "description": "Give your Name Here."
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from flask import Flask
2 |
3 | app = Flask(__name__)
4 |
5 |
6 | @app.route("/")
7 | def hello_world():
8 | return "Jai Shree Krishna !"
9 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | # ©️biisal jai shree krishna 😎
2 | from pyrogram.client import Client
3 | from info import *
4 |
5 |
6 | class Bot(Client):
7 | def __init__(self):
8 | super().__init__( # type:ignore
9 | name="Bisal Gptt",
10 | api_id=API_ID,
11 | api_hash=API_HASH,
12 | bot_token=BOT_TOKEN,
13 | workers=200,
14 | plugins={"root": "plugins"},
15 | sleep_threshold=15,
16 | )
17 |
18 | async def start(self): # type:ignore
19 | await super().start()
20 | me = await self.get_me()
21 | print(f"{me.first_name} Iꜱ Sᴛᴀʀᴛᴇᴅ.....✨️")
22 | await self.send_message(ADMIN, f"**__{me.first_name} Iꜱ Sᴛᴀʀᴛᴇᴅ.....✨️__**")
23 | async def stop(self, *args): # type:ignore
24 | await super().stop()
25 | print("Bᴏᴛ Iꜱ Sᴛᴏᴘᴘᴇᴅ....")
26 |
27 | Bot().run() # type:ignore
28 |
--------------------------------------------------------------------------------
/info.py:
--------------------------------------------------------------------------------
1 | # ©️biisal jai shree krishna 😎
2 | from os import environ
3 | from dotenv import load_dotenv
4 |
5 | load_dotenv()
6 |
7 | API_ID = environ.get("API_ID" , "2099007")
8 | API_HASH = environ.get("API_HASH" , "b1b3d7b3b1b3d7b3b1b3d7b3b1b3d7b3")
9 | BOT_TOKEN = environ.get("BOT_TOKEN" , "2099007:AAH1b3d7b3b1b3d7b3b1b3d7b3b1b3d7b3")
10 | ADMIN = int(environ.get("ADMIN" , "1847899007"))
11 | CHAT_GROUP = int(environ.get("CHAT_GROUP", "-100"))
12 | LOG_CHANNEL = environ.get("LOG_CHANNEL", "-100")
13 | MONGO_URL = environ.get("MONGO_URL" , "mongodb://localhost:27017")
14 | AUTH_CHANNEL = int(
15 | environ.get("AUTH_CHANNEL", "-1001734958816")
16 | )
17 | FSUB = environ.get("FSUB", True)
18 | STICKERS_IDS = (
19 | "CAACAgQAAxkBAAEK99dlfC7LDqnuwtGRkIoacot_dGC4zQACbg8AAuHqsVDaMQeY6CcRojME"
20 | ).split()
21 | COOL_TIMER = 20 # keep this atleast 20
22 | ONLY_SCAN_IN_GRP = environ.get(
23 | "ONLY_SCAN_IN_GRP", True
24 | ) # If IMG_SCAN_IN_GRP is set to True, image scanning is restricted to your support group only. If it's False, the image scanning feature can be used anywhere.
25 | REACTIONS = ["❤️🔥", "⚡", "🔥"]
26 |
--------------------------------------------------------------------------------
/plugins/ai_chat.py:
--------------------------------------------------------------------------------
1 | # ©️biisal jai shree krishna 😎
2 | import asyncio
3 | import random
4 | from pyrogram import filters
5 | from pyrogram.client import Client
6 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
7 | from pyrogram.errors import FloodWait
8 | from info import *
9 | from plugins.utils import create_image, get_ai_response
10 | from .db import *
11 | from .fsub import get_fsub
12 |
13 |
14 | @Client.on_message(filters.command("start") & filters.incoming) # type:ignore
15 | async def startcmd(client: Client, message: Message):
16 | userMention = message.from_user.mention()
17 | if await users.get_user(message.from_user.id) is None:
18 | await users.addUser(message.from_user.id, message.from_user.first_name)
19 | await client.send_message(
20 | LOG_CHANNEL,
21 | text=f"#New_user_started\n\nUser: {message.from_user.mention()}\nid :{message.from_user.id}",
22 | )
23 | if FSUB and not await get_fsub(client, message):return
24 | await message.reply_photo(# type:ignore
25 | photo="https://telegra.ph/file/595e38a4d76848c01b110.jpg",
26 | caption=f"Jai Shree Krishna {userMention},\n\nIᴍ Hᴇʀᴇ Tᴏ Rᴇᴅᴜᴄᴇ Yᴏᴜʀ Pʀᴏʙʟᴇᴍs..\nYᴏᴜ Cᴀɴ Usᴇ Mᴇ As ʏᴏᴜʀ Pʀɪᴠᴀᴛᴇ Assɪsᴛᴀɴᴛ..\nAsᴋ Mᴇ Aɴʏᴛʜɪɴɢ...Dɪʀᴇᴄᴛʟʏ..\n\nMʏ Cʀᴇᴀᴛᴏʀ : Bɪɪsᴀʟ\nMʏ Lᴏᴠᴇʀ : Tʜɪs Pᴇʀsᴏɴ",
27 | )
28 | return
29 |
30 |
31 | @Client.on_message(filters.command("broadcast") & (filters.private) & filters.user(ADMIN)) # type:ignore
32 | async def broadcasting_func(client : Client, message: Message):
33 | msg = await message.reply_text("Wait a second!") # type:ignore
34 | if not message.reply_to_message:
35 | return await msg.edit("Please reply to a message to broadcast.")
36 | await msg.edit("Processing ...")
37 | completed = 0
38 | failed = 0
39 | to_copy_msg = message.reply_to_message
40 | users_list = await users.get_all_users()
41 | for i , userDoc in enumerate(users_list):
42 | if i % 20 == 0:
43 | await msg.edit(f"Total : {i} \nCompleted : {completed} \nFailed : {failed}")
44 | user_id = userDoc.get("user_id")
45 | if not user_id:
46 | continue
47 | try:
48 | await to_copy_msg.copy(user_id , reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🎭 ᴀᴅᴍɪɴ sᴜᴘᴘᴏʀᴛ 🎗️", url='https://t.me/bisal_files_talk')]]))
49 | completed += 1
50 | except FloodWait as e:
51 | if isinstance(e.value , int | float):
52 | await asyncio.sleep(e.value)
53 | await to_copy_msg.copy(user_id , reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🎭 ᴀᴅᴍɪɴ sᴜᴘᴘᴏʀᴛ 🎗️", url='https://t.me/bisal_files_talk')]]))
54 | completed += 1
55 | except Exception as e:
56 | print("Error in broadcasting:", e)
57 | failed += 1
58 | pass
59 | await msg.edit(f"Successfully Broadcasted\nTotal : {len(users_list)} \nCompleted : {completed} \nFailed : {failed}")
60 |
61 |
62 | @Client.on_message(filters.command("ai") & filters.chat(CHAT_GROUP)) # type:ignore
63 | async def grp_ai(client: Client, message: Message):
64 | query : str | None = (
65 | message.text.split(" ", 1)[1] if len(message.text.split(" ", 1)) > 1 else None
66 | )
67 | if not query:
68 | return await message.reply_text( # type:ignore
69 | "Abe gadhe /ai k baad kuch likh to le !!.\n\nExample Use:\n/ai Who is lord krshna??
\n\nHope you got it.Try it now.."
70 | )
71 | if FSUB and not await get_fsub(client, message):return
72 | message.text = query # type:ignore
73 | return await ai_res(client, message)
74 |
75 |
76 | @Client.on_message(filters.command("reset") & filters.private) # type:ignore
77 | async def reset(client: Client, message: Message):
78 | try:
79 | await users.get_or_add_user(message.from_user.id, message.from_user.first_name)
80 | if FSUB and not await get_fsub(client, message):return
81 | is_reset = await chat_history.reset_history(message.from_user.id)
82 | if not is_reset:
83 | return await message.reply_text("Unable to reset chat history.") # type:ignore
84 | await message.reply_text("Chat history has been reset.") # type:ignore
85 | except Exception as e:
86 | print("Error in reset: ", e)
87 | return await message.reply_text("Sorry, Failed to reset chat history.") # type:ignore
88 |
89 |
90 | @Client.on_message(filters.command("gen") & filters.private) # type:ignore
91 | async def gen_image(client: Client, message: Message):
92 | """
93 | Handles private messages with the /gen command and generates an image based on the provided prompt.
94 |
95 | Args:
96 | client (Client): The Client object.
97 | message (Message): The Message object.
98 |
99 | Returns:
100 | None
101 | """
102 | sticker = None
103 | try:
104 | await users.get_or_add_user(message.from_user.id, message.from_user.first_name)
105 | if FSUB and not await get_fsub(client, message):return
106 | sticker = await message.reply_sticker(random.choice(STICKERS_IDS)) # type:ignore
107 | prompt = message.text.replace("/gen", "").strip()
108 | encoded_prompt = prompt.replace("\n", " ")
109 | if not prompt:
110 | return await message.reply_text("Please provide a prompt.") # type:ignore
111 | image_file = await create_image(encoded_prompt)
112 | if not image_file:
113 | return await message.reply_text("Failed to generate image.") # type:ignore
114 | await message.reply_photo(photo=image_file , caption=f"Generated Image for prompt: {prompt[:150]}...") # type:ignore
115 | image_file.close()
116 | except Exception as e:
117 | print("Error in gen_image: ", e)
118 | return await message.reply_text("Sorry, I am not Available right now.") # type:ignore
119 | finally:
120 | if sticker:await sticker.delete()
121 |
122 | @Client.on_message(filters.text & filters.incoming & filters.private) # type:ignore
123 | async def ai_res(client: Client, message: Message ):
124 | """
125 | Handles private text messages and sends AI responses back.
126 | """
127 | sticker = None
128 | reply = None
129 | try:
130 | await users.get_or_add_user(message.from_user.id, message.from_user.first_name)
131 | if FSUB and not await get_fsub(client, message):return
132 | sticker = await message.reply_sticker(random.choice(STICKERS_IDS)) # type:ignore
133 | text = message.text
134 | if text.startswith('/'):
135 | return
136 | user_id = message.from_user.id
137 | history = await chat_history.get_history(user_id)
138 | history.append({"role": "user", "content": text})
139 | reply = await get_ai_response(history)
140 | history.append({"role": "assistant", "content": reply})
141 | await message.reply_text(reply) # type:ignore
142 | await chat_history.add_history(user_id, history)
143 | except Exception as e:
144 | print("Error in ai_res: ", e)
145 | reply = "Sorry, I am not available right now."
146 | await message.reply_text(reply) # type:ignore
147 | finally:
148 | if sticker:
149 | await sticker.delete()
--------------------------------------------------------------------------------
/plugins/db.py:
--------------------------------------------------------------------------------
1 | # ©️biisal jai shree krishna 😎
2 | from typing import Any
3 | from info import *
4 | from motor import motor_asyncio
5 | client: motor_asyncio.AsyncIOMotorClient[Any] = motor_asyncio.AsyncIOMotorClient(MONGO_URL)
6 | db = client["biisal"]
7 |
8 |
9 | class User:
10 | def __init__(self):
11 | """
12 | Initialize the User class.
13 |
14 | This class stores and retrieves user data from the database. The
15 | `users` attribute is a MotorCollection instance, which is the
16 | interface to the MongoDB collection. The `cache` attribute is a
17 | dictionary that stores user data in memory. This cache is updated
18 | whenever the user data is retrieved from the database.
19 |
20 | The cache is used to speed up the process of retrieving user data.
21 | """
22 | self.users = db["users"]
23 | self.cache : dict[int, dict[str, Any]] = {}
24 |
25 | async def addUser(self, user_id: int, name: str) -> dict[str, Any] | None:
26 | """
27 | Add a user to the database.
28 |
29 | Args:
30 | user_id (int): The unique identifier for the user.
31 | name (str): The name of the user.
32 |
33 | Returns:
34 | dict[str, Any] | None: A dictionary representing the user if added successfully, otherwise None.
35 | """
36 | try:
37 | user: dict[str, Any] = {"user_id": user_id, "name": name}
38 | await self.users.insert_one(user)
39 | self.cache[user_id] = user
40 | return user
41 | except Exception as e:
42 | print("Error in addUser: ", e)
43 |
44 |
45 | async def get_user(self, user_id: int) -> dict[str, Any] | None:
46 | """
47 | Retrieves a user from the database.
48 |
49 | Args:
50 | user_id (int): The unique identifier for the user.
51 |
52 | Returns:
53 | dict[str, Any] | None: A dictionary representing the user if found, otherwise None.
54 | """
55 | try:
56 | if user_id in self.cache:
57 | return self.cache[user_id]
58 | user = await self.users.find_one({"user_id": user_id})
59 | return user
60 | except Exception as e:
61 | print("Error in getUser: ", e)
62 | return None
63 |
64 | async def remove_user(self, user_id: int) -> bool:
65 |
66 | """
67 | Removes a user from the database.
68 |
69 | Args:
70 | user_id (int): The unique identifier for the user.
71 |
72 | Returns:
73 | bool: True if the user was removed successfully, False otherwise.
74 | """
75 | try:
76 | await self.users.delete_one({"user_id": user_id})
77 | del self.cache[user_id]
78 | return True
79 | except Exception as e:
80 | print("Error in removeUser: ", e)
81 | return False
82 | async def get_or_add_user(self, user_id: int, name: str) -> dict[str ,str] | None:
83 | """
84 | Retrieves a user from the database or adds the user if they do not exist.
85 |
86 | Args:
87 | user_id (int): The unique identifier for the user.
88 | name (str): The name of the user.
89 |
90 | Returns:
91 | dict[str, str] | None: A dictionary representing the user if found or added successfully, otherwise None.
92 | """
93 | user : dict[str ,str] | None = await self.get_user(user_id)
94 | if user is None :
95 | user = await self.addUser(user_id, name)
96 | return user
97 |
98 | async def get_all_users(self) -> list[dict[str, Any]]:
99 | """
100 | Retrieves a list of all users stored in the database.
101 |
102 | Returns:
103 | list[dict[str, Any]]: A list of dictionaries representing all users in the database.
104 | """
105 | try:
106 | users : list[dict[str, Any]] = []
107 | async for user in self.users.find():
108 | users.append(user)
109 | return users
110 | except Exception as e:
111 | print("Error in getAllUsers: ", e)
112 | return []
113 |
114 |
115 | class ChatHistory:
116 | def __init__(self):
117 | self.history = db["history"]
118 |
119 | async def add_history(self, user_id: int, history: list[dict[str, str]]) -> bool:
120 | """
121 | Add a user's chat history to the database.
122 |
123 | Args:
124 | user_id (int): The Telegram User ID.
125 | history (list[dict[str, str]]): A list of dictionaries with 'role' and 'content' keys
126 | representing the conversation history.
127 |
128 | Returns:
129 | bool: True if successful, False otherwise.
130 | """
131 | try:
132 | recent_history = history[-50:] # increesing this will create a api error
133 | query = {"user_id": user_id}
134 | update = {"$set": {"history": recent_history}}
135 | await self.history.update_one(query, update, upsert=True)
136 | return True
137 | except Exception as e:
138 | print("Error in addHistory: ", e)
139 | return False
140 |
141 |
142 | async def get_history(self, user_id: int) -> list[dict[str, str]]:
143 | """
144 | Retrieve the chat history for a specific user.
145 |
146 | Args:
147 | user_id (int): The unique identifier of the user.
148 |
149 | Returns:
150 | list[dict[str, str]]: A list of dictionaries representing the user's chat history.
151 | Each dictionary contains 'role' and 'content' keys. Returns an empty list if no history is found or an error occurs.
152 | """
153 |
154 | try:
155 | history : dict[str , Any] | None = await self.history.find_one({"user_id": user_id})
156 | return history["history"] if history else []
157 | except Exception as e:
158 | print("Error in getHistory: ", e)
159 | return []
160 |
161 | async def reset_history(self, user_id: int) -> bool:
162 | """
163 | Deletes all chat history of a user.
164 |
165 | Args:
166 | user_id (int): The Telegram User ID.
167 |
168 | Returns:
169 | bool: True if successful, False otherwise.
170 | """
171 | try:
172 | await self.history.delete_one({"user_id": user_id})
173 | return True
174 | except Exception as e:
175 | print("Error in clearHistory: ", e)
176 | return False
177 |
178 |
179 | chat_history = ChatHistory()
180 | users = User()
181 |
--------------------------------------------------------------------------------
/plugins/fsub.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | from pyrogram.errors import UserNotParticipant
3 | from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton , InlineKeyboardButtonBuy
4 | from pyrogram.types import Message
5 | from pyrogram.client import Client
6 | from info import *
7 |
8 |
9 | async def get_fsub(bot : Client, message: Message ) -> bool:
10 | """
11 | Checks if the user is a subscriber of the channel and if not asks him to join the channel.
12 |
13 | Parameters:
14 | bot (Client): The client instance.
15 | message (Message): The message that triggered the function.
16 |
17 | Returns:
18 | bool: True if the user is a subscriber, False otherwise.
19 | """
20 | target_channel_id = AUTH_CHANNEL # Your channel ID
21 | user_id = message.from_user.id
22 | try:
23 | await bot.get_chat_member(target_channel_id, user_id)
24 | except UserNotParticipant:
25 | channel_link :str = (await bot.get_chat(target_channel_id)).invite_link #type: ignore
26 | join_button = InlineKeyboardButton("Join Channel", url=channel_link) # type:ignore
27 | keyboard : List[List[InlineKeyboardButton | InlineKeyboardButtonBuy]] = [[join_button]]
28 | await message.reply( # type:ignore
29 | f"Dᴇᴀʀ Usᴇʀ {message.from_user.mention}!\n\nPʟᴇᴀsᴇ ᴊᴏɪɴ ᴏᴜʀ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ᴛᴏ ᴜsᴇ ᴍᴇ ! 😊\n\nDᴜᴇ ᴛᴏ sᴇʀᴠᴇʀ ᴏᴠᴇʀʟᴏᴀᴅ, ᴏɴʟʏ ᴏᴜʀ ᴄʜᴀɴɴᴇʟ sᴜʙsᴄʀɪʙᴇʀs ᴄᴀɴ ᴜsᴇ ᴛʜɪs ʙᴏᴛ !",
30 | reply_markup=InlineKeyboardMarkup(keyboard),
31 | )
32 | return False
33 | return True
34 |
--------------------------------------------------------------------------------
/plugins/utils.py:
--------------------------------------------------------------------------------
1 | import base64
2 | from io import BytesIO
3 | import httpx
4 |
5 | cl = httpx.AsyncClient(base_url='https://api.codeltix.com' , follow_redirects=True , timeout=20)
6 | async def get_ai_response(history: list[dict[str, str]]) -> str:
7 | """
8 | Get the AI response for the given history of messages.
9 |
10 | Args:
11 | history: A list of dictionaries with 'role' and 'content' keys
12 | representing the conversation history.
13 |
14 | Returns:
15 | The AI response as a string.
16 |
17 | Raises:
18 | httpx.HTTPStatusError: If the server returns an unsuccessful status code.
19 | httpx.RequestError: If a network error occurs.
20 | Exception: If any other unexpected error occurs.
21 | """
22 | try:
23 | response = await cl.post('/ai', json={'history': history})
24 | response.raise_for_status()
25 | reply = response.json().get("message", "No response text found")
26 | source = response.json().get("source", None)
27 | source_title = response.json().get("source_title", None)
28 | if source and source_title:
29 | reply += f"\n\nSource: {source_title}"
30 | return reply
31 | except httpx.HTTPStatusError as exc:
32 | print(f'HTTP error occurred: {exc}')
33 | except httpx.RequestError as exc:
34 | print(f'Request error occurred: {exc}')
35 | except Exception as exc:
36 | print(f'An unexpected error occurred: {exc}')
37 | return 'I\'m sorry, I\'m not able to respond to that right now.'
38 | async def create_image(encoded_prompt: str) -> BytesIO | None:
39 | """
40 | Get an image representation for the given prompt.
41 |
42 | Args:
43 | encoded_prompt: A URL-encoded string representing the prompt.
44 |
45 | Returns:
46 | A BytesIO object containing the image data if successful, otherwise None.
47 |
48 | Raises:
49 | httpx.HTTPStatusError: If the server returns an unsuccessful status code.
50 | httpx.RequestError: If a network error occurs.
51 | Exception: If any other unexpected error occurs.
52 | """
53 | try:
54 | response = await cl.get(f"/ai/image/?prompt={encoded_prompt}")
55 | response.raise_for_status()
56 | base64_image = response.json()["image"]
57 | image_data = base64.b64decode(base64_image)
58 | image_file = BytesIO(image_data)
59 | return image_file
60 | except httpx.HTTPStatusError as exc:
61 | print(f'HTTP error occurred: {exc}')
62 | except httpx.RequestError as exc:
63 | print(f'Request error occurred: {exc}')
64 | except Exception as exc:
65 | print(f'An unexpected error occurred: {exc}')
66 | return None
67 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # ChatGPT Telegram Bot
2 |
3 | Welcome to the **ChatGPT Bot** repository! This bot allows users to chat with an AI directly in Telegram. Whether you're in a private chat or a group, the bot provides seamless interactions powered by the latest AI models.
4 |
5 |
6 | Best thing is you don't need any API key to create this bot.
7 |
8 | ## Features
9 |
10 | - **Live Search**: Users can perform live searches directly through the bot and get summerized results.
11 |
12 | - **Private Chat**: Users can chat with the bot directly without using any commands. The bot stores up to the last 50 messages in the conversation, allowing for continuous, context-aware responses.
13 |
14 | - **Fast Responses**: The bot is optimized for speed, offering the most efficient and fast replies.
15 |
16 | - **Fully Asynchronous**: No blocking or delays. Everything runs smoothly and asynchronously for a fluid experience.
17 |
18 | - **Image Generation**: Using the `/gen` command, users can generate high-quality images with AI.
19 |
20 | - **Group Chat Support**: In group chats, you can interact with the bot using the `/ai` command.
21 |
22 | - **Reset Chat History**: Users can reset their chat history using the `/reset` command.
23 |
24 | - **Database Integration**: All chats and user details are stored in a database for easy management and reference.
25 |
26 | - **Broadcast Command**: Admins can use the broadcast command to send messages to all users at once.
27 |
28 | ## AI Model Credits
29 |
30 | - **Mistral**
31 | - **Llama**
32 | - **Stable Diffusion**
33 |
34 | These powerful AI models provide high-quality responses and image generation capabilities.
35 |
36 | ## Dependencies
37 |
38 | This bot uses **Pyrogram** library for Telegram interactions,**Motor** for async database operations and
39 | runs on **Python 3.12+** for optimal performance.
40 |
41 | ### Installation
42 |
43 | To set up the bot on your local machine, follow these steps:
44 |
45 | 1. Clone the repository:
46 |
47 | ```bash
48 | git clone https://github.com/biisal/chatgpt-bot.git
49 | cd chatgpt-bot
50 | ```
51 |
52 | 2. Install the required dependencies:
53 |
54 | ```bash
55 | pip install -r requirements.txt
56 | ```
57 |
58 | 3. Create a `.env` file in the root directory with your bot token and other configuration details:
59 |
60 | ```bash
61 | API_ID=your-telegram-api-id
62 | API_HASH=your-telegram-api-hash
63 | BOT_TOKEN=your-telegram-bot-token
64 | ADMIN=your-telegram-user-id
65 | CHAT_GROUP=your-telegram-group-id
66 | LOG_CHANNEL=your-telegram-channel-id-for-logs
67 | MONGO_URL=your-mongodb-connection-string
68 | ```
69 |
70 | 4. Run the bot:
71 |
72 | ```bash
73 | python bot.py
74 | ```
75 | - For mac or linux users use ->
76 | `python3 bot.py`
77 |
78 | ### Deploying this bot Repository in Koyeb or Render -
79 | #### Deploying this bot in Render is Almost same as deploying it in Koyeb. You Just need to Follow the Steps.
80 |
81 | - Fork the repo and import it in Koyeb or Render by choosing web services.
82 | - Choose python if any server asks for it.
83 | - For Koyeb, in the builder section, choose the buildpack option.
84 | - For Render, use this as build command: `pip install -r requirements.txt`
85 | - For Koyeb, you don't need to add any build command.
86 | - For run or start command, use this command: `gunicorn app:app & python3 bot.py`
87 | - Add all env variables in environment variables section.
88 |
89 |
90 | ### Commands
91 |
92 | - `/gen [prompt]`: Generate high-quality images using AI.
93 | - `/ai [text]`: Use this command in group chats to interact with the bot.
94 | - `/broadcast`: Admins can broadcast a message to all users.
95 | - `/reset`: Reset the chat history.
96 |
97 | ## Contribution
98 |
99 | Feel free to fork the repository and contribute by creating pull requests. If you find any issues or have suggestions for improvements, please open an issue.
100 |
101 | ## License
102 |
103 | This project is licensed under the MIT License.
104 |
105 | ---
106 |
107 | Enjoy chatting with the AI!
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/biisal/chatgpt-bot/a4e8ffe540e717873cf939ac3734c6abeb9e0985/requirements.txt
--------------------------------------------------------------------------------
/run cmd.txt:
--------------------------------------------------------------------------------
1 | gunicorn app:app & python bot.py
--------------------------------------------------------------------------------