From b16ed918223718376cdbbde6a5181d7ec0606c78 Mon Sep 17 00:00:00 2001 From: Hosein Date: Fri, 26 Dec 2025 11:17:52 +0330 Subject: [PATCH] added database connection --- bot.py | 34 +++++++++++++++++++++++++++---- database/connection.py | 46 ++++++++++++++++++++++++++++++++++++++++++ database/models.py | 26 ++++++++++++++++++++++++ dev.py | 27 +++++++++++++++++++++++++ devrequirements.txt | 6 ++++++ main.py | 30 --------------------------- setting-webhook.txt | 5 +++++ 7 files changed, 140 insertions(+), 34 deletions(-) create mode 100644 database/connection.py create mode 100644 database/models.py create mode 100644 dev.py create mode 100644 devrequirements.txt create mode 100644 setting-webhook.txt diff --git a/bot.py b/bot.py index 8a2de16..7bc0f9b 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,9 @@ import os +import logging +from database.models import testModel +from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton + +logger = logging.getLogger(__name__) _bot = None @@ -7,14 +12,35 @@ def get_bot(): if _bot is None: import telebot BOT_TOKEN = os.environ.get("BOT_TOKEN") - _bot = telebot.TeleBot(BOT_TOKEN, threaded=False) # threaded=False for serverless + _bot = telebot.TeleBot(BOT_TOKEN, threaded=False) - # Register handlers @_bot.message_handler(commands=["start"]) def start(message): - _bot.reply_to(message, "Welcome!") + _bot.reply_to(message, "Welcome! Use /getdata to fetch from database.") + + @_bot.message_handler(commands=["getdata"]) + def get_data(message): + try: + data = testModel.getAllUsers() + if data: + _bot.reply_to(message, f"Data: {data}") + + response = ""; + for i in range(3): + response += "\n"; + response += f""" + 📚 {data[i][0]} + نویسنده: {data[i][1]} + موجودی: {data[i][3]}/{data[i][8]} + کد: {data[i][1]} + """ + _bot.reply_to(message, response, parse_mode='HTML') + else: + _bot.reply_to(message, "No data found or database error.") + except Exception as e: + logger.error(f"Error in getdata handler: {e}") + _bot.reply_to(message, "Sorry, an error occurred.") - # Add a handler for all other messages @_bot.message_handler(func=lambda message: True) def echo_all(message): _bot.reply_to(message, f"You said: {message.text}") diff --git a/database/connection.py b/database/connection.py new file mode 100644 index 0000000..4a0fbdf --- /dev/null +++ b/database/connection.py @@ -0,0 +1,46 @@ +import os +import logging +import psycopg2 +from psycopg2 import pool + +logger = logging.getLogger(__name__) + +# Connection pool for reusing connections (important for serverless!) +_connection_pool = None + +def get_connection_pool(): + global _connection_pool + if _connection_pool is None: + try: + DATABASE_URL = os.environ.get("DATABASE_URL") + _connection_pool = psycopg2.pool.SimpleConnectionPool( + 1, # minimum connections + 5, # maximum connections + DATABASE_URL + ) + logger.info("Database connection pool created") + except Exception as e: + logger.error(f"Failed to create connection pool: {e}") + return None + return _connection_pool + +def get_db_connection(): + """Get a connection from the pool""" + try: + pool = get_connection_pool() + if pool: + conn = pool.getconn() + return conn + return None + except Exception as e: + logger.error(f"Database connection error: {e}") + return None + +def release_db_connection(conn): + """Return connection to the pool""" + try: + pool = get_connection_pool() + if pool and conn: + pool.putconn(conn) + except Exception as e: + logger.error(f"Error releasing connection: {e}") \ No newline at end of file diff --git a/database/models.py b/database/models.py new file mode 100644 index 0000000..d67b314 --- /dev/null +++ b/database/models.py @@ -0,0 +1,26 @@ +import logging +import database.connection as connection + +logger = logging.getLogger(__name__) + + +class testModel: + def getAllUsers(): + conn = None + try: + conn = connection.get_db_connection() + if not conn: + return None + + cursor = conn.cursor() + cursor.execute("SELECT * FROM students"); + result = cursor.fetchall() + cursor.close() + + return result if result else None + except Exception as e: + logger.error(f"Database query error: {e}") + return None + finally: + if conn: + connection.release_db_connection(conn) \ No newline at end of file diff --git a/dev.py b/dev.py new file mode 100644 index 0000000..0695b8a --- /dev/null +++ b/dev.py @@ -0,0 +1,27 @@ +import os +import requests +from bot import get_bot +from dotenv import load_dotenv + +load_dotenv() + +BOT_TOKEN = os.environ.get("BOT_TOKEN") + +def ensure_no_webhook(): + """Remove webhook before starting polling""" + response = requests.post( + f"https://api.telegram.org/bot{BOT_TOKEN}/deleteWebhook" + ) + if response.json()['ok']: + print("✅ Webhook removed, starting polling...") + return True + + print("⚠️ Warning: Could not remove webhook") + return False + + +if __name__ == "__main__": + if ensure_no_webhook(): + bot = get_bot() + print("🤖 Bot is polling locally...") + bot.polling(non_stop=True) \ No newline at end of file diff --git a/devrequirements.txt b/devrequirements.txt new file mode 100644 index 0000000..6f5d5b2 --- /dev/null +++ b/devrequirements.txt @@ -0,0 +1,6 @@ +fastapi +uvicorn +pyTelegramBotAPI +psycopg2-binary +requests +dotenv \ No newline at end of file diff --git a/main.py b/main.py index 1bb780b..9984f32 100644 --- a/main.py +++ b/main.py @@ -43,36 +43,6 @@ async def telegram_webhook(request: Request): return JSONResponse(content={"ok": True}, status_code=200) -@app.post("/api/test") -async def test(): - return {"message": "Test successful"} - - -@app.get("/api/data") -def get_sample_data(): - return { - "data": [ - {"id": 1, "name": "Sample Item 1", "value": 100}, - {"id": 2, "name": "Sample Item 2", "value": 200}, - {"id": 3, "name": "Sample Item 3", "value": 300} - ], - "total": 3, - "timestamp": "2024-01-01T00:00:00Z" - } - - -@app.get("/api/items/{item_id}") -def get_item(item_id: int): - return { - "item": { - "id": item_id, - "name": "Sample Item " + str(item_id), - "value": item_id * 100 - }, - "timestamp": "2024-01-01T00:00:00Z" - } - - @app.get("/", response_class=HTMLResponse) def read_root(): return """ diff --git a/setting-webhook.txt b/setting-webhook.txt new file mode 100644 index 0000000..ba476ff --- /dev/null +++ b/setting-webhook.txt @@ -0,0 +1,5 @@ +# Set the webhook +curl -X POST "https://api.telegram.org/bot/setWebhook?url=https://your-app.vercel.app/api/telegram_webhook" + +# Verify it's set +curl "https://api.telegram.org/bot/getWebhookInfo" \ No newline at end of file