SHUR1K-N / MeetNinja-Google-Meet-Bot

A super dope tool that attends your Google Meet(s) for you. Flawlessly handles scheduled multiple (subsequent) Meet sessions. Also disables the camera & microphone, and shows timestamps of joining & ending times for each Meet. Supported: Google Chrome / Mozilla Firefox running on Linux / Mac / Windows
https://TheComputerNoob.com
71 stars 10 forks source link

Changes a few things up but it doesn't work anymore #19

Closed denppa closed 3 years ago

denppa commented 3 years ago

Hello Shuriken,

So I tried to add the function of:

Clicking Meet link Launch chrome with default profile

But the code is failing me right now:

#!/usr/bin/env python3

from selenium import webdriver; import requests
from selenium.webdriver.support import expected_conditions as when
from selenium.webdriver.common.by import By as by
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.keys import Keys
import pause; import os; import re
import time; from datetime import datetime
import colorama; from termcolor import colored

colorama.init()

###################################################################
#                        Meets                           HH:MM:SS DD/MM/YYYY
MEETS = {"1 https://classroom.google.com/u/3/c/": "21:00:00 24/02/2021",
         #"2 https://meet.google.com/": "08:29:45 05/02/2021",
         #"3 https://meet.google.com/lookup/": "09:14:50 05/02/2021",
         #"4 https://meet.google.com/": "09:59:50 05/02/2021",
         #"5 https://meet.google.com/": "10:43:00 05/02/2021",
         #"6 https://meet.google.com/": "11:29:00 05/02/2021",
         #"7 https://meet.google.com/": "12:59:00 05/02/2021",
         #"8 https://meet.google.com/": "13:44:00 05/02/2021",
         # Add more Meet URLs (if any) using the same format as above
         }

DURATION = 40 # Duration of each Meet in minutes
USERNAME = 
PASSWORD = 

BROWSER_DRIVER = "ChromeDrivers/linux64/chromedriver"

#                   Google Chrome
#           Linux: "ChromeDrivers/linux64/chromedriver"
#             Mac: "ChromeDrivers/mac64/chromedriver"
#        Mac (M1): "ChromeDrivers/mac64_m1/chromedriver"
#         Windows: "ChromeDrivers/win32/chromedriver.exe"

#                   Mozilla Firefox
#     Linux (x32): "FirefoxDrivers/linux32/geckodriver"
#     Linux (x64): "FirefoxDrivers/linux64/geckodriver"
#             Mac: "FirefoxDrivers/mac64/geckodriver"
#   Windows (x32): "FirefoxDrivers/win32/geckodriver.exe"
#   Windows (x64): "FirefoxDrivers/win64/geckodriver.exe"
##################################################################

# All required interactive elements' locators (text fields, buttons, etc.)
usernameFieldPath = "identifierId"
usernameNextButtonPath = "identifierNext"
passwordFieldPath = "password"
passwordNextButtonPath = "passwordNext"
linkButton1Path = "//*[contains(text(), 'meet.google.com')]"
linkButton2Path = "//*[contains(text(), 'meet.google.com')]"
joinButton1Path = "//span[contains(text(), 'Join')]"
joinButton2Path = "//span[contains(text(), 'Ask to join')]"
endButtonPath = "[aria-label='Leave call']"

currentVersionNumber = "v3.1.1"
VERSION_CHECK_URL = "https://raw.githubusercontent.com/SHUR1K-N/MeetNinja-Google-Meet-Bot/master/versionfile.txt"
BANNER1 = colored('''
   ███▄ ▄███▓▓█████ ▓█████▄▄▄█████▓ ███▄    █  ██▓ ███▄    █  ▄▄▄██▀▀▀▄▄▄
  ▓██▒▀█▀ ██▒▓█   ▀ ▓█   ▀▓  ██▒ ▓▒ ██ ▀█   █ ▓██▒ ██ ▀█   █    ▒██  ▒████▄
  ▓██    ▓██░▒███   ▒███  ▒ ▓██░ ▒░▓██  ▀█ ██▒▒██▒▓██  ▀█ ██▒   ░██  ▒██  ▀█▄
  ▒██    ▒██ ▒▓█  ▄ ▒▓█  ▄░ ▓██▓ ░ ▓██▒  ▐▌██▒░██░▓██▒  ▐▌██▒▓██▄██▓ ░██▄▄▄▄██
  ▒██▒   ░██▒░▒████▒░▒████▒ ▒██▒ ░ ▒██░   ▓██░░██░▒██░   ▓██░ ▓███▒   ▓█   ▓██▒
  ░ ▒░   ░  ░░░ ▒░ ░░░ ▒░ ░ ▒ ░░   ░ ▒░   ▒ ▒ ░▓  ░ ▒░   ▒ ▒  ▒▓▒▒░   ▒▒   ▓▒█░
  ░  ░      ░ ░ ░  ░ ░ ░  ░   ░    ░ ░░   ░ ▒░ ▒ ░░ ░░   ░ ▒░ ▒ ░▒░    ▒   ▒▒ ░
  ░      ░      ░      ░    ░         ░   ░ ░  ▒ ░   ░   ░ ░  ░ ░ ░    ░   ▒
         ░      ░  ░   ░  ░                 ░  ░           ░  ░   ░        ░  ░''', 'blue')
BANNER2 = colored('''                    ------------------------------------''', 'blue')
BANNER3 = colored('''                    || MeetNinja: The Google Meet Bot ||''', 'red')
BANNER4 = colored('''                    ------------------------------------''', 'blue')

def printBanner():
    print(BANNER1), print(BANNER2), print(BANNER3), print(BANNER4)

def versionCheck():
    global currentVersionNumber

    print("\nChecking for MeetNinja updates...", end="")

    crawlVersionFile = requests.get(VERSION_CHECK_URL)
    crawlVersionFile = str(crawlVersionFile.content)
    crawlVersionFile = re.findall(r"([0-9]+)", crawlVersionFile)
    latestVersionNumber = int(''.join(crawlVersionFile))

    currentVersionNumber = re.findall(r"([0-9]+)", currentVersionNumber)
    currentVersionNumber = int(''.join(currentVersionNumber))

    if currentVersionNumber >= latestVersionNumber:
        print(colored(" You are using the latest version!\n", "green"))
    elif currentVersionNumber < latestVersionNumber:
        print(colored(" You are using an older version of MeetNinja.", "red"))
        print(colored("\nGet the latest version at https://github.com/SHUR1K-N/MeetNinja-Google-Meet-Bot", "yellow"))
        print(colored("Every new version comes with fixes, improvements, new features, etc..", "yellow"))
        print(colored("Please do not open an Issue if you see this message and have not yet tried the latest version.", "yellow"))

def fixTimeFormat(rawTime):
    rawTime = list(rawTime.split())
    times = list(map(int, rawTime[0].split(":")))
    dates = list(map(int, reversed(rawTime[1].split("/"))))
    startTime = dates + times
    return startTime

def timeStamp():
    timeNow = str(datetime.now())
    timeRegEx = re.findall(r"([0-9]+:[0-9]+:[0-9]+)", timeNow)
    return(timeRegEx[0])

def initBrowser():
    print("\nInitializing browser...", end="")
    if BROWSER_DRIVER.lower().startswith("chrome"):
        chromeOptions = webdriver.ChromeOptions()
        options = webdriver.ChromeOptions()
        options.add_argument("user-data-dir=/home/user/.config/chromium/Default")
    #w = webdriver.Chrome(executable_path="/usr/lib/chromium/chromium", chrome_options=options)

    driver = webdriver.Chrome(executable_path=BROWSER_DRIVER, options=chromeOptions)

def attendMeet():
    print(f"\n\nNavigating to Google Meet #{meetIndex}...", end="")
    driver.get(URL[2:])
    print(colored(" Success!", "green"))
    print(f"Entering Google Meet #{meetIndex}...", end="")

    try:
        linkButton = wait.until(when.element_to_be_clickable((by.XPATH, linkButton1Path)))
    except:
        linkButton = wait.until(when.element_to_be_clickable((by.XPATH, linkButton2Path)))
    try:
        joinButton = wait.until(when.element_to_be_clickable((by.XPATH, joinButton1Path)))
    except:
        joinButton = wait.until(when.element_to_be_clickable((by.XPATH, joinButton2Path)))
    if BROWSER_DRIVER.lower().startswith("chrome"):
        time.sleep(1)
        action.send_keys(Keys.ESCAPE).perform()
    time.sleep(1)
    linkButton.click()
    joinButton.click()

    print(colored(" Success!", "green"))
    time.sleep(1)
    print(colored(f"Now attending Google Meet #{meetIndex} @{timeStamp()}", "green"), end="")

    try:
        joinButton = wait.until(when.element_to_be_clickable((by.XPATH, joinButton1Path)))   # For another prompt that pops up for Meets being recorded
        time.sleep(1)
        joinButton.click()
    except:
        pass

def endMeet():
    endButton = driver.find_element_by_css_selector(endButtonPath)
    endButton.click()
    print(colored(f"\nSuccessfully ended Google Meet #{meetIndex} @{timeStamp()}\n", "red"), end="")

def genericError():
    # clrscr()
    print(colored(" Failed!", "red"), end="")
    print("\n\nPossible fixes:\n")
    print("1.1 Make sure you have downloaded the latest version of MeetNinja from the GitHub page (every new iteration brings fixes and new capabilities)")
    print("1.2 Make sure you have pip-installed all the required python packages mentioned in the README")
    print("2.1 Check your inputs and run MeetNinja again (make sure there are no leading zeros in the Meet start times)")
    print("2.2 And / Or make sure you have chosen the correct webdriver file respective of your web browser and operating system")
    print("3. Make sure the generated web browser is not \"Minimized\" while MeetNinja is working")
    print("4.1. Make sure the webdriver file is of the latest stable build (https://chromedriver.chromium.org/ or https://github.com/mozilla/geckodriver/releases)")
    print("4.2. And / Or make sure your chosen web browser is updated to the latest version")
    print("4.3. And / Or make sure the webdriver file is at least of the same version as your chosen web browser (or lower)")
    print("5. Make sure the small \"time.sleep()\" delays (in seconds) in the login() and attendMeet() functions are comfortable for your internet speed")
    print("6. Make sure your internet connection is stable throughout the process")
    print("\nPress Enter to exit.")
    input()
    try:
        driver.quit()
    except:
        pass

def clrscr():
    if os.name == 'posix':
        _ = os.system('clear')
    else:
        _ = os.system('cls')
    printBanner()

def hibernate():
    print("\nHibernating in 10 seconds. Press Ctrl + C to abort.")
    time.sleep(13)
    _ = os.system('shutdown /h /f')

############### Main ###############

if __name__ == "__main__":

    printBanner()

    versionCheck()

    try:
        DURATION *= 60
        driver = initBrowser()
        wait = webdriver.support.ui.WebDriverWait(driver, 7)
        action = ActionChains(driver)
        for meetIndex, (URL, rawTime) in enumerate(MEETS.items(), start=1):
            startTime = fixTimeFormat(rawTime)
            if (meetIndex <= 1):
                print(colored(f"Waiting until first Meet start time [{rawTime}]...", "yellow"), end="")
            else:
                print(colored(f"\n\nWaiting until next Meet start time [{rawTime}]...", "yellow"), end="")
            pause.until(datetime(*startTime))
            print(colored(" Started!", "green"))

            attendMeet()
            time.sleep(DURATION)
            endMeet()
        print("\n\nAll Meets completed successfully.")
        # hibernate()
        # Uncomment above to hibernate after a 10 second countdown upon completion of all Meets (Ctrl + C to abort hibernation)
        print("Press Enter to exit.")
        input()
        print("\nCleaning up and exiting...", end="")
        driver.quit()

    except KeyboardInterrupt:
        # clrscr()
        print("\n\nCTRL ^C\n\nThrew a wrench in the works.")
        print("Press Enter to exit.")
        input()
        print("\nCleaning up and exiting...", end="")
        driver.quit()
    except:
        print(e)
        # Uncomment above to display error traceback (use when reporting issues)
        genericError()

Error on bash:

Checking for MeetNinja updates... You are using the latest version!

Initializing browser...Traceback (most recent call last):
  File "/home/user/git/MeetNinja-Google-Meet-Bot/MeetNinja.py", line 217, in <module>
    action = ActionChains(driver)
  File "/home/user/.local/lib/python3.9/site-packages/selenium/webdriver/common/action_chains.py", line 72, in __init__
    if self._driver.w3c:
AttributeError: 'NoneType' object has no attribute 'w3c'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/git/MeetNinja-Google-Meet-Bot/MeetNinja.py", line 246, in <module>
    print(e)
NameError: name 'e' is not defined

Please let me know if you have any idea to improve this!

SHUR1K-N commented 3 years ago

Since these are custom implementations that you are trying, they are not Issues. Kindly, raise your question(s) on a platform such as Stack Overflow, with only the specific modules/functions of the program that need to be checked.

Please note that you will have to be very specific with your queries in such forums. For example, you mentioned you added two functions, but there are no added function definitions as far as I can see in the program. If you intended to mean "features", that is a different thing and you are supposed to highlight where you have added them instead of sending someone the entire 200+ line program so they have to search for the 1–2 lines you mean to ask about.