bot: first complete commit with task scheduling

main
EmaMaker 2021-02-05 21:01:10 +01:00
parent 274aa63778
commit 0f606ccf5d
6 changed files with 287 additions and 0 deletions

View File

@ -1,2 +1,18 @@
# GoogleMeetBot
A bot to automatically join Google Meet meetings at the correct time
## How it works
The bot automates a FireFox session using Python and Selenium.<br>
It joins the programmed google meetings automatically, with microphone and webcam disabled.<br>
It uses the **schedule** python module to automatically access and close meetings at the given time, it can only join one meeting at the time<br>
Normally Google Accounts are not allowed to be logged in when using an automated browser, but logging in via stackoverflow.com worksaround this problem<br>
In case this is not working, you can disable such security feature in your google account settings. Some business and enterprise account may not have this problem by default
## Dependencies
All python deps are listed in **requirements.txt**, just run<br>
pip install -r requirements.txt
## Add your own meetings
To add your own meetings into **meetings.py**, adding another <em>scheduleMeeting</em> line like the one already present. You can add as many as you want, but remember that this bot does not support joining multiple meetings at the same time

137
browser_manager.py Normal file
View File

@ -0,0 +1,137 @@
import sys
import selenium
import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import os
from enum import Enum
import threading
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
import time as t
G_ACCOUNT_MAIL = None
G_ACCOUNT_PASS = None
FIREFOX_DVD_DIR = "/usr/bin/geckodriver"
'''Locating by xpath here is the best thing to do here, since google Meet changes selectors, classes name and all that sort of stuff for every meeting
XPaths remaing the same, but a slight change by them would make this program fail.
The xpath is found clicking by inspecting the element of the searched button, and finding the parent div tthat has role="button" tag
'''
MIC_XPATH = '/html/body/div[1]/c-wiz/div/div/div[8]/div[3]/div/div/div[2]/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div/div/div'
WEBCAM_XPATH = '/html/body/div[1]/c-wiz/div/div/div[8]/div[3]/div/div/div[2]/div/div[1]/div[1]/div[1]/div/div[3]/div[2]/div/div'
JOIN_XPATH = '/html/body/div[1]/c-wiz/div/div/div[8]/div[3]/div/div/div[2]/div/div[1]/div[2]/div/div[2]/div/div/div[1]'
OPTION_XPATH = '/html/body/div[1]/c-wiz/div/div/div[6]/div[3]/div/div/div[2]/div/div[1]/div[1]/div[1]/div/div[4]/div'
CHAT_BTN_XPATH = '/html/body/div[1]/c-wiz/div[1]/div/div[6]/div[3]/div[6]/div[3]/div/div[2]/div[3]'
CHAT_SELECTCHAT_BTN_XPATH = '/html/body/div[1]/c-wiz/div[1]/div/div[6]/div[3]/div[3]/div/div[2]/div[2]/div[1]/div[2]'
#Using tagname for text area because xpath doesn't really work, and we're sure it's the only textarea on the webpage
CHAT_TEXT_XPATH = "textarea"
HANG_UP_BTN_XPATH = '/html/body/div[1]/c-wiz/div[1]/div/div[8]/div[3]/div[9]/div[2]/div[2]/div'
CHAT_CLOSE_BTN_XPATH = '/html/body/div[1]/c-wiz/div[1]/div/div[6]/div[3]/div[3]/div/div[2]/div[1]/div[2]/div/button'
browser = None
def initFirefox():
global browser, G_ACCOUNT_MAIL, G_ACCOUNT_PASS
print("Input your google account credentials. The information will not be stored anywhere and you will have to relogin everytime you restart this bot\n")
G_ACCOUNT_MAIL = input("Type your email: ")
G_ACCOUNT_PASS = input("Type your password: ")
#webdriver.FirefoxProfile('/home/emamaker/Documents/Projects/GoogleMeetBot/firefox_profile')
browser = webdriver.Firefox()
def joinMeeting(link):
global browser
if link == '':
return
try:
browser.get(link)
t.sleep(15)
print("Trying to join meeting")
clickButton(By.XPATH, MIC_XPATH)
clickButton(By.XPATH, WEBCAM_XPATH)
clickButton(By.XPATH, JOIN_XPATH)
except:
# In this way, in case of any error we can try again
print("Failed to join meeting, trying again in 60 secs")
t.sleep(60)
joinMeeting(link)
def clickButton(by, selector):
global browser
WebDriverWait(browser, 5).until(EC.element_to_be_clickable((by, selector))).click()
t.sleep(1)
def writeText(by, selector, text):
WebDriverWait(browser, 5).until(EC.element_to_be_clickable((by, selector))).clear()
WebDriverWait(browser, 5).until(EC.element_to_be_clickable((by, selector))).send_keys(text + "\n")
def sendChatMsg(text):
global browser
#open chat menu
clickButton(By.XPATH, CHAT_BTN_XPATH)
#select chat option
clickButton(By.XPATH, CHAT_SELECTCHAT_BTN_XPATH)
#write msg
writeText(By.TAG_NAME, CHAT_BTN_XPATH, text)
t.sleep(1)
#close chat
clickButton(By.XPATH, CHAT_CLOSE_BTN_XPATH)
def checkStarted():
try:
clickButton(By.XPATH, OPTION_XPATH)
except:
return False
return True
def loginIntoGoogle():
global browser
browser.get("https://myaccount.google.com/?utm_source=sign_in_no_continue")
t.sleep(3)
#we can use selectors in this webside, since they're static
#login button
clickButton(By.CSS_SELECTOR, "li.h-c-header__cta-li:nth-child(2) > a:nth-child(1)")
#login with google
#clickButton(By.CSS_SELECTOR, "button.s-btn__icon:nth-child(1)")
#write email
writeText(By.CSS_SELECTOR, "#identifierId", G_ACCOUNT_MAIL)
t.sleep(3)
#write pwd
writeText(By.XPATH, "/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input", G_ACCOUNT_PASS)
t.sleep(3)
def loginIntoGoogleWithStackOverflow():
global browser
browser.get("https://stackoverflow.com/users/login?ssrc=head&returnurl=https%3a%2f%2fstackoverflow.com%2f")
t.sleep(3)
#we can use selectors in this webside, since they're static
#login with google
clickButton(By.CSS_SELECTOR, "#openid-buttons > button.grid--cell.s-btn.s-btn__icon.s-btn__google.bar-md.ba.bc-black-100")
#login button
#write email
writeText(By.CSS_SELECTOR, "#identifierId", G_ACCOUNT_MAIL)
t.sleep(3)
#write pwd
writeText(By.XPATH, "/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input", G_ACCOUNT_PASS)
t.sleep(3)
def hangUpMeeting():
clickButton(By.XPATH, HANG_UP_BTN_XPATH)

19
gmeet_bot.py Normal file
View File

@ -0,0 +1,19 @@
'''Automatically join Google Meet meetings, with muted camera and mic
Just give link and it joins. Features chat too
Planning on adding a schedule system'''
import meetings
import browser_manager
import schedule
import time
browser_manager.initFirefox()
browser_manager.loginIntoGoogleWithStackOverflow()
#while checkStarted() is False:
#browser.sendChatMsg("hello world")
meetings.setup_schedule()
while True:
schedule.run_pending()
time.sleep(1)

30
meetings.py Normal file
View File

@ -0,0 +1,30 @@
import time as t
import schedule
import browser_manager
def setup_schedule():
scheduleMeeting("friday", "21:20", "21:22", "https://meet.google.com/jqn-fgav-aad")
def scheduleMeeting(day, startHour, endHour, link):
if str(day).lower() == "monday":
schedule.every().monday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().monday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "tuesday":
schedule.every().tuesday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().tuesday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "wednesday":
schedule.every().wednesday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().wednesday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "thursday":
schedule.every().thursday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().thursday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "friday":
schedule.every().friday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().friday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "saturday":
schedule.every().saturday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().saturday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "sunday":
schedule.every().sunday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().sunday.at(endHour).do(browser_manager.hangUpMeeting)

83
meetings_school.py Normal file
View File

@ -0,0 +1,83 @@
import time as t
import schedule
import browser_manager
''' STORE MEET LINKS HERE'''
MATHS = 'https://meet.google.com/lookup/fn2tkngzid?authuser=0&hs=179'
LITERATURE = 'https://meet.google.com/lookup/bhoqky4qee?authuser=0&hs=179'
ENGLISH = 'https://meet.google.com/lookup/hlj4rhyj4p?authuser=0&hs=179'
ELECTRONICS = 'https://meet.google.com/lookup/ehuwfglxvr?authuser=0&hs=179'
SYSTEMS = ''
TPSEE = 'https://meet.google.com/lookup/bc4r2d32ua?authuser=0&hs=179'
TPSEE_ELT = 'https://meet.google.com/lookup/gdaq3kmguh?authuser=0&hs=179'
TPSEE_SYS = 'https://meet.google.com/lookup/gdaq3kmguh?authuser=0&hs=179'
ELT_SYSTEMS = ''
'''TIME SCHEDULE - START AND FINISH'''
FIRST_HOUR = "8:00"
SECOND_HOUR = "8:50"
THIRD_HOUR = "9:50"
FOURTH_HOUR = "10:50"
FIFTH_HOUR = "11:50"
SIXTH_HOUR = "12:40"
SEVENTH_HOUR = "13:40"
def setup_schedule():
#scheduleMeeting("friday", "20:56", "20:57", "https://meet.google.com/jqn-fgav-aad")
# Monday schedule
scheduleMeeting("monday", FIRST_HOUR, SECOND_HOUR, TPSEE)
scheduleMeeting("monday", SECOND_HOUR, THIRD_HOUR, ENGLISH)
scheduleMeeting("monday", THIRD_HOUR, FOURTH_HOUR, SYSTEMS)
scheduleMeeting("monday", FOURTH_HOUR, FIFTH_HOUR, MATHS)
scheduleMeeting("monday", FIFTH_HOUR, SEVENTH_HOUR, LITERATURE)
# Tuesday schedule
scheduleMeeting("tuesday", FIRST_HOUR, THIRD_HOUR, SYSTEMS)
scheduleMeeting("tuesday", THIRD_HOUR, FIFTH_HOUR, ELECTRONICS)
scheduleMeeting("tuesday", FIFTH_HOUR, SIXTH_HOUR, TPSEE_ELT)
scheduleMeeting("tuesday", SIXTH_HOUR, SEVENTH_HOUR, TPSEE)
# Wednesday schedule
scheduleMeeting("wednesday", FIRST_HOUR, SECOND_HOUR, ELT_SYSTEMS)
scheduleMeeting("wednesday", SECOND_HOUR, THIRD_HOUR, MATHS)
scheduleMeeting("wednesday", THIRD_HOUR, FOURTH_HOUR, LITERATURE)
scheduleMeeting("wednesday", SIXTH_HOUR, SEVENTH_HOUR, LITERATURE)
# Thursday schedule
scheduleMeeting("thursday", FIRST_HOUR, SECOND_HOUR, ELECTRONICS)
scheduleMeeting("thursday", SECOND_HOUR, THIRD_HOUR, ENGLISH)
scheduleMeeting("thursday", FOURTH_HOUR, FIFTH_HOUR, TPSEE)
scheduleMeeting("thursday", FIFTH_HOUR, SIXTH_HOUR, TPSEE_SYS)
scheduleMeeting("thursday", SIXTH_HOUR, SEVENTH_HOUR, SYSTEMS)
# Friday schedule
scheduleMeeting("friday", FIRST_HOUR, SECOND_HOUR, MATHS)
scheduleMeeting("friday", SECOND_HOUR, THIRD_HOUR, ENGLISH)
scheduleMeeting("friday", FOURTH_HOUR, FIFTH_HOUR, LITERATURE)
scheduleMeeting("friday", FIFTH_HOUR, SIXTH_HOUR, LITERATURE)
scheduleMeeting("friday", SIXTH_HOUR, SEVENTH_HOUR, TPSEE)
def scheduleMeeting(day, startHour, endHour, link):
if str(day).lower() == "monday":
schedule.every().monday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().monday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "tuesday":
schedule.every().tuesday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().tuesday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "wednesday":
schedule.every().wednesday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().wednesday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "thursday":
schedule.every().thursday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().thursday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "friday":
schedule.every().friday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().friday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "saturday":
schedule.every().saturday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().saturday.at(endHour).do(browser_manager.hangUpMeeting)
elif str(day).lower() == "sunday":
schedule.every().sunday.at(startHour).do(browser_manager.joinMeeting, link)
schedule.every().sunday.at(endHour).do(browser_manager.hangUpMeeting)

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
selenium
schedule