jade-assistant / main.py
Madras1's picture
Upload 7 files
9fd07c9 verified
import os
import logging
import asyncio
from datetime import datetime
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters
# Import Agent and ReminderManager
try:
from .core import TelegramJadeAgent
from .tools import ReminderManager
except ImportError:
from core import TelegramJadeAgent
from tools import ReminderManager
# Logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO
)
logger = logging.getLogger(__name__)
# Global instances
reminder_manager = ReminderManager()
agent = TelegramJadeAgent(reminder_manager=reminder_manager)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await context.bot.send_message(chat_id=update.effective_chat.id, text="Hi! I'm Jade, your 24h assistant. How can I help you?")
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
user_text = update.message.text
# 1. Get response from Agent
# agent.chat is blocking (sync), so we wrap it.
response = await asyncio.to_thread(agent.chat, chat_id, user_text)
await context.bot.send_message(chat_id=chat_id, text=response)
async def send_reminder_job(context: ContextTypes.DEFAULT_TYPE):
"""Callback function for the scheduled job."""
job_data = context.job.data
chat_id = job_data["chat_id"]
reminder_message = job_data["message"]
reminder_id = job_data["id"]
# Check if reminder is still valid (not deleted)
current_reminders = reminder_manager.get_due_reminders()
if not any(r["id"] == reminder_id for r in current_reminders):
logger.info(f"Reminder {reminder_id} skipped (deleted or sent).")
return
logger.info(f"Triggering reminder {reminder_id} for chat {chat_id}")
# Generate message via Agent
text = await asyncio.to_thread(agent.generate_reminder_message, chat_id, reminder_message)
await context.bot.send_message(chat_id=chat_id, text=text)
# Mark as sent
reminder_manager.mark_as_sent(reminder_id)
async def check_reminders_loop(context: ContextTypes.DEFAULT_TYPE):
"""
Background task running every X seconds to check for new reminders in DB
and schedule them in the JobQueue.
"""
pending = reminder_manager.get_due_reminders()
job_queue = context.job_queue
# Get current scheduled jobs by name
current_jobs = [j.name for j in job_queue.jobs()]
for r in pending:
job_name = f"reminder_{r['id']}"
if job_name not in current_jobs:
try:
run_date = datetime.strptime(r["time"], "%Y-%m-%d %H:%M:%S")
# If time is in past, schedule for immediate execution
if run_date < datetime.now():
run_date = datetime.now()
logger.info(f"Scheduling {job_name} for {run_date}")
job_queue.run_once(
send_reminder_job,
when=run_date,
data=r,
name=job_name
)
except Exception as e:
logger.error(f"Failed to schedule {job_name}: {e}")
# Build application at module level so it can be imported by app.py
token = os.getenv("TELEGRAM_BOT_TOKEN")
application = None
if token:
application = ApplicationBuilder().token(token).build()
start_handler = CommandHandler('start', start)
msg_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message)
application.add_handler(start_handler)
application.add_handler(msg_handler)
# Add a repeating job to sync reminders (e.g. every 10 seconds)
if application.job_queue:
application.job_queue.run_repeating(check_reminders_loop, interval=10, first=1)
logger.info("Telegram application configured")
else:
logger.warning("TELEGRAM_BOT_TOKEN not found - bot will not start")
if __name__ == '__main__':
if not application:
print("Error: TELEGRAM_BOT_TOKEN not found.")
exit(1)
print("Jade Telegram Bot is running...")
application.run_polling()