-
Notifications
You must be signed in to change notification settings - Fork 7
/
bot.py
205 lines (162 loc) · 6.25 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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
from telebot import TeleBot
# from decouple import config
from scrapper import scrape
from db import subscribe, unsubscribe, users, relevantsub, getData, setData
from apscheduler.schedulers.background import BackgroundScheduler
from nlp import relevant
import requests
import time
import os
token = os.environ['TOKEN']
bot = TeleBot(token)
admin = os.environ['ADMIN']
notifs = getData()
def get_contents():
"""
Checks for changes in ktu site and returns the new notifs
"""
global notifs
contents = []
scraped = scrape()
if scraped != []:
datas = notifs
for scrap in scraped:
k = 0
for data in datas:
# Can't do a "not in" comparison with dictionary element coz download links inside it are
# unique to each request
if data['title'] == scrap['title'] and data['date'] == scrap['date']:
k = 1
break
if k == 0:
relevance = relevant(scrap['content'])
contents.append(
dict({'data': scrap, 'relevance': str(relevance)}))
notifs = scraped
return contents
else:
return []
def send_notifs(chat_id, contents, value):
""" Sends the newly scraped notification to individual users
based on Relevance if user has opted"""
for content in contents:
relevance = content['relevance']
content = content['data']
""" Checking for Relevance using ML and also whether user wants all notifs """
if relevance == '1' or value == 'T':
msg_content = content['date']+'\n\n' + \
content["title"]+':\n\n'+content["content"]
for link in content["link"]:
# telegram supports html like hyperlinks!! :)
msg_link_text = "<a href=\"" + \
link["url"]+"\">"+link["text"]+"</a>"
msg_content += "\n"+msg_link_text
try:
bot.send_message(
int(chat_id), msg_content, parse_mode="html",
)
except Exception as e:
print(str(e))
""" Just a notification to admin to check which notification was makred relevant """
if(chat_id == admin):
bot.send_message(
int(admin), relevance, parse_mode="markdown"
)
def scheduledjob():
""" Send new notifications that come on KTU site. \n
Checks subscription status of each user from Firebase Realtime Database and sends notifs
to subscribers
"""
contents = get_contents()
if contents and contents != []:
for key, value in users().items():
chat_id = key
""" checking if unsubscribed and send the notification """
if value != "F":
send_notifs(chat_id, contents, value)
setData(notifs)
@bot.message_handler(commands=["view"])
def fetch_notifs(message):
""" view """
contents = scrape()
# If dumb KTU is down as expected, fetch from previously scraped data
if contents == [] or not contents:
contents = notifs
for i in range(10):
content = contents[i]
msg_content = content['date']+'\n\n' + \
content["title"]+':\n\n'+content["content"]
for link in content["link"]:
# telegram supports html like hyperlinks!! :)
msg_link_text = "<a href=\""+link["url"]+"\">"+link["text"]+"</a>"
msg_content += "\n"+msg_link_text
bot.send_message(
message.chat.id, msg_content, parse_mode="html",
)
@bot.message_handler(commands=["subscribe"])
def subscribed(message):
""" subscribe """
subscribe(message.chat.id)
bot.send_message(
message.chat.id, "Subscribed!!", parse_mode="markdown",
)
@bot.message_handler(commands=["filtered"])
def filtered(message):
""" subscribe for relevant notifs only """
relevantsub(message.chat.id)
bot.send_message(
message.chat.id, "Subscribed to Relevant Notiications (*Beta*)", parse_mode="markdown",
)
@bot.message_handler(commands=["unsubscribe"])
def unsubscribed(message):
""" unsubscribe """
unsubscribe(message.chat.id)
bot.send_message(
message.chat.id, "Unsubscribed", parse_mode="markdown",
)
@bot.message_handler(commands=["start"])
def send_instructions(message):
"""/start"""
msg_content = (
"*Available commands:*\n\n /subscribe - Subscribe to KTU Notifs \n\n /filtered - Subscribe to *only Relevant* KTU Notifs (*Beta*) \n\n /unsubscribe - Unsubscribe from KTU Notifs \n\n /view - Fetch latest 10 Notifs from KTU \n\n /code - View source code GitHub"
)
bot.send_message(
message.chat.id, msg_content, parse_mode="markdown",
)
@bot.message_handler(commands=["code"])
def start_bot(message):
"""code - Displays link to Github repo of this project"""
bot.send_message(
message.chat.id, "View the complete code at \n\n https://github.com/AJAYK-01/ktu-notifier ", parse_mode="markdown",
)
@bot.message_handler(commands=["broadcast"])
def admin_msg(message):
""" to send service notifications from admin """
if(message.chat.id == int(admin)):
message = message.text.split(" ", 1)[1]
for key, value in users().items():
chat_id = key
""" checking if unsubscribed and send the notification """
if value != "F":
try:
bot.send_message(int(chat_id), message,
parse_mode="markdown")
except Exception as e:
print('line 86'+str(e))
else:
bot.send_message(message.chat.id, "**Uff hAcKerMAn**",
parse_mode="markdown")
def ping_repl():
""" ping flask server in replit to avoid sleeping of the bot """
repl_res = requests.get(
f"https://{os.environ['REPL_SLUG']}.{os.environ['REPL_OWNER']}.repl.co")
print(str(repl_res))
# first executions
ping_repl()
scheduledjob()
scheduler = BackgroundScheduler()
scheduler.add_job(scheduledjob, 'interval', minutes=10)
scheduler.add_job(ping_repl, 'interval', seconds=20)
scheduler.start()
# infinity_polling to prevent timeout to telegram api
bot.polling(none_stop=True, timeout=60)