My Telegram bot acts as a calendar for my favorite team’s matches. It should scrape from a site that publishes the match calendar, put this calendar in a local SQLite database and access it via commands on Telegram (/prossime
, /prossime10
, /calendario
). I also want that if it finds a match on today’s date to send a message on a Telegram channel.
- Although the bot connects to the website to do scraping, until I stop the bot manually the data is not saved in the database. I am having to do CTRL+C to stop the bot and save the data. How to solve it?
- I can’t send messages with
send_match_reminder()
either privately or on the channel. - Even though I send commands the bot doesn’t respond.
import asyncio
import requests
import telegram
import os
import string
import locale
import random
import logging
import schedule
import time
import sqlite3
from lxml import html
from datetime import datetime
from dotenv import load_dotenv
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters, CallbackContext, CallbackQueryHandler
load_dotenv()
CONNESSIONE_DB = sqlite3.connect('JUVENTUS_MATCHES.db')
CONNESSIONE = CONNESSIONE_DB.cursor()
locale.setlocale(locale.LC_TIME, 'it_IT.UTF-8')
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', filename='BOT_JUVE.log')
logger = logging.getLogger(__name__)
async def start_bot(update: Update, context: CallbackContext):
await update.message.reply_text("HI!")
.
.
.
.
.
async def get_next_match():
CONNESSIONE.execute("SELECT * FROM MATCHES ORDER BY DATA")
MATCHES = CONNESSIONE.fetchall()
TODAY = datetime.today().strftime("%Y-%m-%d")
for MATCH in MATCHES:
if MATCH[2] >= TODAY:
return MATCH
return None
async def get_next_10_matches():
CONNESSIONE.execute("SELECT * FROM MATCHES ORDER BY DATA")
MATCHES = CONNESSIONE.fetchall()
TODAY = datetime.today().strftime("%Y-%m-%d")
NEXT_10_MATCHES = []
for MATCH in MATCHES:
if MATCH[2] >= TODAY:
NEXT_10_MATCHES.append(MATCH)
if len(NEXT_10_MATCHES) == 10:
break
return NEXT_10_MATCHES
async def get_all_match():
CONNESSIONE.execute("SELECT * FROM MATCHES ORDER BY DATA")
MATCHES = CONNESSIONE.fetchall()
TODAY = datetime.today().strftime("%Y-%m-%d")
ALL_MATCHES = []
for MATCH in MATCHES:
ALL_MATCHES.append(MATCH)
return ALL_MATCHES
.
.
.
.
.
async def send_match_reminder(update: Update, context: CallbackContext):
MATCH = await get_next_match()
if MATCH:
MESSAGE = f"⚠️ OGGI GIOCHIAMO! ⚠️nn"
if MATCH[1] == "Serie A":
MESSAGE += f"???? {MATCH[1]} - {MATCH[4]}n⚽️ {MATCH[2]}n???? {datetime.strptime(MATCH[3], '%Y-%m-%d').strftime('%A %d %B %Y')}n???? {MATCH[5]}nn"
else:
MESSAGE += f"???? {MATCH[1]}n⚽️ {MATCH[2]}n???? {datetime.strptime(MATCH[3], '%Y-%m-%d').strftime('%A %d %B %Y')}n???? {MATCH[5]}nn"
await context.bot.send_message(chat_id=update.effective_chat.id, text=MESSAGE, parse_mode="HTML")
else:
MESSAGE = f"<b>❗️ NON CI SONO PARTITE IN PROGRAMMA ❗️</b>"
await context.bot.send_message(chat_id=update.effective_chat.id, text=MESSAGE, parse_mode="HTML")
.
.
.
.
.
async def update_database():
MATCHES = await get_juventus_matches()
CONNESSIONE.execute('DROP TABLE IF EXISTS MATCHES')
CONNESSIONE.execute('CREATE TABLE MATCHES (TIPO TEXT, PARTITA TEXT, DATA DATE, ORA TEXT, GIORNATA TEXT)')
CONNESSIONE.executemany("INSERT INTO MATCHES (TIPO, PARTITA, DATA, ORA, GIORNATA) VALUES (?, ?, ?, ?, ?)", [(MATCH['TIPO'], MATCH['PARTITA'], MATCH['DATA'], MATCH['ORA'], MATCH['GIORNATA']) for MATCH in MATCHES])
CONNESSIONE_DB.commit()
schedule.every().day.at("10:45").do(lambda: asyncio.run(update_database()))
def main():
app = ApplicationBuilder()
.read_timeout(100)
.write_timeout(100)
.token(os.environ["BOT_TOKEN"])
.build()
app.add_handler(CommandHandler("start", start_bot))
app.add_handler(CommandHandler("prossima", next_match_command))
app.add_handler(CommandHandler("prossime10", next_10_matches_command))
app.add_handler(CommandHandler("calendario", get_all_command))
app.run_polling()
schedule.run_pending()
if __name__ == "__main__":
main()