/
__init__.py
58 lines (47 loc) · 1.81 KB
/
__init__.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
__version__ = '0.3.0'
from functools import wraps
from nacl.exceptions import BadSignatureError
from nacl.signing import VerifyKey
class InteractionType:
PING = 1
APPLICATION_COMMAND = 2
MESSAGE_COMPONENT = 3
APPLICATION_COMMAND_AUTOCOMPLETE = 4
class InteractionResponseType:
PONG = 1
CHANNEL_MESSAGE_WITH_SOURCE = 4
DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE = 5
DEFERRED_UPDATE_MESSAGE = 6
UPDATE_MESSAGE = 7
APPLICATION_COMMAND_AUTOCOMPLETE_RESULT = 8
class InteractionResponseFlags:
EPHEMERAL = 1 << 6
def verify_key(raw_body: str, signature: str, timestamp: str, client_public_key: str) -> bool:
message = timestamp.encode() + raw_body
try:
vk = VerifyKey(bytes.fromhex(client_public_key))
vk.verify(message, bytes.fromhex(signature))
return True
except Exception as ex:
print(ex)
return False
def verify_key_decorator(client_public_key):
from flask import request, jsonify
# https://stackoverflow.com/questions/51691730/flask-middleware-for-specific-route
def _decorator(f):
@wraps(f)
def __decorator(*args, **kwargs):
# Verify request
signature = request.headers.get('X-Signature-Ed25519')
timestamp = request.headers.get('X-Signature-Timestamp')
if signature is None or timestamp is None or not verify_key(request.data, signature, timestamp, client_public_key):
return 'Bad request signature', 401
# Automatically respond to pings
if request.json and request.json.get('type') == InteractionType.PING:
return jsonify({
'type': InteractionResponseType.PONG
})
# Pass through
return f(*args, **kwargs)
return __decorator
return _decorator