forked from 39bit/spoilerobot
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhandlers_callback.py
51 lines (42 loc) · 2.01 KB
/
handlers_callback.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
import asyncio
import time
from telethon import events
from telethon.errors import PeerIdInvalidError, UserIsBlockedError
import database
from config import MINOR_SPOILER_CACHE_TIME, MULTIPLE_CLICK_TIMEOUT
from message_serializer import deserialize_to_params, extract_contents
from proxy import client, logger, me
from util import format_exception
# TODO: gc old taps
pending_double_taps = {}
@client.on(events.CallbackQuery())
async def on_callback(event: events.CallbackQuery.Event):
uuid = database.UUID(event.data.decode('ascii'))
tap_id = (event.message_id, event.query.user_id)
if uuid.is_major and int(time.monotonic()) - pending_double_taps.get(tap_id, 0) > MULTIPLE_CLICK_TIMEOUT:
await event.answer(message='Please tap again to see the spoiler')
pending_double_taps[tap_id] = int(time.monotonic())
return
pending_double_taps.pop(tap_id, None)
spoiler = await database.get_spoiler(uuid)
if not spoiler:
logger.error(f"{event.query.user_id} requested missing spoiler uuid={uuid.get_str()} major={uuid.is_major} t={uuid.read_timestamp()}")
await event.answer(message='Spoiler not found. Too old?', cache_time=60)
return
if spoiler.type == 'Text' and len(spoiler.content) <= 200:
logger.info(f"{event.query.user_id} requested {spoiler.type} major={uuid.is_major}")
await event.answer(
message=spoiler.content,
alert=True,
cache_time=0 if uuid.is_major else MINOR_SPOILER_CACHE_TIME
)
return
logger.info(f"deeplinking {event.query.user_id} for {spoiler.type} major={uuid.is_major} qid={event.id}")
params = deserialize_to_params(spoiler)
try:
await asyncio.wait_for(client.send_message(event.query.user_id, **params), timeout=3.0)
await event.answer(url=f't.me/{me.username}?start=ignore')
# TODO: there might be more exceptions
except (UserIsBlockedError, PeerIdInvalidError, asyncio.TimeoutError) as e:
logger.info(f"failed to deeplink qid={event.id} ({format_exception(e)})")
await event.answer(url=f't.me/{me.username}?start={uuid.get_str()}')