It's probably my fault, but I can't make the "run_repeating" method works. I took a look at the examples from the official Github repo and find that timerbot.py. I tried to follow the same idea in my code, but I failed. I mean, the timerbot works, but I'm doing something wrong I can't figure out that is not working in my code. And I know, timerbot uses "run_once" instead of "run_repeating" but the documentation indicates a pretty similar syntax for both.
By the way, my bot is supposed to be a price tracker for Amazon products using Selenium (that part is ok). The bot get the url, then tracks the product until the price get cheaper and notify the user with a message.
This is basically the code (the part that matters):
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext, MessageHandler, Filters, ConversationHandler
from selenium import webdriver, common
import time, re
#Variables
token = open('note_token_telegram', 'r').read()
driver_path = open('note_driver','r').read()
bin_path = open('note_bin','r').read()
#Track
def track(update: Update, context: CallbackContext) -> None:
data = context.user_data
url = context.args[0]
chat_id = update.message.chat_id
if re.match(r'(https:\/\/www\.amazon\.).*', url):
print('track running')
#Scrape
driver_options = webdriver.FirefoxOptions()
driver_options.add_argument('--headless')
driver_options.binary_location = bin_path.strip()
driver = webdriver.Firefox(executable_path=driver_path.strip(), options=driver_options)
driver.get(url)
try:
try:
price = driver.find_element_by_css_selector('#priceblock_ourprice')
except common.exceptions.NoSuchElementException:
try:
price = driver.find_element_by_css_selector('#priceblock_saleprice')
except:
price = driver.find_element_by_css_selector('#priceblock_dealprice')
name = driver.find_element_by_css_selector('#productTitle')
except:
update.message.reply_text('Are you sure this is an Amazon product page? '+url)
driver.close()
data[name.text] = {'url': url, 'price' : price.text}
print(data.items())
driver.close()
print(chat_id)
context.job_queue.run_repeating(notification, 30, context=chat_id, name=str(chat_id))
update.message.reply_text("Good! We are now tracking one more Product!")
def notification(update, context):
#The Script
job = context.job
print('notification running')
print(type(job.context))
print(job.context)
print(context.user_data.items())
#Scrape
driver_options = webdriver.FirefoxOptions()
driver_options.add_argument('--headless')
driver_options.binary_location = bin_path.strip()
driver = webdriver.Firefox(executable_path=driver_path.strip(), options=driver_options)
for i in context.user_data.items():
driver.get(i[1]['url'])
try:
try:
new_price = driver.find_element_by_css_selector('#priceblock_ourprice')
except common.exceptions.NoSuchElementException:
try:
new_price = driver.find_element_by_css_selector('#priceblock_saleprice')
except:
new_price = driver.find_element_by_css_selector('#priceblock_dealprice')
except:
context.bot.send_message(job.context, text='Are you sure this is an Amazon product page?'+i['url'])
#Notification
if '-' in new_price.text and float(new_price.text[1:4]) < float(i[1]['price']):
context.bot.send_message(job.context, text=f"It's on your budget! \n{i[0]} \n {price.text} \n {i[1]['url']}")
driver.close()
elif float(new_price.text[1:9]) < float(i[1]['price']):
context.bot.send_message(job.context, text=f"It's on your budget! \n{i[0]} \n {price.text} \n {i[1]['url']}")
driver.close()
else:
driver.close()
#Main Function
def main():
updater = Updater(token.strip())
#Commands Instantiation
updater.dispatcher.add_handler(CommandHandler('track', track))
updater.dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, help))
#Main loop methods
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
And this is the error message I am receiveing:
raise ValueError('The following arguments have not been supplied: %s' %
ValueError: The following arguments have not been supplied: context
It's indicating a value error, but I have paste the context and all that stuff in the right place at the notification function, don't I? I just follow the same principles of timerbot.py (at least I tried...).