I'm using python-telegram-bot
def delete(update: Update, context: CallbackContext) -> None:
"""delete account from database"""
num = random.randrange(111111,999999)
update.message.reply_text("Something to write here\n\n****" + str(num) + "****")
time.sleep(10)
if int(update.message.text) == num: #here update.message.text == '/cancel' and not the message user
flag = delete_db(update.effective_user.id)
if flag:
update.message.reply_text('OK')
else:
update.message.reply_text('Something goes wrong or time is out')
How can i force the update of the message? I think is there the problem...
I resolved it, on the advice of the telegram community, with a Conversational Handler with two function, one to start the operation and the second to confirm.
In def main:
dispatcher.add_handler(
ConversationHandler(
entry_points = [MessageHandler(Filters.regex('^Cancel$'), delete)],
states = {
DELETE: [MessageHandler(Filters.text, random_number)],
},
fallbacks = [None], # here you can enter an /end function to break the process
conversation_timeout = 30,
),
)
Start function 'delete':
def delete(update: Update, context: CallbackContext):
update.message.reply_text('some message')
CallbackContext.chat_data = random.randrange(111111,999999)
update.message.reply_text("some other message\n*" + str(CallbackContext.chat_data) + "*")
return DELETE
The function to keep the string message and compare to random number generated:
def random_number(update: Update, context: CallbackContext):
try:
user_action = int(update.message.text)
if user_action == CallbackContext.chat_data:
#flag = delete_db(update.effective_user.id) # function to delete from database
if flag:
update.message.reply_text('Okay done')
else:
update.message.reply_text('Wrong number')
except:
update.message.reply_text('failed')
return ConversationHandler.END
Related
I'm really new to python and
I have a python selenium script
#Developed by github.com/useragents
#This script was made for educational purposes. I am not responsible for your actions using this script. This code is a few months old, hence why it may not appear as professional but still works to this day.
try:
from selenium import webdriver
import time, os, ctypes, requests
from colorama import Fore, init
import warnings, selenium, platform
except ImportError:
input("Error while importing modules. Please install the modules in requirements.txt")
init(convert = True, autoreset = True)
warnings.filterwarnings("ignore", category=DeprecationWarning)
clear = "clear"
if platform.system() == "Windows":
clear = "cls"
os.system(clear)
ascii_text = f"""{Fore.RED}
████████▀▀▀████
████████────▀██
████████──█▄──█
███▀▀▀██──█████
█▀──▄▄██──█████
█──█████──█████
█▄──▀▀▀──▄█████
███▄▄▄▄▄███████ github.com/useragents
"""
class automator:
def __init__(self):
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_experimental_option("excludeSwitches", ["enable-logging"])
self.xpaths = {
"followers": "/html/body/div[4]/div[1]/div[3]/div/div[1]/div/button",
"likes": "/html/body/div[4]/div[1]/div[3]/div/div[2]/div/button",
"views": "/html/body/div[4]/div[1]/div[3]/div/div[4]/div/button",
"shares": "/html/body/div[4]/div[1]/div[3]/div/div[5]/div/button"
}
try:
self.driver = webdriver.Chrome(options = options)
except Exception as e:
self.error(f"Error trying to load web driver: {e}")
self.status = {}
self.sent = 0
self.cooldowns = 0
self.ratelimits = 0
def check_status(self):
for xpath in self.xpaths:
value = self.xpaths[xpath]
element = self.driver.find_element_by_xpath(value)
if not element.is_enabled():
self.status.update({xpath: "[OFFLINE]"})
else:
self.status.update({xpath: ""})
def check_for_captcha(self):
while True:
try:
if "Enter the word" not in self.driver.page_source:
return
except:
return
os.system(clear)
print(ascii_text)
print(f"{self.console_msg('Error')} Complete the CAPTCHA in the driver.")
time.sleep(1)
def console_msg(self, status):
colour = Fore.RED
if status == "Success":
colour = Fore.GREEN
return f" {Fore.WHITE}[{colour}{status}{Fore.WHITE}]"
def update_ascii(self):
options = f"""
{self.console_msg("1")} Follower Bot {Fore.RED}{self.status["followers"]}
{self.console_msg("2")} Like Video Bot {Fore.RED}{self.status["likes"]}
{self.console_msg("3")} View Bot {Fore.RED}{self.status["views"]}
{self.console_msg("4")} Share Bot {Fore.RED}{self.status["shares"]}
"""
return ascii_text + options
def check_url(self, url):
redirect = True
if "vm.tiktok.com/" in url:
redirect = False
if redirect:
if "/video/" not in url:
return False
session = requests.Session()
r = session.get(url, allow_redirects=redirect)
if redirect:
if r.status_code == 200:
return True
return False
location = r.headers["Location"]
if "/video" in location:
return True
return False
def convert(self, min, sec):
seconds = 0
if min != 0:
answer = int(min) * 60
seconds += answer
seconds += int(sec) + 15
return seconds
def check_submit(self, div):
remaining = f"/html/body/div[4]/div[{div}]/div/div/h4"
try:
element = self.driver.find_element_by_xpath(remaining)
except:
return None, None
if "READY" in element.text:
return True, True
if "seconds for your next submit" in element.text:
output = element.text.split("Please wait ")[1].split(" for")[0]
minutes = element.text.split("Please wait ")[1].split(" ")[0]
seconds = element.text.split("(s) ")[1].split(" ")[0]
sleep_duration = self.convert(minutes, seconds)
return sleep_duration, output
return element.text, None
def update_cooldown(self, sleep_time, bot, rl = False):
cooldown = sleep_time
while True:
time.sleep(1)
try:
cooldown -= 1
except TypeError:
break
self.update_title(bot, cooldown, rl)
if cooldown == 0:
break
def wait_for_ratelimit(self, arg, div):
time.sleep(1)
duration, output = self.check_submit(div)
if duration == True:
return
if output == None:
time.sleep(0.7)
self.wait_for_ratelimit(arg, div)
self.cooldowns += 1
self.update_cooldown(duration, arg)
def send_bot(self, video_url, bot, div):
try:
self.driver.find_element_by_xpath(self.xpaths[bot]).click()
time.sleep(0.5)
except:
pass
enter_link_xpath = f"/html/body/div[4]/div[{div}]/div/form/div/input"
link = self.driver.find_element_by_xpath(enter_link_xpath)
link.clear()
link.send_keys(video_url)
self.driver.find_element_by_xpath(f"/html/body/div[4]/div[{div}]/div/form/div/div/button").click() #Search button
time.sleep(0.8)
send_button_xpath = f"/html/body/div[4]/div[{div}]/div/div/div[1]/div/form/button"
try:
self.driver.find_element_by_xpath(send_button_xpath).click()
except selenium.common.exceptions.NoSuchElementException:
self.wait_for_ratelimit(bot, div)
self.driver.find_element_by_xpath(f"/html/body/div[4]/div[{div}]/div/form/div/div/button").click() #Search button
time.sleep(0.8)
self.driver.find_element_by_xpath(send_button_xpath).click()
time.sleep(3)
try:
s = self.driver.find_element_by_xpath(f"/html/body/div[4]/div[{div}]/div/div/span")
if "Too many requests" in s.text:
self.ratelimits += 1
self.update_cooldown(50, bot, True)
self.send_bot(video_url, bot, div)
elif "sent" in s.text:
sent = 100
if bot == "likes":
try:
sent = int(s.text.split(" Hearts")[0])
except IndexError:
sent = 30
if bot == "views":
sent = 2500
if bot == "shares":
sent = 500
self.sent += sent
else:
print(s.text)
except:
self.sent += sent
self.update_title(bot, "0")
self.wait_for_ratelimit(bot, div)
self.send_bot(video_url, bot, div)
def update_title(self, bot, remaining, rl = False):
if clear == "cls":
os.system(clear)
ctypes.windll.kernel32.SetConsoleTitleW(f"TikTok AIO | Sent: {self.sent} | Cooldown: {remaining}s | Developed by #useragents on Github")
print(ascii_text)
print(self.console_msg(self.sent) + f" Sent {bot}")
rl_cooldown = "0"
cooldown = "0"
if rl:
rl_cooldown = remaining
else:
cooldown = remaining
print(self.console_msg(self.cooldowns) + f" Cooldowns {Fore.WHITE}[{Fore.RED}{cooldown}s{Fore.WHITE}]")
print(self.console_msg(self.ratelimits) + f" Ratelimits {Fore.WHITE}[{Fore.RED}{rl_cooldown}s{Fore.WHITE}]")
def main(self):
if clear == "cls":
ctypes.windll.kernel32.SetConsoleTitleW("TikTok AIO | Developed by #useragents on Github")
self.driver.get("https://zefoy.com/")
time.sleep(2)
if "502 Bad Gateway" in self.driver.page_source:
os.system(clear)
print(ascii_text)
input(f"{self.console_msg('Error')} This website does not allow VPN or proxy services.")
os._exit(0)
self.check_for_captcha()
self.check_status()
self.start()
def error(self, error):
print(ascii_text)
print(f"{self.console_msg('Error')} {error}")
time.sleep(5)
os._exit(0)
def start(self):
os.system(clear)
print(self.update_ascii())
try:
option = int(input(f" {Fore.RED}> {Fore.WHITE}"))
except ValueError:
self.start()
if option == 1:
if self.status["followers"] != "":
return self.start()
div = 2
ver = "followers"
username = str(input(f"\n{self.console_msg('Console')} TikTok Username: #"))
print()
self.send_bot(username, ver, div)
return
elif option == 2:
if self.status["likes"] != "":
return self.start()
div = 3
ver = "likes"
elif option == 3:
if self.status["views"] != "":
return self.start()
div = 5
ver = "views"
elif option == 4:
if self.status["shares"] != "":
return self.start()
div = 6
ver = "shares"
else:
return self.start()
video_url = str(input(f"\n{self.console_msg('Console')} Video URL: "))
print()
check = self.check_url(video_url)
if not check:
return self.error("This URL does not exist.")
self.send_bot(video_url, ver, div)
obj = automator()
obj.main()
And tried to add https proxy with auth in this script
My proxy is 34.72.101.101:3127:user:BasAJSzAdAAWD
I tried to configure script to use proxy but it crashed one time and another time when I tried another way it worked but after some step proxy disappear
I need to write a method that will call on another class (once I have created it) to create a password. I need to be able to use the variable issueDescription from ticketCreation class to change what the output of respond() will be from supportResponse class. Basically, if the tickets issue is that they need a new password, I want the support response to respond with that new password (for now, I'm just trying to get it to return a string). I'm trying to do this under newPassword, however to be able to call on the ticketCreation.issueDescription within the supportResponse class, I seemingly need to put ticketCreation in the parameters for supportresponse __init__, but then that means I need to manually input that positional argument into respond(), which defeats the point of it being automatically triggered if the words "change password" is in the issueDescription (this being the output in case I'm not explaining this very well:
t1R = supportResponse("sucks")
TypeError: __init__() missing 1 required positional argument: 'ticketCreation'
Feel like I might be overthinking this, but here's what I've got:
class ticket(object):
counter = 2000
def __init__(self):
self.name = 'Ticket'
self.tc = ticketCreation(self.creatorName, self.staffID, self.email, self.issueDescription)
self.sr = supportResponse(self.ticketResponse)
class ticketCreation(ticket):
def __init__(self, creatorName, staffID, email, issueDescription):
self.creatorName = creatorName
self.staffID = staffID
self.email = email
self.issueDescription = issueDescription
ticket.counter += 1
self.ticketNumber = ticket.counter
def displayTicket(self):
ticket_info = []
ticket_info.append(self.ticketNumber)
ticket_info.append(self.creatorName)
ticket_info.append(self.staffID)
ticket_info.append(self.email)
ticket_info.append(self.issueDescription)
if self.creatorName == "":
print("Ticket Creator: Not Specified")
else:
print("Ticket Creator: " + str(ticket_info[1]))
if self.staffID == "":
print("--STAFF ID REQUIRED TO SUBMIT TICKET--")
return
else:
print("Staff ID: " + str(ticket_info[2]))
if self.email == "":
print("Email Address: Not Specified")
else:
print("Email Address: " + str(ticket_info[3]))
if self.issueDescription == "":
print("--DESCRIPTION OF YOUR ISSUE IS REQUIRED TO SUBMIT TICKET--")
return
else:
print("Description: " + str(ticket_info[4]))
def autoAssign(self):
if self.staffID == "" or self.issueDescription == "":
print("TICKET NOT CREATED\nTicket Number: N/A")
return
else:
print("Ticket Number: " + str(self.ticketNumber))
class supportResponse(ticket):
def __init__(self, ticketResponse, ticketCreation):
self.ticketResponse = ticketResponse
self.problem = ticketCreation.issueDescription
def respond(self):
if self.ticketResponse == "":
print("Response: Not Yet Provided")
else:
print("Response: " + self.ticketResponse)
def resolve(self):
if self.ticketResponse == "":
print("Ticket Status: Open")
else:
print("Ticket Status: Closed")
def reopenStatus(self):
print("Ticket Status: Reopened")
def newPassword(self):
if "change password" in self.problem:
self.ticketResponse = "New password generated: " #this will later call class passwordGenerator once I have made it
print(self.ticketResponse)
t1 = ticketCreation("Inna", "INNAM", "inna#whitecliffe.co.nz", "My monitor stopped working")
t1R = supportResponse("sucks")
t2 = ticketCreation("", "MARIAH", "", "Request for video camera to conduct webinars")
t2R = supportResponse("")
t3 = ticketCreation("Joel", "JOELS", "", "change password")
t3P = supportResponse.newPassword("")
print("\nPrinting Tickets:\n")
t1.autoAssign()
t1.displayTicket()
t1R.respond()
t1R.resolve()
print()
t2.autoAssign()
t2.displayTicket()
t2R.respond()
t2R.resolve()
print()
t3.autoAssign()
t3.displayTicket()
t3P.newPassword()
t3R.resolve()
thank you in advance for your help!
My goal is to edit the nickname of any user in the server which does not comply with the formatting I specify.
The following loop works perfectly fine without the line await user.edit(nick=f"SAS{jsonPilotID} - {jsonName}"), which is the one supposed to edit the actual nickname. However, when I add the line, the loop just blocks itself on the first user it encounters and does not want to advance. No errors are thrown and no nicknames are edited either.
#tasks.loop(seconds=LoopTimer)
async def NicknameUpdater(msg):
url = rankUrl
req = requests.post(url)
req = json.loads(req.text)
y = msg.guild.members
print("Start nickname edit loop \n")
for user in y:
for i in req['records']:
if not i['discordid'] == None:
jsonDiscordID = int(i['discordid'])
jsonName = i['firstname']
jsonPilot = i['pilotid']
if len(jsonPilot) == 1:
userPilotIDZero = "000"
elif len(jsonPilot) == 2:
userPilotIDZero = "00"
elif len(jsonPilot) == 3:
userPilotIDZero = "0"
elif len(jsonPilot) == 4:
userPilotIDZero = ""
jsonPilotID = userPilotIDZero + jsonPilot
if jsonDiscordID == user.id:
print(f"User {user} discord ID {user.id} name {jsonName}")
print(jsonPilotID)
print(f"SAS{jsonPilotID} - {jsonName}")
if not user.display_name == f"SAS{jsonPilotID} - {jsonName}":
await user.edit(nick=f"SAS{jsonPilotID} - {jsonName}")
print(f"Changed username for {jsonName} to SAS{jsonPilotID} - {jsonName}")
else:
print("no need to change nickname.")
else:
pass
t = time.localtime()
current_time = time.strftime("%H:%M:%S", t)
loopCompleteMessage = f"\n\nNickname edit loop end at {current_time}. Next loop in {LoopTimer} seconds"
print(loopCompleteMessage)
I will be happy to answer any questions.
Thanks in advance for your help!
def final_or_make_changes_to_bill(bot, update):
user_choice_make_changes = update.message.text
if user_choice_make_changes == "Yes":
reply_keyboard = [["Add","Delete"]]
message = "Do you want to add or delete?"
bot.send_message(chat_id=update.message.chat_id, text=message, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
return ADD_OR_DELETE
return STOP
For some reason the state STOP in my code is never reached. I tried other states and none of them are reached. I tried replacing the return statement in the if condition to STOP to check if there was a problem with the state. But it seems to work fine and the state is reached through the if statement block.
This is the function for the STOP state.
def stop(bot, update):
print("ht")
bot.send_message(chat_id=update.message.chat_id,text="dsfdsfsadf")
return ConversationHandler.END
Here's the entire code.
import os
import logging
from DBHelper import DBHelper
from telegram.ext import Updater,CommandHandler,MessageHandler,ConversationHandler,Filters
from telegram import ReplyKeyboardMarkup
from random import randint
TOKEN = ""
db = DBHelper()
ADD_ITEMS, FINAL_OR_MAKE_CHANGES, ADD_OR_DELETE, DELETE, STOP = range(5)
bill_items = []
ID = None
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
def start(bot, update):
message = "Welcome to the Bill Splitter Bot. An easy way to split bills among friends. The following are a list of"
+ "commands you can use."
bot.send_message(chat_id=update.message.chat_id, text=message)
message = ""
message += "/help - To get a list of commands\n"
message += "/create - To create a new bill\n"
message += "/add - To add items spent on for a particular bill"
message += "/get - To get the amount owed"
def create(bot, update):
global ID
message = "Hey! Looks like you're trying to create a new bill! One moment, while I create a new ID for you!"
bot.send_message(chat_id=update.message.chat_id, text=message)
id_for_bill = randint(1000,9999)
# Check if bill id does not exist in database
message = "Here's the ID for your bill: " + str(id_for_bill)
ID = id_for_bill
print(ID)
bot.send_message(chat_id=update.message.chat_id, text=message)
message = "Can you enter the items followed by the price for the bill? A simple format would look as follows. Type "
message += "Done when you're done adding items to the bill\n"
bot.send_message(chat_id=update.message.chat_id, text=message)
message = " <pre>Pizza - 150\n"
message += "Pasta - 150\n"
message += "Garlic Bread - 230</pre> "
reply_keyboard = [["Done"]]
bot.send_message(chat_id=update.message.chat_id, text=message,parse_mode="html")
return ADD_ITEMS
def add_items_to_bill(bot, update):
user_input_bill_items = update.message.text
# Use regex
if user_input_bill_items == "Done":
message = "Looks like you're done! Here's your bill for re-confirmation: "
item_count=0
for item in bill_items:
item_count += 1
message += "<pre>" + str(item_count) + ". " + str(item) + "\n</pre>"
bot.send_message(chat_id=update.message.chat_id, text=message, parse_mode="html")
message = "Do you want to make any changes to the bill?"
reply_keyboard = [["Yes","No"]]
bot.send_message(chat_id=update.message.chat_id, text=message, reply_markup=ReplyKeyboardMarkup(reply_keyboard,one_time_keyboard=True))
return FINAL_OR_MAKE_CHANGES
bill_items.append(user_input_bill_items)
return ADD_ITEMS
def final_or_make_changes_to_bill(bot, update):
user_choice_make_changes = update.message.text
if user_choice_make_changes == "Yes":
reply_keyboard = [["Add","Delete"]]
message = "Do you want to add or delete?"
bot.send_message(chat_id=update.message.chat_id, text=message, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
return ADD_OR_DELETE
return STOP
def add_or_delete(bot, update):
user_choice_add_or_delete = update.message.text
if user_choice_add_or_delete == "Add":
message = "Enter items you want to add."
bot.send_message(chat_id=update.message.chat_id, text=message)
return ADD_ITEMS
message = "Enter the list number of the item you want to delete. Type Done when you're done."
bot.send_message(chat_id= update.message.chat_id, text=message)
return DELETE
def delete_item_from_bill(bot, update):
number_to_delete = update.message.text
print(number_to_delete)
# SQL command to delete from table
print("to be filled")
return STOP
def stop(bot, update):
print("ht")
bot.send_message(chat_id=update.message.chat_id,text="dsfdsfsadf")
return ConversationHandler.END
# def done(bot, update):
# global ID
# bot.send_message(chat_id=update.message.chat_id, text="done")
# print("done")
# message = "Great! Share this ID with the other participants of the bill: "
# bot.send_message(chat_id=update.message.chat_id, text=message)
# return ConversationHandler.END
def cancel(bot,update):
print("cancel")
return ConversationHandler.END
def add_bought_items(bot, update):
message = "Add the list of items conforming to this example. Bill followed by ID\nEg: 4632 1,2,3"
bot.send_message(chat_id=update.message.chat_id, text=message)
def error(bot, update, error):
"""Log Errors caused by Updates."""
logger.warning('Update "%s" caused error "%s"', update, update.error)
def main():
updater = Updater(TOKEN)
db.setup()
PORT = int(os.environ.get('PORT','8443'))
dp = updater.dispatcher
dp.add_handler(CommandHandler("help",start))
create_conversation_handler = ConversationHandler(
entry_points = [CommandHandler('create',create)],
states = {
# GET_BILL_DETAILS: [MessageHandler(Filters.text,get_bill_details)],
ADD_ITEMS: [MessageHandler(Filters.text, add_items_to_bill)],
FINAL_OR_MAKE_CHANGES: [MessageHandler(Filters.text, final_or_make_changes_to_bill)],
ADD_OR_DELETE: [MessageHandler(Filters.text, add_or_delete)],
DELETE: [MessageHandler(Filters.text, delete_item_from_bill)],
STOP: [MessageHandler(Filters.text, stop)]
},
fallbacks = [CommandHandler('cancel',cancel)]
)
dp.add_handler(create_conversation_handler)
dp.add_error_handler(error)
dp.add_handler(CommandHandler("add",add_bought_items))
# dp.add_handler(CommandHandler("add",add))
updater.start_polling()
if __name__ == "__main__":
main()
Abstract.
I have two python files. The first one reads some inputs (texts) and the second one stores some functions. The problem here is the method I'm using to look for the function that I need. Now I'm using a If / Elif method to compare the input and the functions but this method needs to compare all the functions stored in the second file with the input and I was thinking if "this is the best way to do it?".
Full explanation.
I'm trying to build a Telegram chat bot, just to practice some Python. Before anything I drew a mental map to know what I want this scripts will do. Because of that mental map, I came with the idea of spliting the code in different files in order organize everything better and to do the debugging process a little bit easier. So, I did that. I store the credentials (for the api's) in one file, the mainframe in other file and the functions in other file. I import in the files into the mainframe with From Credentials import * and From Comands import *. When any text come to the bot it first checks how it starts, if it starts with "/" then it stores whatever comes after the slash in a variable and send it as a parameter to the functions file. When is there it starts to look for the exact command required and execute it. And it works but I guessing if there is a better way to do it. I hope I explained well the problem and you can help me. Here's the extract of code that I'm talking.
mainframe.py
from Comands import *
from credentials import *
...
if text.startswith("/"):
comando = text[1:]
print(comando)
Comands.search(comando)
elif text in items:
db.delete_item(text, chat)
items = db.get_items(chat)
keyboard = build_keyboard(items)
send_message("Select an item to delete", chat, keyboard)
else:
db.add_item(text, chat)
items = db.get_items(chat)
message = "\n".join(items)
send_message(message, chat)
...
Comands.py
from message_dictionary import *
from mainframe import *
def search(comando):
if comando == "start":
def start():
keyboard = build_keyboard(acuerdo)
send_message(mensaje["start"], chat, keyboard)
elif comando == "done":
def done():
keyboard = build_kerboard(items)
send_message("Select an item to delete", chat, keyboard)
First, I'll start with 2 recommendations:
Don't use stars in imports (it is hard to tell where functions are declared later)
Try to avoid cycle imports (import Command in mainframe.py and import mainframe in command.py)
mainframe.py
import command
comando_str = 'str_command'
# at this stage we want to call command.str_command(), but we have a string, not a function
if hasattr(command, comando_str): # let's check if such command exist in `command` module
comando_function = getattr(command, comando_str) # now let's get a reference to that function
# we can now call comando_function()!
# but maybe you have some parameters to call (like passing in `keyboard`)
arg_count = comando_function.__code__.co_argcount # total number of arguments to the function
# co_varnames has all the variables that function would use, but arguments come firs
arg_names = comando_function.__code__.co_varnames[:arg_count]
if arg_count >= 1 and arg_names[0] == 'keyboard':
comando_function(keyboard)
elif arg_count == 0: # function require no arguments
comando_function()
else:
raise Exception('Function %s could not be called', comando_str)
else:
raise Exception('Function command.%s is not declared', comando_str)
command.py
import message_dictionary as md # no *!
def str_command(keyboard):
md.send_message(mensaje["start"], chat, keyboard) # now I know that send_message is in md (message_dictionary)
def start():
keyboard = build_keyboard(acuerdo)
send_message(mensaje["start"], chat, keyboard)
some notes about your comand.py:
def search(comando): # ok
if comando == "start": # ok
# here you define function `start`
# yet, you have not called `start` function
# so, when you exit `search` function, this function is gone!
def start():
keyboard = build_keyboard(acuerdo) # where is acuerdo is declared?
send_message(mensaje["start"], chat, keyboard) # where mensaje and chat are declared?
elif comando == "done":
# same problem as with `start` function above
def done():
keyboard = build_kerboard(items)
send_message("Select an item to delete", chat, keyboard)
modified comand.py to return callable function (to address questions in comments):
def search(comando):
if comando == "start":
def start():
keyboard = build_keyboard(acuerdo)
send_message(mensaje["start"], chat, keyboard)
return start
elif comando == "done":
# same problem as with `start` function above
def done():
keyboard = build_kerboard(items)
send_message("Select an item to delete", chat, keyboard)
return done
modified fragment mainframe.py to use returned values:
if text.startswith("/"):
comando = text[1:]
print(comando) # look at the logging as a fancy replacing for print
call_me = Comands.search(comando)
if call_me: # checking that something is returned (not None)
call_me() # example of calling it
Here it is.
mainframe.py (it is actually called Prubeas.py)
#PYTHON 3.6.2
#LGsus
import json
import requests
import time
import urllib
from dbhelper import DBHelper
from credentials import *
from message_dictionary import *
import Comands
db = DBHelper()
#DECLARAR ID DEL BOT Y URL DE TELEGRAM
URL = "https://api.telegram.org/bot{}/".format(telegram_token)
#CONSULTAR ESTADO
def get_url(url):
response = requests.get(url)
content = response.content.decode("utf8")
return content
#CAMBIAR DE JSON A PYTHON (PARSE)
def get_json_from_url(url):
content = get_url(url)
js = json.loads(content)
return js
#SOLICITAR LISTA DE MENSAJES
def get_updates(offset=None):
url = URL + "getUpdates?timeout=100"
if offset:
url += "&offset={}".format(offset)
js = get_json_from_url(url)
return js
#DETERMINAR MENSAJES NO LEÍDOS
def get_last_update_id(updates):
update_ids = []
for update in updates["result"]:
update_ids.append(int(update["update_id"]))
return max(update_ids)
#RESPONDER A TODOS LOS NO LEIDOS
def handle_updates(updates):
for update in updates["result"]:
text = update["message"]["text"]
chat = update["message"]["chat"]["id"]
items = db.get_items(chat)
if text.startswith("/"):
comando = text[1:]
print(comando)
Comands.search(comando)
#fin = text.find(" ")
#print(fin)
#if text == "/done":
# keyboard = build_keyboard(items)
# send_message("select an item to delete", chat, keyboard)
#elif text == "/start":
# keyboard = build_keyboard(acuerdo)
# send_message(mensajes["start"], chat, keyboard)
#elif text.startswith("/"):
# continue
elif text in items:
db.delete_item(text, chat)
items = db.get_items(chat)
keyboard = build_keyboard(items)
send_message("Select an item to delete", chat, keyboard)
else:
db.add_item(text, chat)
items = db.get_items(chat)
message = "\n".join(items)
send_message(message, chat)
#SOLICITAR ULTIMO MENSAJE Y ID DEL CHAT
def get_last_chat_id_and_text(updates):
global Texto
global full_last
num_updates = len(updates["result"])
lista = updates["result"]
data = json.dumps(lista)
last_update = num_updates - 1
full_last = updates["result"][last_update]
Texto = "text" in full_last["message"]
if Texto == True:
text = updates["result"][last_update]["message"]["text"]
else:
text = "Entrada invalida"
chat_id = updates["result"][last_update]["message"]["chat"]["id"]
return (text, chat_id)
#CREAR EL TECLADO
def build_keyboard(items):
keyboard = [[item] for item in items]
reply_markup = {"keyboard":keyboard, "one_time_keyboard":True}
return json.dumps(reply_markup)
#ENVIAR MENSAJE
def send_message(text, chat_id, reply_markup=None):
text = text.encode(encoding='utf-8')
text = urllib.parse.quote_plus(text)
url = URL + "sendMessage?text={}&chat_id={}&parse_mode=Markdown".format(text, chat_id)
if reply_markup:
url += "&reply_markup={}".format(reply_markup)
get_url(url)
print (text)
text, chat = get_last_chat_id_and_text(get_updates())
send_message(text, chat)
##EJECUTAR
def main():
db.setup()
last_update_id = None
while True:
updates = get_updates(last_update_id)
if len(updates["result"]) > 0:
last_update_id = get_last_update_id(updates) + 1
handle_updates(updates)
time.sleep(0.5)
#CONDICION PARA EJECUTAR
if __name__ == '__main__':
main()
#import ccxt
#b = ccxt.bitso({
# 'apiKey': "XXXXXX",
# 'secret': "XXXXXX",
# 'verbose': False,
# })
#
#print(b.fetchBalance())
Whats it commented at the end of this code is for an API i'll try to use later, once I done with the telegram api.
Comands.py
#Lista de comandos
from message_dictionary import *
from Prubebas import *
def search(comando):
if comando == "start":
#def start():
keyboard = build_keyboard(acuerdo)
send_message(mensaje["start"], chat, keyboard)
def done():
keyboard = build_kerboard(items)
send_message("Select an item to delete", chat, keyboard)
I apologies for mixing the languages. I really appreciate your help, thanks.