-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbot.py
188 lines (153 loc) Β· 6.75 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import logging
import os
from time import sleep
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.firefox.service import Service
from telegram.ext import ContextTypes, Application
# Set up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Load environment variables
USER_NAME = os.getenv("USER_NAME")
PASSWORD = os.getenv("PASSWORD")
API_TOKEN = os.getenv("API_TOKEN")
current_job_list = {}
driver = None
def get_session_items():
global driver
logger.info("Starting API token retrieval process")
url = "https://readytalent2.singaporetech.edu.sg/"
try:
options = webdriver.FirefoxOptions()
options.add_argument("--headless")
service = Service(executable_path="/usr/bin/geckodriver")
driver = webdriver.Firefox(options=options, service=service)
driver.get(url)
wait = WebDriverWait(driver, 10)
sign_in_button = wait.until(
ec.element_to_be_clickable((By.XPATH, "/html/body/div[4]/div/div/div[2]/div/a[2]"))
)
sleep(5)
sign_in_button.click()
logger.info("Clicked initial sign-in button")
username = wait.until(ec.visibility_of_element_located((By.ID, "userNameInput")))
username.send_keys(USER_NAME)
logger.info("Entered username")
password = wait.until(ec.visibility_of_element_located((By.ID, "passwordInput")))
password.send_keys(PASSWORD)
logger.info("Entered password")
sign_in = wait.until(ec.element_to_be_clickable((By.ID, "submitButton")))
sign_in.click()
logger.info("Clicked final sign-in button")
wait.until(ec.presence_of_element_located((By.TAG_NAME, "body")))
sleep(5)
api_token = driver.execute_script("return sessionStorage.getItem('apitoken')")
logger.info("Retrieved API token")
student_id = driver.execute_script("return sessionStorage.getItem('StudentId')")
logger.info(f"Retrieved student ID: {student_id}")
return student_id, api_token
except Exception as e:
logger.error(f"Error in get_api_token: {str(e)}")
return None
finally:
driver.quit()
logger.info("Closed browser")
def get_job_list(initial=False):
logger.info("Starting job list retrieval")
session_items = get_session_items()
url = f"https://mvw9e7kvt9.execute-api.ap-southeast-1.amazonaws.com/Prod?requestname=LoadJobDetailsStudentDashboard&studentId={session_items[0]}&accessLevelCondition="
headers = {'apitoken': session_items[1]}
try:
response = requests.post(url, headers=headers)
response.raise_for_status()
response_json = response.json()
job_list = {
job['sit_jobpostingid']: {
'job_title': job['sit_name'],
'company_name': job['acc.name'],
'allowance': job['sit_allowance@OData.Community.Display.V1.FormattedValue'],
'number_of_vacancies': job['sit_numberofvacancies']
} for job in response_json
}
if initial:
# On initial run, we keep trying until we get at least one job
while len(job_list) == 0:
logger.info("Initial API call returned no jobs, retrying...")
response = requests.post(url, headers=headers)
response.raise_for_status()
response_json = response.json()
job_list = {
job['sit_jobpostingid']: {
'job_title': job['sit_name'],
'company_name': job['acc.name'],
'allowance': job['sit_allowance@OData.Community.Display.V1.FormattedValue'],
'number_of_vacancies': job['sit_numberofvacancies']
} for job in response_jsoncd
}
logger.info(f"Initial job list retrieval completed with {len(job_list)} jobs")
else:
# For subsequent runs, if no jobs are found, we return without updating
if len(job_list) == 0:
logger.info("Subsequent API call returned no jobs, keeping the current job list")
return {}
return job_list
except requests.RequestException as e:
logger.error(f"Error in get_job_list: {str(e)}")
return {}
def check_job_list():
logger.info("Checking for new jobs")
new_job_list = get_job_list()
global current_job_list
# If new_job_list is empty, we retain the current job list
if len(new_job_list) == 0:
logger.info("No new jobs found in API response")
return None
# Find new jobs that are not already in the current_job_list
new_jobs = {job_id: job for job_id, job in new_job_list.items() if job_id not in current_job_list}
if new_jobs:
logger.info(f"Found {len(new_jobs)} new jobs")
current_job_list = new_job_list
else:
logger.info("No new jobs found")
return new_jobs if new_jobs else None
async def notify_new_jobs(context: ContextTypes.DEFAULT_TYPE):
logger.info("Starting job notification process")
new_jobs = check_job_list()
if new_jobs is None:
logger.info("No new jobs to notify")
return
for job_id, job in new_jobs.items():
message = (
f"π New Job Listing π\n"
f"π {job['job_title']}\n"
f"π’ {job['company_name']}\n"
f"π° {job['allowance']}\n"
f"π₯ {job['number_of_vacancies']}\n"
)
try:
# Replace chat_id with your own chat_id
await context.bot.send_message(chat_id='@sitnofuture', text=message)
logger.info(f"Sent notification for job: {job['job_title']}")
sleep(2)
except Exception as e:
logger.error(f"Error sending notification for job {job['job_title']}: {str(e)}")
def main():
logger.info("Starting application")
application = Application.builder().token(API_TOKEN).build()
job_queue = application.job_queue
# Initial job check to populate current_job_list
check_job_list_initial = get_job_list(initial=True)
global current_job_list
current_job_list = check_job_list_initial
logger.info(f"Initial job check completed successfully with {len(current_job_list)} jobs")
# Schedule 10-min job to check for new jobs
logger.info("Scheduling job to check for new jobs every 10 minutes")
job_queue.run_repeating(notify_new_jobs, interval=600)
application.run_polling()
logger.info("Application is running")
if __name__ == "__main__":
main()