Compare commits
1 Commits
master
...
feature/v2
Author | SHA1 | Date | |
---|---|---|---|
|
4eba664d20 |
70
README.md
70
README.md
@ -1,3 +1,69 @@
|
||||
# selenium-energy-bot
|
||||
# selenium-energy-bot_v2018
|
||||
|
||||
The project contains a selenium bot which was created to automate the Energy Air or Energy Star Night competition. It is only intended as a POC and not to be used to win real tickets. (If you want to win tickets with it, you do it at your own risk.)
|
||||
The project contains a selenium bot which was created to automate the Energy Air or Energy Star Night competition. It is only intended as a POC and not to be used to win real tickets. (If you want to win tickets with it, you do it at your own risk.)
|
||||
|
||||
It is written in Python3 and requires an Android app to redirect the SMS.
|
||||
After successful implementation of the Smartphone app and the Python Bot, the SMS code is automatically read after the end of the session and the game starts from the beginning.
|
||||
|
||||
## Configuration
|
||||
[Download Python 3.7.4](https://www.python.org/ftp/python/3.7.4/python-3.7.4.exe)\
|
||||
After downloading the file, run it. During the installation it is important to note that the check mark under "Add Python 3.7 to PATH" is set.\
|
||||
Now open CMD and navigate to the folder "selenium-energy-bot":
|
||||
```
|
||||
cd \path\to\your\folder\selenium-energy-bot
|
||||
```
|
||||
There virtualenv must be installed:
|
||||
```
|
||||
pip3 install virtualenv
|
||||
virtualenv venv
|
||||
```
|
||||
or:
|
||||
```
|
||||
python -m .\venv
|
||||
```
|
||||
Afterwards:
|
||||
```
|
||||
venv\Scripts\activate.bat
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Gmail Account needed
|
||||
* Click on [Enable The GMAIL API](https://developers.google.com/gmail/api/quickstart/python) and "Download Client Config".
|
||||
* In the Gmail Inbox [mail.google.com](https://mail.google.com/) create a new "label".
|
||||
* Under Settings (top right), go to "Filters & blocked addresses "Create new filter".
|
||||
* As subject: *Forward SMS message from number [+41YOURNR] (sender - Energy (No contact specified))*
|
||||
* Contains the words: *Dein Code für game.energy.ch*
|
||||
* Create a filter and apply it to the newly created label.
|
||||
|
||||
### Download APP PlayStore
|
||||
* Download App [SMS to mail/phone - auto redirect](https://play.google.com/store/apps/details?id=com.gawk.smsforwarder)
|
||||
* Configure the app to forward the SMS to your previously configured Gmail.
|
||||
* Attention: The app must remain open in the background, so do not delete the app from the "open apps". Possibly adjust the energy plan on your mobile phone.
|
||||
|
||||
### App Iphone (optional)
|
||||
* If you don't have an Android, you can also use a corresponding app from the Appstore, which redirects SMS to Mail. The regex to find the code in the string has to be adjusted in the gmail_nrg_code.py script.\
|
||||
Possible App: [mysms mirror: Forward SMS](https://apps.apple.com/ch/app/mysms-mirror-sms-weiterleiten/id681057282)
|
||||
|
||||
### Other Downloads (REQUIRED)
|
||||
* Download the [Chrome Webdriver](https://chromedriver.chromium.org/downloads) in the appropriate version for your browser.\
|
||||
Find out the Webdriver version:
|
||||
1. open Chrome Browser
|
||||
2. click on the three points in the upper right corner
|
||||
3. help, then "about Google Chrome"
|
||||
4. at the top you will see "Version 78.0.3904.97"
|
||||
* Alternatively you can also use webdriver of Edge or IE. But I personally had the best experiences with Chrome (adjust the webdriver in the script nggame_2019.py if you want to change it).
|
||||
|
||||
## Usage
|
||||
### Unique execution
|
||||
* Place credentials.json (GMAIL Api Auth) and chromedriver.exe in the project folder.
|
||||
* In gmail_nrg_code.py there is a place (marked with Uncomment). Comment this block (Attention: After the "#" there is still a space, delete it).
|
||||
* Comment the function (main()) at the last place in the code and execute the script.
|
||||
```
|
||||
python gmail_nrg_code.py
|
||||
```
|
||||
* Copy the id of the label and paste it at the following code position:
|
||||
* ```results = service.users().messages().list(userId='me', labelIds=['UNREAD', 'Label_YOURIDHERE'],```
|
||||
* Comment code out again. Also the function at the end!
|
||||
|
||||
### Execute
|
||||
```python energy-bot.py```
|
158
energy-bot.py
158
energy-bot.py
@ -1,96 +1,55 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from selenium import webdriver
|
||||
import time
|
||||
import gmail_nrg_code as nrg_code
|
||||
|
||||
print("© 2019 Michael Reber . ALL RIGHTS RESERVED.")
|
||||
print("© 2018 Michael Reber . ALL RIGHTS RESERVED.")
|
||||
print("Created to win the endless energy game..")
|
||||
print("\r")
|
||||
|
||||
print("May the Force be with you.")
|
||||
print("Patience you must have, my young padawan.")
|
||||
|
||||
driver = webdriver.Chrome(executable_path=r"D:\Energy-Bot-2019\chromedriver.exe")
|
||||
driver = webdriver.Chrome(executable_path=r"D:\selenium-energy-bot\chromedriver.exe")
|
||||
driver.get("https://game.energy.ch/")
|
||||
# assert "Energy" in driver.title
|
||||
|
||||
# ANSWERS FOR ENERGY AIR:
|
||||
answers = [
|
||||
|
||||
#################################################################
|
||||
# ANTWORTEN FUERS ENERGY AIR 2019:
|
||||
#"One Republic",
|
||||
#"1300",
|
||||
#"gewinnen",
|
||||
#"XTRA-Circle",
|
||||
#"Twitter",
|
||||
#"E-Mail",
|
||||
#"2014",
|
||||
#"450 Tonnen",
|
||||
#"70 Meter",
|
||||
#"Die sechste",
|
||||
#"Lo & Leduc",
|
||||
#"im Radio, auf der Website und über Social Media",
|
||||
#"40’000",
|
||||
#"Energy Air findet trotzdem statt",
|
||||
#"Im Privatjet",
|
||||
#"Stade de Suisse, Bern",
|
||||
#"Bastian Baker",
|
||||
#"60",
|
||||
#"Um 17 Uhr", ## Kontzertbeginn 19:00
|
||||
#"250",
|
||||
#"Alvaro Soler",
|
||||
#"14",
|
||||
#"...der unter freiem Himmel stattfindet.",
|
||||
#"Averdeck",
|
||||
#"Sein Mami",
|
||||
#"Eine komplett weisse Garderobe",
|
||||
#"BSC Young Boys",
|
||||
#"7. September 2019",
|
||||
|
||||
#################################################################
|
||||
# AB HIER ANTWORTEN FUER ENERGY STAR NIGHT:
|
||||
"Swisscom", # ---------------------------------------------- (WELCHES UNTERNEHMEN IST «PRESENTING PARTNER» DER ENERGY STAR NIGHT?)
|
||||
"Über 1'000'000", #Geraten --------------------------------- (WIE VIELE KUNDEN BESUCHEN LIPO JÄHRLICH?)
|
||||
"2003", # -------------------------------------------------- (WANN FAND DIE ENERGY STAR NIGHT (EHEMALS ENERGY STARS FOR FREE) ZUM ERSTEN MAL STATT?)
|
||||
"Mark Forster", # ------------------------------------------ (WELCHER DIESER ACTS HATTE EINEN AUFTRITT AN DER ENERGY STAR NIGHT 2017?)
|
||||
"Um 19:00 Uhr", # ------------------------------------------ (WANN IST KONZERTBEGINN DER ENERGY STAR NIGHT?)
|
||||
"Reinach (Kanton Basel)", # -------------------------------- (IN WELCHER STADT ERÖFFNETE 1976 DIE ERSTE LIPO FILIALE DER SCHWEIZ?)
|
||||
"Energy Star Night 2017", # -------------------------------- (WELCHE AUSGABE DER ENERGY STAR NIGHT WURDE ZULETZT AUF PRO7 SCHWEIZ ÜBERTRAGEN?)
|
||||
"14'000", # ------------------------------------------------ (WIE VIELE ENERGY STAR NIGHT TICKETS WERDEN VERLOST?)
|
||||
"Graubünden",# ---------------------------------------------
|
||||
"Jastina Doreen, Ex-Miss Schweiz", # ----------------------- (WEN KÜSSTE ENERGY MODERATOR JONTSCH AN DER LETZTJÄHRIGEN ENERGY STAR NIGHT?)
|
||||
"3", # ----------------------------------------------------- (WIE VIELE ENERGY MUSIC AWARDS (IN ZUSAMMENARBEIT MIT DEM SCHWEIZERISCHEN ROTEN KREUZ) WURDEN BISHER VERLIEHEN?)
|
||||
"gewinnen", # ---------------------------------------------- (ENERGY STAR NIGHT TICKETS KANN MAN AUSSCHLIESSLICH…)
|
||||
"Die fünfzehnte", # Dieses Jahr ist die 17 Energy Star Night!
|
||||
"Energy Stars For Free", # --------------------------------- (DIE ENERGY STAR NIGHT HIESS EHEMALS...)
|
||||
"dem Schweizerischen Roten Kreuz",# ------------------------ (DER ENERGY MUSIC AWARD WIRD JEWEILS IN ZUSAMMENARBEIT MIT ... VERLIEHEN?)
|
||||
"Ein Schweizer Musikpreis", # ------------------------------ (WAS IST DER ENERGY MUSIC AWARD?)
|
||||
"Energy Star Night findet trotzdem statt", # ---------------
|
||||
"Möbel", # ------------------------------------------------- (WAS KANN MAN BEI LIPO KAUFEN?)
|
||||
"Oktober 2016", # ------------------------------------------ (WANN WURDE ENERGY STARS FOR FREE IN ENERGY STAR NIGHT UMBENANNT?)
|
||||
"Stefanie Heinzmann", # ------------------------------------ (WELCHER ACT ERÖFFNETE DIE ENERGY STAR NIGHT 2018?)
|
||||
"Usgang.ch", # --------------------------------------------- (WELCHES UNTERNEHMEN IST «MEDIENPARTNER» DER ENERGY STAR NIGHT 2019?)
|
||||
"im Radio, auf der Event-Website und über Social Media", # - (WO ERFÄHRST DU IMMER DIE NEUSTEN INFOS RUND UM DIE ENERGY STAR NIGHT?)
|
||||
"Vorhänge individuell konfigurieren", # -------------------- (WAS VERSTECKT SICH HINTER DEM BEGRIFF «MASSDESIGN» BEI LIPO?)
|
||||
"Orange", # ------------------------------------------------ (WELCHE FARBE HAT DAS LIPO LOGO?)
|
||||
"das grösste Indoor Musik-Event der Schweiz", # ------------ (DIE ENERGY STAR NIGHT IST…)
|
||||
"22", # ---------------------------------------------------- (AN WIE VIELEN STANDORTEN BIETET LIPO AKTUELL ALLES AN, WAS ES ZUM WOHNEN BRAUCHT)
|
||||
"22. November 2019", # ------------------------------------- (WANN FINDET DIE ENERGY STAR NIGHT 2019 STATT?)
|
||||
"Postkarte", # --------------------------------------------- (AUF WELCHEM WEG KANN MAN KEINE ENERGY STAR NIGHT TICKETS GEWINNEN?)
|
||||
"Hallenstadion, Zürich", # --------------------------------- (IN WELCHER EVENTLOCATION FINDET DIE ENERGY STAR NIGHT STATT?)
|
||||
"«The Game Is On»", #Geraten ------------------------------- (WIE LAUTETE DAS MOTTO DER ENERGY STAR NIGHT 2018?)
|
||||
"Hiltl Club, Zürich",# -------------------------------------
|
||||
"Nemo", # -------------------------------------------------- (WELCHER SCHWEIZER ACT RÄUMTE DEN ENERGY MUSIC AWARD 2018 AB?)
|
||||
"VIP", # --------------------------------------------------- (WELCHE TICKETKATEGORIE WIRD NICHT FÜR DIE ENERGY STAR NIGHT VERLOST?)
|
||||
"Winterthur und Villeneuve", #Geraten ---------------------- (IN WELCHEN BEIDEN STÄDTEN ERÖFFNET LIPO AM 22. NOVEMBER 2019 JEWEILS EINE NEUE FILIALE?)
|
||||
"Die tiefsten Preise der Schweiz", # ----------------------- (WAS GARANTIERT LIPO SEINEN KUNDEN?)
|
||||
"#esn19", # ------------------------------------------------ (WIE LAUTET DER OFFIZIELLE HASHTAG DER ENERGY STAR NIGHT 2019?)
|
||||
"Twitter", # ----------------------------------------------- (AUF WELCHER SOCIAL MEDIA PLATTFORM KANN MAN KEINE ENERGY STAR NIGHT TICKETS GEWINNEN?)
|
||||
"Mex" #Geraten --------------------------------------------- (WIE HEISST DER HUND IM AKTUELLEN WERBESPOT?)
|
||||
"One Republic",
|
||||
"1300",
|
||||
"gewinnen",
|
||||
"XTRA-Circle",
|
||||
"Twitter",
|
||||
"E-Mail",
|
||||
"2014",
|
||||
"450 Tonnen",
|
||||
"70 Meter",
|
||||
"Die sechste",
|
||||
"Lo & Leduc",
|
||||
"im Radio, auf der Website und über Social Media",
|
||||
"40’000",
|
||||
"Energy Air findet trotzdem statt",
|
||||
"Im Privatjet",
|
||||
"Stade de Suisse, Bern",
|
||||
"Bastian Baker",
|
||||
"60",
|
||||
"Um 17 Uhr",
|
||||
"250",
|
||||
"Alvaro Soler",
|
||||
"14",
|
||||
"...der unter freiem Himmel stattfindet.",
|
||||
"Averdeck",
|
||||
"Sein Mami",
|
||||
"Eine komplett weisse Garderobe",
|
||||
"BSC Young Boys",
|
||||
"7. September 2019"
|
||||
]
|
||||
|
||||
def press_answer(quest_nr):
|
||||
for answer in answers:
|
||||
try:
|
||||
labelname = '//label[@for="' + answer + '"]'
|
||||
labelname = "//label[@for='" + answer + "']"
|
||||
elem1 = driver.find_elements_by_xpath(labelname)[0]
|
||||
time.sleep(2)
|
||||
elem1.click()
|
||||
@ -105,11 +64,8 @@ def press_answer(quest_nr):
|
||||
question_Nr = 0
|
||||
counter = 0
|
||||
input("Press to enter script")
|
||||
|
||||
print("Enter Your Energy Registered Account Email:")
|
||||
account_mail = input("Email: ")
|
||||
print("Enter Your Passwort:")
|
||||
account_password = input("Passwort: ")
|
||||
print("Enter Phone Nr: (do not enter starting '0'! Example: 798765432")
|
||||
tel_nr = int(input("+41"))
|
||||
|
||||
while True:
|
||||
while question_Nr < 10:
|
||||
@ -117,11 +73,8 @@ while True:
|
||||
question_Nr += 1
|
||||
else:
|
||||
try:
|
||||
win1 = driver.find_elements_by_xpath("//button[@class='btn btn-primary game-button game-button-slot']")[0]
|
||||
win1.click()
|
||||
elem2 = driver.find_elements_by_xpath("//div[@class='circle col-xs-4 col-sm-3 col-md-4 col-lg-3']")[6]
|
||||
elem2.click()
|
||||
|
||||
try:
|
||||
elem1 = driver.find_elements_by_xpath("//button[@class='btn btn-primary game-button btn-lg']")[0]
|
||||
elem1.click()
|
||||
@ -130,24 +83,33 @@ while True:
|
||||
except:
|
||||
try:
|
||||
try:
|
||||
try:
|
||||
energyLogin = driver.find_elements_by_xpath("//input[@name='email']")[0]
|
||||
energyLogin.send_keys(account_mail)
|
||||
elem3 = driver.find_elements_by_xpath("//button[@id='first-step-continue-btn']")[0]
|
||||
elem3.click()
|
||||
except:
|
||||
try:
|
||||
energyPass = driver.find_elements_by_xpath("//input[@name='password']")[0]
|
||||
energyPass.send_keys(account_password)
|
||||
elem4 = driver.find_elements_by_xpath("//button[@id='native-login-btn']")[0]
|
||||
elem4.click()
|
||||
except:
|
||||
pass
|
||||
elem3 = driver.find_elements_by_xpath("//input[@placeholder='Handynummer']")[0]
|
||||
elem3.send_keys(tel_nr)
|
||||
elem1 = driver.find_elements_by_xpath("//button[@class='btn btn-primary game-button btn-lg']")[0]
|
||||
elem1.click()
|
||||
found_mail = False
|
||||
while found_mail is False:
|
||||
sms_code = nrg_code.main()
|
||||
if sms_code is not None:
|
||||
found_mail = True
|
||||
print(sms_code + "....................................................")
|
||||
code_numb_list = []
|
||||
for numb in sms_code:
|
||||
code_numb_list.append(numb)
|
||||
driver.find_elements_by_xpath("//input[@id='1']")[0].send_keys(code_numb_list[0])
|
||||
driver.find_elements_by_xpath("//input[@id='2']")[0].send_keys(code_numb_list[1])
|
||||
driver.find_elements_by_xpath("//input[@id='3']")[0].send_keys(code_numb_list[2])
|
||||
driver.find_elements_by_xpath("//input[@id='4']")[0].send_keys(code_numb_list[3])
|
||||
elem1 = \
|
||||
driver.find_elements_by_xpath(
|
||||
"//button[@class='btn btn-primary game-button btn-lg btn-declined']")[0]
|
||||
elem1.click()
|
||||
else:
|
||||
time.sleep(5)
|
||||
except:
|
||||
pass
|
||||
elem1 = driver.find_elements_by_xpath("//button[@class='btn btn-primary game-button btn-lg']")[0]
|
||||
elem1.click()
|
||||
|
||||
except:
|
||||
pass
|
||||
question_Nr = 0
|
||||
@ -155,7 +117,7 @@ while True:
|
||||
print("COUNT:", counter)
|
||||
if counter == 115:
|
||||
driver.close()
|
||||
driver = webdriver.Chrome(executable_path=r"D:\Energy-Bot-2019\chromedriver.exe")
|
||||
driver = webdriver.Chrome(executable_path=r"D:\selenium-energy-bot\chromedriver.exe")
|
||||
driver.get("https://game.energy.ch/")
|
||||
assert "Energy" in driver.title
|
||||
counter = 0
|
80
gmail_nrg_code.py
Normal file
80
gmail_nrg_code.py
Normal file
@ -0,0 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pickle
|
||||
import os.path
|
||||
from googleapiclient.discovery import build
|
||||
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||
from google.auth.transport.requests import Request
|
||||
import re
|
||||
|
||||
# If modifying these scopes, delete the file token.pickle.
|
||||
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.modify']
|
||||
|
||||
|
||||
def main():
|
||||
"""Shows basic usage of the Gmail API.
|
||||
Lists the user's Gmail labels.
|
||||
"""
|
||||
creds = None
|
||||
# The file token.pickle stores the user's access and refresh tokens, and is
|
||||
# created automatically when the authorization flow completes for the first
|
||||
# time.
|
||||
if os.path.exists('token.pickle'):
|
||||
with open('token.pickle', 'rb') as token:
|
||||
creds = pickle.load(token)
|
||||
# If there are no (valid) credentials available, let the user log in.
|
||||
if not creds or not creds.valid:
|
||||
if creds and creds.expired and creds.refresh_token:
|
||||
creds.refresh(Request())
|
||||
else:
|
||||
flow = InstalledAppFlow.from_client_secrets_file(
|
||||
'credentials.json', SCOPES)
|
||||
creds = flow.run_local_server(port=0)
|
||||
# Save the credentials for the next run
|
||||
with open('token.pickle', 'wb') as token:
|
||||
pickle.dump(creds, token)
|
||||
|
||||
service = build('gmail', 'v1', credentials=creds)
|
||||
|
||||
###############################################################################
|
||||
"""Uncomment to print label_name + label_id
|
||||
is needed to determine Energy Label id.
|
||||
"""
|
||||
# results = service.users().labels().list(userId='me').execute()
|
||||
#
|
||||
# labels = results.get('labels', [])
|
||||
#
|
||||
# if not labels:
|
||||
# print('No labels found.')
|
||||
# else:
|
||||
# print('Labels:')
|
||||
# for label in labels:
|
||||
# print(label['name'] + " " + label['id'])
|
||||
###############################################################################
|
||||
|
||||
# Call the Gmail API to fetch INBOX Energy, only unread messages
|
||||
results = service.users().messages().list(userId='me', labelIds=['UNREAD', 'Label_5204902350138961179'],
|
||||
maxResults=1).execute()
|
||||
messages = results.get('messages', [])
|
||||
|
||||
if not messages:
|
||||
print("No messages found.")
|
||||
return None
|
||||
else:
|
||||
print("Message snippets:")
|
||||
for message in messages:
|
||||
msg = service.users().messages().get(userId='me', format='full', id=message['id']).execute()
|
||||
# marks mail as read
|
||||
service.users().messages().modify(userId='me', id=message['id'],
|
||||
body={'removeLabelIds': ['UNREAD']}).execute()
|
||||
snippet = msg['snippet']
|
||||
print(snippet)
|
||||
verification_code = str(snippet).split("Dein Code für game.energy.ch")[-1]
|
||||
verification_code = verification_code.split(re.match('[0-3][0-9]/[0-1][0-9]/2019', verification_code))[
|
||||
0].strip()
|
||||
print(verification_code)
|
||||
return verification_code
|
||||
###############################################################################
|
||||
"""uncomment to run once to fetch label id or for development"""
|
||||
#if __name__ == '__main__':
|
||||
# main()
|
||||
###############################################################################
|
Loading…
Reference in New Issue
Block a user