For personal work, I’m building a Telegram Bot that acts as a calendar for my favorite team’s matches. The idea for this Bot was to scrape from a site that publishes the match calendar, put this calendar in a local database (sqlite3
) and access it via the commands on Telegram, /prossime
, /prossime10
, /calendario
. Another task I would like you to do is that if you find a match on today’s date (after checking with the scheduler) you must send me a message on a Telegram channel; however, the issues I have encountered so far are:
-
Although the Bot connects to the website to do scraping, I find that until I stop the bot manually the data is not saved in the database. I therefore find myself having to do
CTRL + C
every time to stop the Bot and save the data, which can then be easily accessed by the Bot. Do you have any idea how to solve it? -
I can’t send messages with the
send_match_reminder()
function either privately or on the channel. Here too, do you have any ideas? -
Finally, I can’t get the Bot to work on the channel, even though I send commands, the Bot doesn’t respond. Something is probably missing.
I leave much of the code for you to understand. I will also send more eventually.
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()
The Bot generally works, except that to save the data in the DB I have to close the application every time. I have difficulty doing this manually though; also, I have problems as described above with messages in channels.