import datetime import signal import sys import logging from os import getenv from typing import Union from googleapiclient.discovery import Resource from telegram.ext import Updater, CommandHandler, CallbackContext from telegram import Update from telegram.ext.jobqueue import Job from sheets_client import ( authenticate_sheets, fetch_sheet_data, update_sheet_last_done_column, ) from data_parser import ( filter_only_this_week, process_rows, updated_last_done_datestamps, ) from functools import partial chats_mem_cache = {} ALLOWED_USER_IDS = [ int(id) for id in getenv("TELEGRAM_USER_IDS", "").split(",") if len(id) > 0 ] def _signal_handler(sig, frame): print("You pressed Ctrl+C!") updater = frame.f_locals["updater"] for chat_id in chats_mem_cache.keys(): updater.bot.send_message(chat_id=chat_id, text="HommaBot-palvelin sammutettu!") updater.stop() sys.exit(0) def _callback_alarm(context: CallbackContext, sheets_service: Resource): chat_id: int = context.job.context logging.info(f"Authenticating and fetching data from Sheets...") rows = fetch_sheet_data(sheets_service) logging.info(f"Processing data...") processed_rows = process_rows(rows) this_weeks_rows = filter_only_this_week(processed_rows) logging.info(f"Sending sheet data to chat id {chat_id}...") if len(this_weeks_rows) > 0: message = "Tällä viikolla tehtävät hommat:\n" + "\n".join( f"{task.name} ({task.interval})" for task in this_weeks_rows ) else: message = "Tällä viikolla ei toistuvia hommia! 🎉 " context.bot.send_message(chat_id=chat_id, text=message) new_datestamps = updated_last_done_datestamps(processed_rows) update_sheet_last_done_column(sheets_service, new_datestamps) def _callback_timer(update: Update, context: CallbackContext, sheets_service: Resource): chat_id = update.message.chat_id user_id = update.message.from_user.id if user_id not in ALLOWED_USER_IDS: logging.info(f"User {user_id} is not allowed to start timer.") update.message.reply_text( "Käyttäjälläsi ei ole oikeuksia startata HommaBottia." ) return logging.info(f"Starting timer in chat id {chat_id}...") update.message.reply_text( "HommaBot startattu. Uusia hommapäivityksiä viikon välein." ) job = context.job_queue.run_repeating( partial(_callback_alarm, sheets_service=sheets_service), datetime.timedelta(weeks=1), 1, # run once immediately after 1 sec name="callback_alarm", context=chat_id, ) chats_mem_cache[chat_id] = job def _stop_timer(update: Update, context: CallbackContext): chat_id = update.message.chat_id user_id = update.message.from_user.id if chat_id not in chats_mem_cache: return if user_id not in ALLOWED_USER_IDS: logging.info(f"User {user_id} is not allowed to stop timer.") update.message.reply_text( "Käyttäjälläsi ei ole oikeuksia pysäyttää HommaBottia." ) return logging.info(f"Stopping timer in chat id {chat_id}...") update.message.reply_text("HommaBot pysäytetty!") job: Job = chats_mem_cache[chat_id] job.schedule_removal() del chats_mem_cache[chat_id] def run_telegram(): sheets_service = authenticate_sheets() tg_token = getenv("TELEGRAM_TOKEN") logging.info("Creating Telegram bot object...") updater = Updater(tg_token) logging.info("Registering Telegram bot /start handler...") updater.dispatcher.add_handler( CommandHandler( "start", partial(_callback_timer, sheets_service=sheets_service), pass_job_queue=True, ) ) logging.info("Registering Telegram bot /stop handler...") updater.dispatcher.add_handler( CommandHandler("stop", _stop_timer, pass_job_queue=True) ) logging.info("Starting Telegram bot (HommaBot)...") updater.start_polling() logging.info("Registering SIGINT handler...") signal.signal(signal.SIGINT, _signal_handler) logging.info("Bot started successfully. Pausing main thread... (this is expected)") signal.pause()