Initial commit: project scaffold, full spec, database schema, bot and cron
- SPEC.md: full project specification from design discussion - schema.sql: SQLite database schema - db.py: database wrapper with all query functions - bot.py: telegram bot entrypoint - commands.py: all command handlers with admin/creator guards - cron.py: daily reminder job - requirements.txt: python-telegram-bot, dateparser - README.md, CONTRIBUTING.md - .gitignore
This commit is contained in:
77
cron.py
Normal file
77
cron.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""Daily reminder cron job for JIGAIDO.
|
||||
|
||||
Run with: python -m cron
|
||||
Or schedule via systemd timer / cron.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
# Add project root to path
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
import db
|
||||
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
|
||||
level=logging.INFO,
|
||||
)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Token from environment
|
||||
BOT_TOKEN = os.environ.get("JIGAIDO_BOT_TOKEN", "")
|
||||
|
||||
REMINDER_WINDOW_DAYS = 7
|
||||
|
||||
|
||||
async def send_reminder(user_telegram_id: int, bounty: dict, bot) -> None:
|
||||
days_left = (bounty["due_date_ts"] - int(time.time())) // 86400
|
||||
if days_left < 0:
|
||||
urgency = "OVERDUE"
|
||||
elif days_left == 0:
|
||||
urgency = "TODAY"
|
||||
else:
|
||||
urgency = f"{days_left} days left"
|
||||
|
||||
due_str = time.strftime("%Y-%m-%d", time.localtime(bounty["due_date_ts"]))
|
||||
text = f"⏰ Reminder: bounty #{bounty['id']}"
|
||||
if bounty["text"]:
|
||||
text += f" — {bounty['text']}"
|
||||
text += f"\nDue: {due_str} ({urgency})"
|
||||
|
||||
try:
|
||||
await bot.send_message(chat_id=user_telegram_id, text=text, disable_web_page_preview=True)
|
||||
log.info(f"Reminder sent to {user_telegram_id} for bounty #{bounty['id']}")
|
||||
except Exception as e:
|
||||
log.error(f"Failed to send reminder to {user_telegram_id}: {e}")
|
||||
|
||||
|
||||
async def run_reminders() -> None:
|
||||
if not BOT_TOKEN:
|
||||
log.error("JIGAIDO_BOT_TOKEN not set")
|
||||
return
|
||||
|
||||
from telegram import Bot
|
||||
bot = Bot(BOT_TOKEN)
|
||||
|
||||
user_ids = db.get_all_user_ids()
|
||||
log.info(f"Running reminders for {len(user_ids)} users...")
|
||||
|
||||
for user_telegram_id in user_ids:
|
||||
due_bounties = db.get_bounties_due_soon(user_telegram_id, REMINDER_WINDOW_DAYS)
|
||||
for bounty in due_bounties:
|
||||
await send_reminder(user_telegram_id, dict(bounty), bot)
|
||||
db.log_reminder(user_telegram_id, bounty["id"])
|
||||
|
||||
log.info("Reminder run complete.")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
asyncio.run(run_reminders())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user