diff --git a/bot.py b/bot.py index b891517..764cca6 100644 --- a/bot.py +++ b/bot.py @@ -16,7 +16,7 @@ from telegram.ext import ( filters, ) -from db import init_db, save_workout, get_workouts, get_workout_count, get_stats_sql, delete_workout +from db import init_db, save_workout, get_workouts, get_workout_count, get_stats_sql, delete_workout, save_feedback from parser import parse_workout, format_workout load_dotenv() @@ -93,7 +93,8 @@ async def cmd_start(update: Update, context: ContextTypes.DEFAULT_TYPE): "/history \u2014 view recent workouts\n" "/stats \u2014 quick summary\n" "/delete <id> \u2014 delete a workout\n" - "/export \u2014 export all data as JSON" + "/export \u2014 export all data as JSON\n" + "/feedback <text> \u2014 send feedback" ) if WEBAPP_URL: @@ -197,6 +198,21 @@ async def cmd_export(update: Update, context: ContextTypes.DEFAULT_TYPE): ) +async def cmd_feedback(update: Update, context: ContextTypes.DEFAULT_TYPE): + user_id = update.effective_user.id + text = " ".join(context.args) if context.args else "" + + if not text: + await update.message.reply_text( + "Usage: /feedback <your feedback>", + parse_mode=ParseMode.HTML, + ) + return + + save_feedback(user_id, text) + await update.message.reply_text("\U0001f4dd Feedback saved, thanks!") + + # ── Message handler (workout parsing) ─────────────────────────────────────── @@ -290,6 +306,7 @@ def main(): app.add_handler(CommandHandler("stats", cmd_stats)) app.add_handler(CommandHandler("delete", cmd_delete)) app.add_handler(CommandHandler("export", cmd_export)) + app.add_handler(CommandHandler("feedback", cmd_feedback)) # Handle all text messages (including forwarded ones) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message)) diff --git a/db.py b/db.py index 5f424cd..30ce291 100644 --- a/db.py +++ b/db.py @@ -60,6 +60,13 @@ def init_db(): CREATE INDEX IF NOT EXISTS idx_workouts_user ON workouts(user_id, timestamp); + + CREATE TABLE IF NOT EXISTS feedback ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + text TEXT NOT NULL, + created_at TEXT NOT NULL DEFAULT (datetime('now')) + ); """) # Migrations @@ -246,3 +253,23 @@ def export_workouts(user_id: int) -> list[dict]: """, (user_id,)).fetchall() return [dict(r) for r in rows] + + +def save_feedback(user_id: int, text: str) -> int: + """Save user feedback. Returns the feedback id.""" + with get_db() as conn: + cur = conn.execute( + "INSERT INTO feedback (user_id, text) VALUES (?, ?)", + (user_id, text), + ) + return cur.lastrowid + + +def get_feedback(limit: int = 50) -> list[dict]: + """Get all feedback, newest first.""" + with get_db() as conn: + rows = conn.execute( + "SELECT id, user_id, text, created_at FROM feedback ORDER BY created_at DESC LIMIT ?", + (limit,), + ).fetchall() + return [dict(r) for r in rows]