added database connection
This commit is contained in:
@@ -1,4 +1,9 @@
|
|||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
from database.models import testModel
|
||||||
|
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
_bot = None
|
_bot = None
|
||||||
|
|
||||||
@@ -7,14 +12,35 @@ def get_bot():
|
|||||||
if _bot is None:
|
if _bot is None:
|
||||||
import telebot
|
import telebot
|
||||||
BOT_TOKEN = os.environ.get("BOT_TOKEN")
|
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"])
|
@_bot.message_handler(commands=["start"])
|
||||||
def start(message):
|
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"""
|
||||||
|
<b>📚 {data[i][0]}</b>
|
||||||
|
<i>نویسنده:</i> {data[i][1]}
|
||||||
|
<i>موجودی:</i> {data[i][3]}/{data[i][8]}
|
||||||
|
<code>کد: {data[i][1]}</code>
|
||||||
|
"""
|
||||||
|
_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)
|
@_bot.message_handler(func=lambda message: True)
|
||||||
def echo_all(message):
|
def echo_all(message):
|
||||||
_bot.reply_to(message, f"You said: {message.text}")
|
_bot.reply_to(message, f"You said: {message.text}")
|
||||||
|
|||||||
@@ -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}")
|
||||||
@@ -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)
|
||||||
@@ -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)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fastapi
|
||||||
|
uvicorn
|
||||||
|
pyTelegramBotAPI
|
||||||
|
psycopg2-binary
|
||||||
|
requests
|
||||||
|
dotenv
|
||||||
@@ -43,36 +43,6 @@ async def telegram_webhook(request: Request):
|
|||||||
return JSONResponse(content={"ok": True}, status_code=200)
|
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)
|
@app.get("/", response_class=HTMLResponse)
|
||||||
def read_root():
|
def read_root():
|
||||||
return """<!DOCTYPE html>
|
return """<!DOCTYPE html>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Set the webhook
|
||||||
|
curl -X POST "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook?url=https://your-app.vercel.app/api/telegram_webhook"
|
||||||
|
|
||||||
|
# Verify it's set
|
||||||
|
curl "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getWebhookInfo"
|
||||||
Reference in New Issue
Block a user