This repository was archived by the owner on Jan 24, 2024. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathbot.py
More file actions
294 lines (251 loc) · 14.5 KB
/
Copy pathbot.py
File metadata and controls
294 lines (251 loc) · 14.5 KB
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
from telepotpro import Bot, glance
from telepotpro.exception import TelegramError, BotWasBlockedError
from time import sleep
from threading import Thread
from random import choice
from json import load as jsload
from os.path import abspath, dirname, join
from pony.orm import db_session, select
from modules import helpers, keyboards
from modules.database import User, Message
with open(join(dirname(abspath(__file__)), "settings.json")) as settings_file:
settings = jsload(settings_file)
bot = Bot(settings["token"])
forwardChannel = settings["forwardChannel"]
messages = {
"start": "<b>Ciao, {}!</b> Sono il bot di <a href=\"t.me/offerVolt\">offerVolt</a>.\n"
"Puoi usarmi per richiedere un coupon per prodotti <b>Banggood</b>, oppure per segnalare un'offerta.\n"
"<b>Ricorda che abbiamo coupon solo per Banggood, gearbest o geekbuying, per cui non richiederci coupon per altri store come Amazon o AliExpress.</b>\n"
"Premi /help per vedere come funziono!",
"help": "Ciao, sono il bot di richiesta e segnalazione di offerte di overVolt.\n\n"
"🎟 <b>Come richiedo un coupon?</b>\n"
"Per richiedere un coupon devi mandarci il link del prodotto, e poi noi provvederemo a ricercare coupon "
"in giro per i meandri più oscuri di qualche magazzino orientale.\n"
"<b>Nota: Possiamo trovare coupon solo per prodotti Banggood, Gearbest e Geekbuying.</b>\n\n"
"Esempio:\n"
"- <i>Vorrei un coupon per questo prodotto https://link.del.prodotto/</i>\n\n"
"💡 <b>Come richiedo una offerta?</b>\n"
"Per richiedere una offerta è necessario che tu ci fornisca dei dettagli sul tipo di prodotto che stai "
"cercando, come per esempio fascia di prezzo e caratteristiche.\n\n"
"Esempio:\n"
"- <i>Sto cercando un tablet per lo studio con la penna inclusa, voglio spendere massimo 400€</i>\n\n"
"<b>Potrebbe capitare che in mezzo a tutti i messaggi che ci arrivano ne perdiamo di vista qualcuno: se proprio vedi "
"che dopo un giorno non ti abbiamo ancora risposto, invia di nuovo il messaggio e ti risponderemo!</b>\n"
"<b>Possiamo trovare coupon solo per prodotti Banggood, Gearbest e Geekbuying.</b>",
"msg_sent": "<b>Messaggio inviato!</b>\n"
"<b>Ricorda che abbiamo coupon solo per Banggood, gearbest o geekbuying, per cui non richiederci coupon per altri store come Amazon o AliExpress.</b>\n"
"Un membro del team ti risponderà il prima possibile.\n"
"⚠️ <b>Ricordati che <u>siamo in pochi</u> a gestire tutte le richieste</b> che ci arrivano: ci piacerebbe rispondere a "
"tutti in poco tempo ma è impossibile, porta pazienza se non rispondiamo subito!\n"
"Se non ricevi risposta entro qualche giorno probabilmente ci è sfuggito il tuo messaggio, "
"per cui inviacelo di nuovo avendo cura di fornirci tutti i dettagli necessari a soddisfare la tua richiesta.",
"command_ukn": "🤨 Comando sconosciuto.",
"muted": "⛔ <b>Sei mutato.</b>\n"
"Un admin ti ha temporaneamente limitato, quindi non puoi scrivere messaggi diretti allo staff.",
"thanks": [
"Richiesta effettuata!", "Grazie per la richiesta!", "Grazie dell'aiuto!"
]
}
@db_session
def reply(msg):
chatId = int(msg['chat']['id'])
msgId = int(msg['message_id'])
name = msg['from']['first_name']
if "last_name" in msg['from']:
name += " " + msg['from']['last_name']
if "text" in msg:
text = msg['text']
elif "caption" in msg:
text = msg['caption']
else:
text = ""
# Change Banggood mobile version to desktop one
text = text.replace("it-m.banggood.com", "banggood.com")
text = text.replace("m.banggood.com", "banggood.com")
## Messaggio da canale interno
if chatId == -1001298078411:
print(msg) # TODO: debug
## Messaggio da chat normali
elif chatId > 0:
# Genera entry nel database
if not User.exists(lambda u: u.chatId == chatId):
isNewUser = True
user = User(chatId=chatId, name=name)
else:
isNewUser = False
user = User.get(chatId=chatId)
user.name = name
# Comandi bot
if text == "/listmuted" and helpers.isAdmin(chatId):
mutedUsers = select(u for u in User if u.muted)[:]
mutedList = ""
for u in mutedUsers:
mutedList += "- <a href=\"tg://user?id={}\">{}</a>\n".format(u.chatId, u.name)
if mutedList:
bot.sendMessage(chatId, "🔇 <b>Lista utenti mutati:</b>\n"
"{}".format(mutedList), parse_mode="HTML")
else:
bot.sendMessage(chatId, "🔇 <b>Nessun utente mutato!</b>", parse_mode="HTML")
elif text.startswith("/annuncio ") and helpers.isAdmin(chatId):
bdText = "📢 <b>Annuncio dallo staff</b>\n" + text.split(" ", 1)[1]
pendingUsers = select(u.chatId for u in User)[:]
userCount = len(pendingUsers)
for uid in pendingUsers:
try:
bot.sendMessage(uid, bdText, parse_mode="HTML", disable_web_page_preview=True)
except (TelegramError, BotWasBlockedError):
userCount -= 1
bot.sendMessage(chatId, "📢 Messaggio inviato correttamente a {0} utenti!".format(userCount))
elif text == "/start":
if isNewUser:
bot.sendMessage(chatId, messages["help"], parse_mode="HTML")
else:
bot.sendMessage(chatId, messages["start"].format(msg['from']['first_name']), parse_mode="HTML")
elif text == "/help":
bot.sendMessage(chatId, messages["help"], parse_mode="HTML")
## Admin ha risposto ad un messaggio di testo
elif "reply_to_message" in msg and helpers.isAdmin(chatId):
try:
quotedMessage = msg['reply_to_message']
# Cerca i dati del messaggio dal database
origMsg = None
dbQuery = select(m for m in Message if m.sentIds[str(chatId)] == int(quotedMessage['message_id']))[:]
if len(dbQuery) > 0:
origMsg = dbQuery[0]
userId = origMsg.fromUser.chatId
userName = origMsg.fromUser.name
else:
# Cerca di capire le informazioni da Telegram
if "forward_from" in quotedMessage:
userId = quotedMessage['forward_from']['id']
userName = quotedMessage['forward_from']['first_name']
if "last_name" in quotedMessage['forward_from']:
userName += " " + msg['reply_to_message']['forward_from']['last_name']
else:
bot.sendMessage(chatId, "😔 <b>Errore nell'invio.</b>\n\n"
"L'utente ha attivato la privacy per i messaggi inoltrati, e il "
"messaggio non è nel database.", parse_mode="HTML")
return
# Controlla se è un comando di servizio
if text.startswith("/"):
if text == "/mute":
if not origMsg.fromUser.muted:
origMsg.fromUser.muted = True
bot.sendMessage(chatId, "🔇 Utente mutato.\n"
"Usa /unmute per smutarlo.")
bot.sendMessage(origMsg.fromUser.chatId, "🔇 Sei stato mutato da un admin.")
else:
bot.sendMessage(chatId, "⚠️ Utente già mutato.")
elif text == "/unmute":
if origMsg.fromUser.muted:
origMsg.fromUser.muted = False
bot.sendMessage(chatId, "🔉 Utente smutato.\n"
"Usa /mute per mutarlo di nuovo.")
bot.sendMessage(origMsg.fromUser.chatId, "🔉 Puoi nuovamente inviare messaggi al bot!")
else:
bot.sendMessage(chatId, "⚠️ Utente già smutato.")
else:
bot.sendMessage(chatId, messages["command_ukn"], parse_mode="HTML")
# Altrimenti, invia risposta a utente
else:
replyToId = origMsg.fromMsgId if origMsg else None
bot.sendMessage(userId, "💬 <b>Risposta dello staff</b>\n"
"{}".format(text), parse_mode="HTML", reply_to_message_id=replyToId)
bot.sendMessage(chatId, "Risposta inviata!")
# Segnala ad altri admin la risposta data
otherAdmins = [a for a in helpers.isAdmin() if a != chatId]
for a in otherAdmins:
try:
replyToId = origMsg.sentIds[str(a)] if origMsg else None
if replyToId:
bot.deleteMessage((a, replyToId))
bot.sendMessage(a, "<a href=\"tg://user?id={}\">{}</a> ha risposto a <a href=\"tg://user?id={}\">{}</a>:\n"
"<i>{}</i>".format(chatId, name, userId, userName, text), parse_mode="HTML")
except (TelegramError, BotWasBlockedError, KeyError):
pass
bot.deleteMessage((chatId, quotedMessage['message_id']))
bot.deleteMessage((chatId, int(quotedMessage['message_id'])+1))
#così elimina anche il messaggio sotto con le risposte rapide (compila e controlla se funzia perchè sto editando da github)
except Exception as e:
bot.sendMessage(chatId, "😔 <b>Errore nell'invio.</b>\n\n"
"<i>Debug Info:</i>\n"
"<code>{}</code>".format(e), parse_mode="HTML")
return
## Messaggio non contiene un link: modalità limitatibot
elif not helpers.getLink(msg):
if user.muted:
bot.sendMessage(chatId, messages["muted"], parse_mode="HTML")
return
if text.startswith("/"):
bot.sendMessage(chatId, messages["command_ukn"], parse_mode="HTML")
return
sentIdsCache = {}
for a in helpers.isAdmin():
try:
sentMsg = bot.forwardMessage(a, chatId, msg['message_id'])
sentIdsCache[str(a)] = int(sentMsg['message_id'])
except (TelegramError, BotWasBlockedError):
pass
# Se non c'è il messaggio nel database, è nuovo: salvalo
if not Message.exists(fromUser=user, fromMsgId=msgId):
Message(fromUser=user, fromMsgId=msgId, sentIds=sentIdsCache)
# Se esiste già il messaggio nel database, aggiorna i vecchi ID
else:
oldMessage = Message.get(fromUser=user, fromMsgId=msgId)
oldMessage.sentIds = sentIdsCache
bot.sendMessage(chatId, messages["msg_sent"], parse_mode="HTML")
## Messaggio contiene link: logga offerta e rispondi
else:
if user.muted:
bot.sendMessage(chatId, messages["muted"], parse_mode="HTML")
return
link = helpers.getLink(msg)
sent = bot.sendMessage(forwardChannel, "<b>Nuovo messaggio!</b>\n"
"<i>Da:</i> <a href=\"tg://user?id={}\">{}</a>\n\n"
"{}".format(chatId, name, text),
parse_mode="HTML", disable_web_page_preview=True, reply_markup=None)
Message(fromUser=user, fromMsgId=msgId, sentIds={str(forwardChannel): int(sent['message_id'])})
if helpers.short(link):
bot.editMessageReplyMarkup((forwardChannel, sent['message_id']), keyboards.link_prenota(helpers.short(link), sent['message_id']))
else:
bot.editMessageReplyMarkup((forwardChannel, sent['message_id']), keyboards.error_prenota(sent['message_id']))
bot.sendMessage(chatId, choice(messages["thanks"]), parse_mode="HTML")
@db_session
def button_press(msg):
query_id, chatId, query_data = glance(msg, flavor="callback_query")
query_split = query_data.split("#")
message_id = int(query_split[1])
button = query_split[0]
if button == "error":
bot.answerCallbackQuery(query_id, "Non sono riuscito a creare il link per Scontino.")
elif button == "prenotato":
linkid = query_split[2]
prevText = msg['message']['text']
bot.answerCallbackQuery(query_id, "Offerta prenotata!")
bot.editMessageText((forwardChannel, message_id), prevText.replace("Nuovo messaggio!\n",
"<b>[Offerta prenotata da {}]</b>\n".format(msg['from']['first_name'])), parse_mode="HTML")
if linkid != -1:
bot.editMessageReplyMarkup((forwardChannel, message_id), keyboards.open_scontino(linkid, message_id))
else:
bot.editMessageReplyMarkup((forwardChannel, message_id), keyboards.error(message_id))
elif button == "richiesta":
try:
prevText = msg['message']['text']
bot.answerCallbackQuery(query_id, "Richiesta prenotata!")
sent = bot.sendMessage(chatId, prevText.replace("Nuovo messaggio!\n", "<b>[Richiesta prenotata]</b>\n"), parse_mode="HTML")
bot.sendMessage(chatId, "ℹ️ <b>Risposte Rapide</b>\n"
"<code>Ciao, purtroppo non ho coupon per questo prodotto</code>", parse_mode="HTML", disable_notification=True)
bot.deleteMessage((forwardChannel, message_id))
dbQuery = select(m for m in Message if m.sentIds[str(forwardChannel)] == message_id)[:]
if len(dbQuery) > 0:
origMsg = dbQuery[0]
origMsg.sentIds = {str(chatId): int(sent['message_id'])}
except Exception as e:
print(e)
def accept_message(msg):
Thread(target=reply, args=[msg]).start()
def accept_button(msg):
Thread(target=button_press, args=[msg]).start()
bot.message_loop({'chat': accept_message, 'callback_query': accept_button})
while True:
sleep(60)