How to implement inline keyboard navigation in Python Telegram program? - python

I have written a Python Telegram program but I need a bit of help on navigating the inline keyboard. When user clicks on one of the custom keyboard button [Feedback], an inline keyboard appears:
"Message: Do you find this app useful"
[No], [Yes], [Leave Comments].
When pressing [No], only a text message appears "Thank you and we hope you can leave some comments how to improve the app", goes back to main menu.
When pressing [Yes], a second inline button message appears with wording "Please vote for this app!" which hyperlinks to external website.
When pressing [Leave Comments], user needs to type in comments which is saved into a database.
My problem is upon pressing any of the 3 inline button, it leads to the same function "insert_UserFeedback".
Part of my codes as follows.
keyboard03 = [[InlineKeyboardButton("No", callback_data='no'),
InlineKeyboardButton("Yes", callback_data='yes')],
[InlineKeyboardButton("Leave Comments", callback_data='comments')]]
reply_markup03 = InlineKeyboardMarkup(keyboard03)
update.message.reply_text('Do you find the app useful?',
reply_markup=reply_markup03)
user = update.message.from_user
return FEEDBACK
At conv_handler states={
FEEDBACK: [MessageHandler(Filters.text,
insert_UserFeedback,
pass_user_data=True),
def insert_UserFeedback(bot, update, user_data):
user = update.message.from_user
#some codes..
sql10 = "UPDATE `subscribers` SET `feedback`='" + userFeedbackTxt + "',
`feedbackDate`='" + todaydatestamp + "' WHERE `id`=" + str(user.id) + ";"
cc.execute(sql10)
copp.commit()
copp.close()
update.message.reply_text(user.first_name + ', thank you for your feedback!')
return KEYBOARDVAL
So regardless if I choose which inline button I chose, "insert_UserFeedback" is called which then requires user to write a comment, because the program did not know in advance which inline button was selected.

The response object InlineQuery has a field query where the result of the user action is returned. Check the structure at Telegram API Inline Query

Related

ipywidgets button on click run next widget

I am building a small Jupyter Notebook widget to call a Rest API and get some data.
The user need to provide an auth token to be able to call the API. The auth token (JWT Token) will be provided to the user from a different interface. The API will respond with a json list of data which needs to be put into a combobox and then user can choose 1 which will be inserted into a new cell
The issue I am running into is that I am unable to tell the API call to wait for user to input the auth token and click on the submit button.
There are 2 actions happening here
Act 1 : Text Box and Button for the auth token. User puts the auth token in the text box and clicks submit.
Auth token gets put into a global variable by the button on clicked function
Act 2: Use the global variable to call the Rest API to get the JSON list of data
Put the list into a combobox
User chooses a specific value.
Dump that specific data into a new cell
import requests
import json
from IPython.display import Javascript, display
def click_get_auth_token(b):
global get_datasources_api_token
get_datasources_api_token = atok.value
return None
def show_wid():
global atok
atok = widgets.Text(
placeholder='Auth_Token',
description='Auth Token',
disabled=False
)
display(atok)
button = widgets.Button(description="Submit")
display(button)
button.on_click(click_get_auth_token)
return None
def click_get_auth_token():
show_wid()
headers = {}
resp = requests.get('http://localhost:5000/get_data', headers={"Authorization" : "Bearer " + get_datasources_api_token})
resp = resp.json()
dsr_list = resp['datasources']
opt_list = []
for dsr in dsr_list:
opt_list.append(dsr["name"])
print(opt_list)
global w
w = widgets.Combobox(
options= opt_list,
disabled=False,
ensure_option=True,
)
display(w)
button = widgets.Button(description="Get Data")
display(button)
button.on_click(click_get_datasources)
def click_get_datasources()
dataset = None
for dsr in dsr_list:
if(dsr["name"] == w.value):
dataset = dsr
encoded_code = (base64.b64encode(str.encode(dataset))).decode()
display(Javascript("""
var code = IPython.notebook.insert_cell_below('code');
code.set_text(atob("{0}"));
""".format(encoded_code)))
My code is probably all over the place and is needlessly complex.
At the moment it works as long as I hard code an auth token.
But I am unable to get the Rest call to wait for the user to paste the token.
Any help would be appreciated.
Thank you

Selenium webdriver isn't able to clear a field, but is able to send_keys to it

I'm trying to create a program that signs up for instagram with a new account, I've got the emails and the rest generated, when I go ahead and send_keys to the appropriate fields, it does it just fine. I wanted to implement a retry function, which would clear the email field and try with a different mail. However this does not work, even though send_keys to it worked previously? Snippet of my code below.
driver.get('https://www.instagram.com')
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail)
driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]").send_keys(name + lastname)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(namae+lastonamae+pamae2)
driver.find_element_by_xpath("//*[contains(#aria-label,'Password')]").send_keys(password)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
This attempts to create a new account with the appropriate credentials, however when it fails, I want it to try to look for an element that is only present when it fails, and if it finds that, it should clear the email field and retry with a different one. Code below.
driver.find_element_by_xpath('//*[#id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[3]/div/div[2]/span') #this looks for the element only present on the fail page
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").clear()
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)
It doesn't clear the field, but doesn't raise an error either. It then proceeds to type the 2nd email with no problems. I appreciate any help on the matter.
EDIT: Posting a bigger chunk of the code.
def signup():
driver.get('https://www.instagram.com')
time.sleep(7)
if trycounter < 3: #this is almost always true, just a failsafe
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]").send_keys(name + ' ' + lastname)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(name+lastname+extension)
driver.find_element_by_xpath("//*[contains(#aria-label,'Password')]").send_keys(password)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
time.sleep(7)
try: #this only executes if a popup that wants you to confirm your age pops up
driver.find_element_by_xpath('//*[#id="igCoreRadioButtonageRadioabove_18"]').click()
driver.find_element_by_xpath('/html/body/div[3]/div/div[3]/div/button').click()
time.sleep(5)
except:
pass
try:
randomgen() #generates the mail,password and name
driver.find_element_by_xpath('//*[#id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[3]/div/div[2]/span')
time.sleep(1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").clear()
time.sleep(1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(username)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
time.sleep(7)
You can use following code as alternative for clear method:
from selenium.webdriver.common.keys import Keys
email_element = driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]")
email_element.send_keys(Keys.CONTROL, 'a')
email_element.send_keys(mail1)
fullname_element = driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]")
fullname_element.send_keys(Keys.CONTROL, 'a')
fullname_element.send_keys(name + ' ' + lastname)
# do it for other field as well
So this will definitely work as a workaround. I just tried it on instagram. Although there was no field with an aria label called Email for me. It was aria-label "Mobile Number or Email" for me.
driver.execute_script("$(\"input[aria-label='Email']"\").value = '';");
I will keep looking at it to see why the clear command didn't work though.
You can try something like this to delete mail1.
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(Keys.chord(Keys.CONTROL,"a"))
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(Keys.DELETE)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)

send_keys(Keys.RETURN) submitting 1 extra character (python selenium)

I am attempting to automate a login process.
To do so, I am using send_keys('email') and send_keys('password') in their respective fields like so:
email = driver.find_element_by_xpath('//*[#id="email"]')
email.send_keys('e#mail.com')
pwd = driver.find_element_by_xpath('//*[#id="password"]')
pwd.send_keys('pwd12345')
These two steps are successful. Now, I would like to use the "return" key to submit the login credentials and be logged in. To do so, I have tried:
pwd.send_keys(Keys.RETURN)
The password I am attempting to enter is 8 characters long. After the 8 characters have been entered, pwd.send_keys(Keys.RETURN) enters a 9th character into the password field JUST before the credentials are submitted, resulting in "incorrect email address or password".
I have also tried:
email.send_keys(Keys.RETURN) - which also returns "incorrect email address or password"
pwd.submit() - which clears the email and password fields completely and does not log in (?)
Thoughts?
Can you try code below?
pwd = driver.find_element_by_xpath('//*[#id="password"]')
ActionChains(driver).send_keys_to_element(pwd,'pwd12345').send_keys_to_element(pwd, Keys.RETURN).perform()
Here is the Answer to your Question:
Considering you are trying to login in to your PayPal Account with a valid set of credentials the following code block works through all the 3 options as in:
Using click()
Using Keys.ENTER
Using Keys.RETURN
Having said that I will suggest you to consider using the click() and clear() methods before entering any text into any input tag. Here is the working code block:
driver.get('https://www.paypal.com/in/home');
driver.implicitly_wait(20);
driver.find_element_by_id('ul-btn').click();
email = driver.find_element_by_id('email')
email.click();
email.clear();
email.send_keys('debanjan.selenium#gmail.com');
password = driver.find_element_by_id('password');
password.click();
password.clear();
password.send_keys('dev_anjan');
#Using Keys.ENTER
#password.send_keys(Keys.ENTER);
#Using Keys.RETURN
password.send_keys(Keys.RETURN);
#Using LogIn Button Click
#login_button = driver.find_element_by_id('btnLogin')
#login_button.click();
Let me know if this Answers your Question.
Please try this way, it's working for me:
email = driver.find_element_by_xpath('//*[#id="email"]')
email.send_keys('e#mail.com')
pwd = driver.find_element_by_xpath('//*[#id="password"]')
pwd.send_keys('pwd12345')
login_button = driver.find_element_by_xpath('//*[#id="btnLogin"]')
login_button.click()
Insted of pressing Enter on the password field you should do what a normal guy does and press the Log In button.

Python - Getting textboxes input data by Selenium

lastly I'm working about a Python project which uses the library "selenium". The project should type in passwords according to the usernames that it has got. My problem is that I don't know how to get data from a text box.
For example, if I want to use the project on "Facebook", at first I have to get the E-mail which the user typed in (kind of like putting it as a string variable), and then I have to type in the correct password (I know how to do that). My main problem is that the command " .text " doesn't work because the E-mail isn't found in any attribute of the textbox, so I can't call it.
Does someone have a solution please?
The current lines are :
driver = webdriver.Chrome('C:\\Users\User\Desktop\chromedriver.exe')
driver.get('https://www.facebook.com/stype=lo&jlou=AfdFutu6bihEQajPctMRwj2ySoaIGAE71YZ0aBZe9FYV4Xd2XuZ3SGth5wernWcF7s4pSvZH5W6f0ed2BfafHrkbupDcW4GDQECBTnhQID1FQ&smuh=4370&lh=Ac_eTqeC_DcDMq9f')
mail = driver.find_element_by_id('email').text
The problem is that the current "mail" variable is an empty string, because the E-mail textbox of Facebook's website is empty as it's waiting for the client to type in his E-mail. I'm trying to get the client's E-mail AFTER he typed it in.
Thanks in advance!
You can get value from input field simply as
email_input = driver.find_element_by_xpath('//input[#type="email"]')
print(email_input.get_attribute('value'))
Update
If you want to get text from input after user enter email:
driver = webdriver.Chrome('C:\\Users\User\Desktop\chromedriver.exe')
driver.get('https://www.facebook.com/stype=lo&jlou=AfdFutu6bihEQajPctMRwj2ySoaIGAE71YZ0aBZe9FYV4Xd2XuZ3SGth5wernWcF7s4pSvZH5W6f0ed2BfafHrkbupDcW4GDQECBTnhQID1FQ&smuh=4370&lh=Ac_eTqeC_DcDMq9f')
email = input("Please enter your Email: ")
email_input = driver.find_element_by_xpath('//input[#type="email"]')
email_input.send_keys(email)
print(email_input.get_attribute('value')) # or just print(email)
Note, that user should enter email value to command line, but not to browser input field

How to properly implement tkMessageBox in Python3.4?

I want to launch a warning using tkMessageBox in Python3. This warning is supposed to launch when a user doesn't select an element from a listbox. Unfortunately whenever I try to implement message box it does not launch like it is supposed to. I have code for a script called pietalkgui.py which contains the code where I want to implement the message box:
from tkinter import messagebox
# Gives warning if no user is selected for whisper
def whisperwarning(self):
# show warning to user
showwarning("Select User","Select a user to whisper to!")
# Handles whisper
def whispermessage(self):
# stores element selected in temp variable
temp = self.userslist.get(self.userslist.curselection())
# if no item is selected from userslist (listbox)
if temp == "":
# launch warning to user if no item is selected
self.whisperwarning()
else:
# retrieves usernames from userslist
username = temp
# storing whisper
outwhisper = ' /w "' + username +'" ' + self.messagebox.get("0.0",END)
# handling whisper
self.handler(outwhisper)
# erase message in message box
self.messagebox.delete("0.0",END)
Am I doing something wrong in the implementation of tkMessageBox? Or am I not properly checking if not item is selected from the listbox?
It appears that you are calling the method showwarning, but haven't defined it or imported it. That is the name of a function the messagebox module, so perhaps you need to change this:
showwarning("Select User","Select a user to whisper to!")
... to this:
messagebox.showwarning("Select User","Select a user to whisper to!")
Also, FWIW, this code is slightly incorrect: self.messagebox.delete("0.0",END) -- text indices start at "1.0", not "0.0".

Categories

Resources