Files
jigaido/apps/telegram-bot/bot.py
shokollm 4885be0752 fix: cleanup codebase and sync SPEC with actual permissions
Phase 1: Ruff lint fixes
- Remove unused imports across all files
- Remove unused variables (now_utc, tz, ctx)
- Fix f-string without placeholders
- Fix E402 import order with noqa comments

Phase 2: Remove confusing hard delete from storage
- Removed delete_bounty() from RoomStorage Protocol (never used by app)
- Removed delete_bounty() from JsonFileRoomStorage (was hard delete)
- Removed corresponding tests (hard delete was never used)

Phase 3: Sync SPEC.md with actual code behavior
- Updated overview: admins can add/edit/delete (not 'anyone' + 'creator')
- Updated command table: /add, /edit, /delete are admin only
- Updated error handling messages

Test results: 96 passed (2 hard delete tests removed)
2026-04-09 10:01:02 +00:00

111 lines
2.8 KiB
Python

"""JIGAIDO Telegram bot entrypoint."""
import logging
import sys
sys.path.insert(0, "/home/shoko/repositories/jigaido")
from telegram.ext import (
Application,
CommandHandler,
CallbackQueryHandler,
)
from commands import (
cmd_add,
cmd_admin,
cmd_bounty,
cmd_delete,
cmd_delete_message,
cmd_edit,
cmd_help,
cmd_my,
cmd_recover,
cmd_show,
cmd_start,
cmd_timezone,
cmd_track,
cmd_untrack,
cmd_update,
)
logging.basicConfig(
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
level=logging.INFO,
)
log = logging.getLogger(__name__)
from config import config # noqa: E402
BOT_TOKEN = config.bot_token or ""
async def error_handler(update, context):
log.error(f"Error: {context.error}")
def build_app() -> Application:
app = Application.builder().token(BOT_TOKEN).build()
app.add_handler(CommandHandler("start", cmd_start))
app.add_handler(CommandHandler("help", cmd_help))
app.add_handler(CommandHandler("bounty", cmd_bounty))
app.add_handler(CommandHandler("my", cmd_my))
app.add_handler(CommandHandler("add", cmd_add))
app.add_handler(CommandHandler("edit", cmd_edit))
app.add_handler(CommandHandler("update", cmd_update))
app.add_handler(CommandHandler("delete", cmd_delete))
app.add_handler(CommandHandler("track", cmd_track))
app.add_handler(CommandHandler("untrack", cmd_untrack))
app.add_handler(CommandHandler("show", cmd_show))
app.add_handler(CommandHandler("timezone", cmd_timezone))
app.add_handler(CommandHandler("admin", cmd_admin))
app.add_handler(CommandHandler("recover", cmd_recover))
app.add_handler(CallbackQueryHandler(cmd_delete_message))
app.add_error_handler(error_handler)
return app
async def post_init(app: Application) -> None:
await app.bot.set_my_commands(
[
("bounty", "List bounties"),
("my", "Your tracked bounties"),
("add", "Add a bounty"),
("edit", "Edit a bounty"),
("track", "Track a bounty"),
("untrack", "Stop tracking"),
("show", "Show bounty details"),
("timezone", "Get/set room timezone"),
("admin", "Manage admins"),
("recover", "Recover deleted bounties"),
("help", "Show help"),
]
)
def main() -> None:
import asyncio
if not BOT_TOKEN:
log.error("JIGAIDO_BOT_TOKEN environment variable not set.")
sys.exit(1)
app = build_app()
app.post_init = post_init
log.info("JIGAIDO starting...")
# Python 3.14 compatibility: ensure event loop exists
try:
asyncio.get_event_loop()
except RuntimeError:
asyncio.set_event_loop(asyncio.new_event_loop())
app.run_polling(drop_pending_updates=True)
if __name__ == "__main__":
main()