Appium & Python: How to move to another app? - python-3.x

I am making a testing bot with Python and Appium.
I need to extract the email of a button. I tired to extract href, but button are obviously something else than in smartphone applications.
So I click on this button which open my gmail with the New message window and the email in the "To" field.
SO I investigate and I could find only 1 tutoriel in Java :-(.
I found something else. SOmeone propose to instantiate new driver:
driver2 = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps2)
print("we setup driver2")
email = driver2.find_element_by_id("com.google.android.gm:id/to").text
But it stop immediately the browser. ANd Pycharm displayed this error:
Error Traceback (most recent call last): File
"C:\Users\Nino\AppData\Local\Programs\Python\Python37\lib\unittest\case.py",
line 59, in testPartExecutor
yield File "C:\Users\Nino\AppData\Local\Programs\Python\Python37\lib\unittest\case.py",
line 628, in run
testMethod() File "C:\Users\Nino\PycharmProjects\mybot\mybot_mybot.py", line 92, in
test_scrap_email
email = driver2.find_element_by_id("com.google.android.gm:id/to").text File
"C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_) File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\appium\webdriver\webdriver.py",
line 276, in find_element
'value': value})['value'] File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 321, in execute
self.error_handler.check_response(response) File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\appium\webdriver\errorhandler.py",
line 29, in check_response
raise wde File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\appium\webdriver\errorhandler.py",
line 24, in check_response
super(MobileErrorHandler, self).check_response(response) File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py",
line 242, in check_response
raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: An element
could not be located on the page using the given search parameters.
I am using unittest which instantiate one driver going to 1 app (where there si the email button), then I instantiate in the middle of the code a new driver.
But it bugs. And Icannot find anywhere an article or forum question about switching from 1 app to other app.
I prefer to let you te code of my bot:
from datetime import time
from time import sleep
from appium import webdriver
import unittest
from selenium.webdriver.common.by import By
class apptotest1(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName']='Android'
desired_caps['platformVersion']='6.0'
desired_caps['deviceName']='S6S5IN3G'
desired_caps['noReset']='true'
desired_caps['appPackage']='com.apptotest1'
desired_caps['appActivity']=' com.apptotest1.android/com.apptotest1.android.activity.MainTabActivity'
self.driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
#self.driver = webdriver.Remote('http://0.0.0.0:4723/wd/hub',desired_caps)
def tearDown(self):
self.driver.quit()
def test_scrap_email(self):
search_button = self.driver.find_element(By.XPATH,"//android.widget.ImageView[#bounds='[126,800][162,836]']")
#search_button = self.driver.find_element(By.XPATH ("//android.widget.ImageView[#content-desc='Rechercher et explorer']"))
if search_button:
print("search_button was found!")
search_button.click()
else:
print("search_button was not found :-(")
search_field = self.driver.find_element_by_id('com.apptotest1.android:id/action_bar_search_edit_text')
search_field.send_keys('marketing')
users_button = self.driver.find_element_by_id('com.apptotest1.android:id/tab_button_fallback_icon')
if users_button:
print("users_button was found!")
users_button.click()
else:
print("users_button was not found :-(")
users_button2 = self.driver.find_element(By.XPATH, "//android.widget.ImageView[#bounds='[162,123][198,159]']")
if users_button2:
print("users_button2 was found!")
users_button2.click()
else:
print("users_button2 was not found :-(")
sleep(5)
profile_test = self.driver.find_elements_by_id("com.apptotest1.android:id/row_search_user_username")[1]
if profile_test:
print("profile_test was found!")
profile_test.click()
else:
print("profile_test was not found :-(")
sleep(5)
button_email = self.driver.find_element(By.XPATH,"//android.widget.TextView[#text='Adresse e-mail']")
if button_email:
print("button_email was found!")
button_text = button_email.text
print("button_text is :" + str(button_text))
button_email.click()
else:
print("button_email was not found :-(")
desired_caps2 = {}
desired_caps2['platformName'] = 'Android'
desired_caps2['platformVersion'] = '6.0'
desired_caps2['deviceName'] = 'S6S5IN3G'
desired_caps2['noReset'] = 'true'
desired_caps2['appPackage'] = 'com.google.android.gm'
desired_caps2['appActivity'] = ' com.google.android.gm.ComposeActivityGmailExternal'
driver2 = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps2)
print("we setup driver2")
email = driver2.find_element_by_id("com.google.android.gm:id/to").text
sleep(10)
if email:
print("email was found!")
print("Es eso que querias :-) =>" + str(email))
else:
print("Email was not found :-(")
sleep(5)
if __name__ == '__main__':
suite = unittest.Testloader().loadTestsFromTestCase(apptotest1)
unittest.TextTestRunner(verbosity=1).run(suite)
Does anyone can help me please?

It looks like you're looking for start_activity function
The driver.start_activity method opens arbitrary activities on a device. If the activity is not part of the application under test, it will also launch the activity's application.
driver.start_activity('com.foo.app', '.MyActivity')
This way you should be able to switch between applications within the bounds of the same webdriver instance
You might also find Launch command useful as it is cross-platform approach allowing kicking off any installed application. The command is available via SeeTest Appium Extension.

It seems like you just need switch context, you facing web in gmail, try :
driver2 = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps2)
print("we setup driver2")
driver2.switch_to.context('WEBVIEW_1')
email = driver2.find_element_by_id("com.google.android.gm:id/to").text
Or
# switch to webview
webview = driver.contexts.last
driver.switch_to.context(webview)
And please try without new initilize driver2
Please read this reference and this.

Related

Invisible intercepting element

I am trying to browse the chefsteps account (this one worked) and click the chefsteps account in my instagram account (the clicking part does not work). But I got "Element Click Intercepted Exception". There is no visible dialog box, but the 'chefsteps' button (element click) is intercepted. What should I do to fix this?
Traceback (most recent call last):
File "C:\Users\DELL\PycharmProjects\Day52_instagram_followers_bot\main.py", line 65, in <module>
bot.find_followers()
File "C:\Users\DELL\PycharmProjects\Day52_instagram_followers_bot\main.py", line 38, in find_followers
chefsteps.click()
File "C:\Users\DELL\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
self._execute(Command.CLICK_ELEMENT)
File "C:\Users\DELL\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "C:\Users\DELL\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\DELL\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <div class="_3SOD">...</div> is not clickable at point (207, 135). Other element would receive the click: <div class="jLwSh" role="dialog"></div>
(Session info: chrome=94.0.4606.81)
import selenium.common.exceptions
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import os
from time import sleep
CHROME_DRIVER_PATH ="C:\Development\chromedriver_win32\chromedriver.exe"
SIMILAR_ACCOUNT = "chefsteps"
INSTAGRAM_EMAIL = os.environ['YOUR_INSTAGRAM_EMAIL']
INSTAGRAM_PASSWORD = os.environ['YOUR_INSTAGRAM_PASSWORD']
class InstaFollower:
def __init__(self):
self.driver = webdriver.Chrome(executable_path=CHROME_DRIVER_PATH)
def login(self):
self.driver.get('https://www.instagram.com/')
sleep(3)
email = self.driver.find_element_by_name('username')
email.send_keys(INSTAGRAM_EMAIL)
password = self.driver.find_element_by_name('password')
password.send_keys(INSTAGRAM_PASSWORD)
password.send_keys(Keys.ENTER)
pass
def find_followers(self):
sleep(3)
notif = self.driver.find_element_by_xpath('/html/body/div[5]/div/div/div/div[3]/button[2]')
notif.click()
browser = self.driver.find_element_by_class_name("x3qfX")
browser.send_keys(SIMILAR_ACCOUNT)
sleep(7)
try:
chefsteps = self.driver.find_element_by_class_name('uL8Hv')
chefsteps.click()
except selenium.common.exceptions.ElementClickInterceptedException:
chefsteps = self.driver.find_element_by_css_selector('._4EzTm div')
chefsteps.click()
def follow(self):
sleep(7)
followers_button = self.driver.find_element_by_class_name('-nal3')
followers_button.click()
sleep(5)
number_of_followers = int(followers_button.get_attribute("title").replace(",", ""))
print(number_of_followers)
n = 1
while n < number_of_followers:
try:
follow_buttons = self.driver.find_elements_by_class_name("y3zKF")
for i in follow_buttons:
sleep(1)
i.click()
except selenium.common.exceptions.ElementClickInterceptedException:
cancel = self.driver.find_element_by_class_name("HoLwm")
cancel.click()
continue
bot = InstaFollower()
bot.login()
bot.find_followers()
bot.follow()
Try like below:
1: Not sure where the button appears, If the Element appears after Scrolling:
chefsteps = self.driver.find_element_by_class_name('uL8Hv')
self.driver.execute_script("arguments[0].scrollIntoView(true);",chefsteps)
chefsteps.click()
2: Can use ActionsChains:
from selenium.webdriver import ActionChains
chefsteps = self.driver.find_element_by_class_name('uL8Hv')
actions = ActionChains(self.driver)
actions.move_to_element(chefsteps).click().perform()
3: Use Javascript:
chefsteps = self.driver.find_element_by_class_name('uL8Hv')
self.driver.execute_script("arguments[0].click();",chefsteps)
If none of the above methods work, check if the Element is in an Iframe or shadow-root. And also check for the locator you are using, It should be unique in the DOM that is 1/1.

How to wait for a text field to be editable with selenium in python 3.8

I am just making a selenium bot as a fun project that is supposed to play typeracer for me, and I am having a bit of trouble getting it to wait for the countdown to be done before it tries to start typing. The best way that I have found to do this is to just wait for the text input field to be editable instead of waiting for the countdown popup to be gone, but as I said before, I can't get it to wait unless I use a time.sleep() function. This wouldn't work well because of the fact that we could have to wait for anywhere from 5ish-12ish seconds before the bot can start so it could wait too long or not long enough. I have tried the solutions from many other similar questions such as this one, but so far nothing has worked.
Here is my code at the moment:
#!/usr/bin/env/python3
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class TRBot:
def __init__(self, username, passwd):
self.username = username
self.driver = webdriver.Safari()
self.driver.get("https://play.typeracer.com") # Open automated safari to typeracer
time.sleep(2)
self.driver.find_element_by_xpath("//a[#title=\"Keyboard shortcut: Ctrl+Alt+I\"]").click() # Click the "Enter a typing race" button
time.sleep(2)
inputField = WebDriverWait(self.driver, 10).until(EC.visibility_of((By.XPATH, "<div contenteditable=\"plaintext-only\"></div>")))
# Find the first word of the passage to type
text = self.driver.find_element_by_xpath("//*[#id=\"gwt - uid - 15\"]/table/tbody/tr[2]/td/table/tbody/tr[1]/td/table/tbody/tr[1]/td/div/div/span[1]").get_attribute("innerHTML")
while text != "":
inputField.send_keys(text) # Type the word
text = self.driver.find_element_by_xpath("//*[#id=\"gwt - uid - 15\"]/table/tbody/tr[2]/td/table/tbody/tr[1]/td/table/tbody/tr[1]/td/div/div/span[1]").get_attribute("innerHTML") # Find the next word
time.sleep(5)
self.driver.quit()
TypeRacerBot = TRBot("TRBot", "R0b0t#")
and here is the error output:
Traceback (most recent call last):
File "/Users/myuser/Documents/Programming/Python/TypeRacerBot.py", line 45, in <module>
TypeRacerBot = TRBot("TRBot", "R0b0t#")
File "/Users/myuser/Documents/Programming/Python/TypeRacerBot.py", line 29, in __init__
inputField = WebDriverWait(self.driver, 10).until(EC.visibility_of((By.XPATH, "<div contenteditable=\"plaintext-only\">\*</div>")))
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/support/wait.py", line 71, in until
value = method(self._driver)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/support/expected_conditions.py", line 144, in __call__
return _element_if_visible(self.element)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/support/expected_conditions.py", line 148, in _element_if_visible
return element if element.is_displayed() == visibility else False
AttributeError: 'tuple' object has no attribute 'is_displayed'
Right now, everything works as expected up to the inputField = WebDriverWait(... line so that's what I'm currently focused on fixing, but if you see anything that won't work further along in the code I am open to suggestions there too.
Thanks in advance!
You need to replace the line:
inputField = WebDriverWait(self.driver, 10).until(EC.visibility_of((By.XPATH, "<div contenteditable=\"plaintext-only\"></div>")))
with:
inputField = WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element_by_xpath("//div[#contenteditable='plaintext-only']")))
or:
inputField = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//div[#contenteditable='plaintext-only']")))

selenium.common.exceptions.NoSuchElementException: Message: no such element error using ChromeDriver and Chrome through Selenium and Python

I am creating a bot to register accounts on instagram and when I run my selenium script locally (Mac OS) , it works perfectly while when I run in on Ubuntu 18.4 on Azure Cloud , it fails localting selectors so practically I have tried everything from changing xpath to ID and so on.
from selenium import webdriver
from random import randint
import time
from selenium.webdriver.common.by import By
import accountInfoGenerator as account
from webdriver_manager.chrome import ChromeDriverManager
import random
import string
import os,sys
from selenium.webdriver.common.action_chains import ActionChains
from pyvirtualdisplay import Display
#!/usr/bin/env python
error = 'null'
##generator for random letters
def guess_letter():
return random.choice('abcdefghijklmnopqrstuvwxyz')
##generator for random letters
def guess_number():
return random.choice('1234567890')
#chooses PROXY AFTER EACH OTHER
def randomproxy():
file = open("./proxy.txt")
for line in file:
fields = line.split(";")
return random.choice(fields)
def insta():
print("We are now using this proxy:" + randomproxy())
while True:
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--proxy-server=%s' % randomproxy())
# #hrome_option.add_argument('--headless') ,service_args=['--verbose', '--log-path=/tmp/chromedriver.log']
display = Display(visible=0, size=(1024, 768))
display.start()
browser = webdriver.Chrome("./chromedriver",options=chrome_option)
action_chains = ActionChains(browser)
##checks if theres internet
def has_connection(browser):
try:
browser.find_element_by_xpath('//span[#jsselect="heading" and #jsvalues=".innerHTML:msg"]')
return False
except: return True
browser.get("http://www.instagram.com")
#if no internet then restart progras
if not has_connection(browser):
print('No Internet connection, aborted!')
browser.quit()
os.execv(sys.executable, ['python'] + sys.argv)
time.sleep(5) #time.sleep count can be changed depending on the Internet speed.
name = account.username()
#Fill the email value
email_field = browser.find_element_by_name('emailOrPhone')
action_chains.move_to_element(email_field)
email_field.send_keys(account.generatingEmail())
time.sleep(3)
print("We registered with email "+account.generatingEmail())
#Fill the fullname value
fullname_field = browser.find_element_by_name('fullName')
action_chains.move_to_element(fullname_field)
fullname_field.send_keys(account.generatingName())
time.sleep(3)
print("We registered with name" + account.generatingName())
#Fill username value
username_field = browser.find_element_by_name('username')
name2 = (name + guess_letter() + guess_number())
action_chains.move_to_element(username_field)
time.sleep(3)
username_field.send_keys(name2)
print("We registered using this username" + name2 )
#Fill password value
password_field = browser.find_element_by_name('password')
action_chains.move_to_element(password_field)
time.sleep(3)
password_field.send_keys('aa12345bb12345cc'+name) #You can determine another password here.
##clicks button and checks if button was clicked due to lags
time.sleep(6)
button = browser.find_element_by_xpath('//div[7]/div/button')
action_chains.move_to_element(button)
button.submit()
time.sleep(6)
age_button = browser.find_element_by_id('igCoreRadioButtonageRadioabove_18')
action_chains.move_to_element(age_button)
age_button.click()
time.sleep(3)
next = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div/button')
next.click()
time.sleep(10)
print('Registering....')
##checks if error
def has_error(browser):
try:
browser.find_element_by_class_name('Ma93n')
return False
except: return True
#if error then restart
if not has_error(browser):
print('Error found! , aborted!')
browser.quit()
os.execv(sys.executable, ['python'] + sys.argv)
#if sucessfully created and connection is alive then save credentials
if has_error(browser):
f = open('../instabot/examples/secret.txt','a')
f.write( name + ':' + ('aa12345bb12345cc'+name) )
f.close()
print("Sucessfully saved")
time.sleep(10)
browser.close()
flag = True
while flag:
insta()
This is the output from ssh console
samih#app:~/instabotauto/autoaccount$ python botAccountCreate.py
We are now using this proxy:p.webshare.io:20192
We registered with email ytbygt#seznam.cz
We registered with nameBrandyn Ayana
We registered using this username.v.jkij2
Traceback (most recent call last):
File "botAccountCreate.py", line 129, in <module>
insta()
File "botAccountCreate.py", line 94, in insta
age_button = browser.find_element_by_id('igCoreRadioButtonageRadioabove_18')
File "/home/samih/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "/home/samih/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element
'value': value})['value']
File "/home/samih/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/home/samih/.local/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element:{"method":"id","selector":"igCoreRadioButtonageRadioabove_18"}
(Session info: chrome=73.0.3683.86)
(Driver info: chromedriver=2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881),platform=Linux 4.18.0-1014-azure x86_64)
What the program should is that it creates users and stores them in .txt file that is used by other program to log in to Instagram.
while on mac the console run without errors.
Checking for mac64 chromedriver:74.0.3729.6 in cache
Driver found in /Users/samihassan/.wdm/chromedriver/74.0.3729.6/mac64/chromedriver
We registered with email .skosr#seznam.cz
We registered with nameButali Zengin
We registered using this usernamefdzzicz2
Registering....
Checking for mac64 chromedriver:74.0.3729.6 in cache
Driver found in /Users/samihassan/.wdm/chromedriver/74.0.3729.6/mac64/chromedriver
This error message...
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element:{"method":"id","selector":"igCoreRadioButtonageRadioabove_18"}
(Session info: chrome=73.0.3683.86)
(Driver info: chromedriver=2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881),platform=Linux 4.18.0-1014-azure x86_64)
...implies that the ChromeDriver was unable to locate the desired element and NoSuchElementException was raised.
You can find a detailed discussion on NoSuchElementException in Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome
However your main issue is the incompatibility between the version of the binaries you are using as follows:
You are using chromedriver=2.35
Release Notes of chromedriver=2.35 clearly mentions the following :
Supports Chrome v62-64
You are using chrome=73.0
Release Notes of ChromeDriver v2.46 clearly mentions the following :
Supports Chrome v71-73
So there is a clear mismatch between the ChromeDriver v2.35 and the Chrome Browser v73.0
Solution
Upgrade ChromeDriver to current ChromeDriver v2.46 level.
Keep Chrome version between Chrome v71-73 levels. (as per ChromeDriver v2.46 release notes)
You can find a relevant discussion in selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium

Discord bot.py file unable to load extensions [discord.py rewrite]

I've run into an issue with switching to the rewrite of discord.py. On extension loading I'm running into an ExtensionNotFound error.
I've tried different methods to get the extension to be recognized (such as using the entire directory in the code to find the folder containing cogs). Unfortunately all methods I've tried have resulted in the same ExtensionNotFound error.
Methods I've tried:
STARTUP = ['cogsR.basic_repliesR']
cogs_dir = r'D:\Code-Dev\Pyhthon\DiscordStuff\Bots\ri0tbot\ri0t-bot_current_v(rewrite)\cogsR'
if __name__ == '__main__':
for extension in [f.replace('.py', '') for f in listdir(cogs_dir) if isfile(join(cogs_dir, f))]:
try:
bot.load_extension(cogs_dir + "." + extension)
except (d.ClientException, ModuleNotFoundError):
print(f'Failed to load extension {extension}.')
traceback.print_exc()
STARTUP = ['cogR.basic_repliesR']
if __name__ == '__main__':
sys.path.insert(1, os.getcwd() + '/cogsR/')
for extension in STARTUP:
try:
bot.load_extension(extension)
except (AttributeError, ImportError) as e:
exc = '{}: {}'.format(type(e).__name__, e)
cprint('extension error {}\n{}'.format(extension, exc), 'red')
Through either of these methods the bot.py file should have been able to load the extensions in the STARTUP library. Instead I'm met with the following error message on file run.
Exception has occurred: ExtensionNotFound
Extension 'cogsR.basic_repliesR' could not be loaded.
File "C:\Users\edmun\AppData\Local\Programs\Python\Python36\Lib\site-packages\discord\ext\commands\bot.py", line 620, in load_extension
raise errors.ExtensionNotFound(name, e) from e
File "D:\Code-Dev\Pyhthon\discordstuff\Bots\ri0tbot\ri0t-bot_current_v(rewrite)\botR.py", line 50, in <module>
bot.load_extension(extension)
File "C:\Users\edmun\AppData\Local\Programs\Python\Python36\Lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\edmun\AppData\Local\Programs\Python\Python36\Lib\runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "C:\Users\edmun\AppData\Local\Programs\Python\Python36\Lib\runpy.py", line 263, in run_path
pkg_name=pkg_name, script_name=fname)
'''cog: commands using a list for randomly chosen replies'''
from random import choice
import asyncio
import os
import discord as d
from discord.ext import commands
from discord.ext.commands.cooldowns import BucketType
from utilitiesR import lists
class ListCommands(commands.Cog):
def __init__(self, bot, **kwargs):
self.bot = bot
self.name = kwargs.get('username')
#commands.command(pass_context=True)
async def rip(self, ctx):
'''a basic rip command'''
#await ctx.send_typing()
#await asyncio.sleep(0.3)
_choice = choice(lists.RIP)
await ctx.send(_choice)
def setup(bot):
'''cog setup'''
bot.add_cog(ListCommands(bot))
print('list commands ready')
Try This.
if __name__ == '__main__':
for cog in os.listdir("./cogsR"):
if cog.endswith(".py"):
try:
cog = f"cogs.{cog.replace('.py', '')}"
bot.load_extension(cog)
except Exception as e:
print(f"{cog} Can not be loaded")
raise e
else:
print("{} has been succesfully Loaded.".format(cog))

Logging in as user using discord.py

I am trying to make some simple program, showing received messages through the terminal. Now I am trying to ask the user for their email address and password for the login, but some errors occur, which I do not quite understand. This is what my code looks like:
import discord
class DiscordClient(discord.Client):
def __init__(self, *args, **kwargs):
discord.Client.__init__(self, **kwargs)
async def on_ready(self):
print('Success!')
if __name__ == '__main__':
dc = DiscordClient()
dc.login(input('email : '), input('password : '), bot=False)
dc.run()
and the error is:
Traceback (most recent call last):
File "[...]/Main.py", line 16, in <module>
dc.run()
File "[...]/lib/python3.6/site-packages/discord/client.py", line 519, in run
self.loop.run_until_complete(self.start(*args, **kwargs))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 466, in run_until_complete
return future.result()
File "[...]/lib/python3.6/site-packages/discord/client.py", line 490, in start
yield from self.login(*args, **kwargs)
File "[...]/lib/python3.6/site-packages/discord/client.py", line 418, in login
raise TypeError('login() takes 1 or 2 positional arguments but {} were given'.format(n))
TypeError: login() takes 1 or 2 positional arguments but 0 were given
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x103881fd0>
So, what am I doing wrong, or what should code look like? All I was doing was write an on_message() and some basic commands like send_message().
client.login is a coroutine so it should be (untested) :
await dc.login(input('email : '), input('password : '), bot=False)
Note that in this case, bot parameter is not needed.
However, to use client.login, you need to use the client loop. To avoid that, you can simply do:
dc.run(email, password)
Which will both login and connect and then start the loop.
After that you can (in the on_ready function) get a desired server from dc.servers and a suitable channel to send there, for example, a 'Hello message' with dc.send_message.
When you are done with the connection, do self.close() from within the DiscordClient class.
Working example for Python 3.4 (replace keywords as necessary for Python 3.6)
import discord
import asyncio
import datetime
class DiscordClient(discord.Client):
def __init__(self, *args, **kwargs):
discord.Client.__init__(self, **kwargs)
#asyncio.coroutine
def on_ready(self):
servers = list(self.servers)
for server in servers:
if server.name == 'My server':
break
for channel in server.channels:
if channel.name == 'general':
break
now = datetime.datetime.now()
yield from self.send_message(channel, 'Api Success! at ' + str(now))
print('Success!')
yield from self.close()
if __name__ == '__main__':
dc = DiscordClient()
email = input('email : ')
password = input('password : ')
dc.run(email, password)

Resources