Last active
July 14, 2019 11:36
-
-
Save marios8543/a9a8755de55eea59ef5bacfa5b9c996f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from Discord.uwebsockets import client | |
from machine import Timer | |
from ujson import loads,dumps | |
from urequests import post | |
import uzlib | |
import sys | |
ZLIB_SUFFIX = "ÿÿ" | |
class Client: | |
def __init__(self,prefix="esp!"): | |
self.commands = {} | |
self.events = {} | |
self.on_message = None | |
self.prefix = prefix | |
self.websocket = None | |
self.heartbeat_timer = Timer(-1) | |
self.sequence = 0 | |
self.session_id = None | |
self.token = None | |
self.running = True | |
def add_command(self,func): | |
if func.__name__ in self.commands: | |
return | |
self.commands[func.__name__] = func | |
def add_event(self,func): | |
if func.__name__ not in self.events: | |
self.events[func.__name__] = [func] | |
else: | |
self.events[func.__name__].append(func) | |
def on_message_event(self,func): | |
self.on_message = func | |
def send(self,channel,content): | |
res = post("https://discordapp.com/api/v6/channels/{}/messages".format(channel),json={'content':content},headers={'Authorization':'Bot {}'.format(self.token),'Content-Type':'application/json'}) | |
if res.status_code==200: | |
print("Sent message to {} successfully".format(channel)) | |
else: | |
print("{} Failed to send message ({})".format(res.status_code,res.text)) | |
res.close() | |
def start(self,token): | |
while self.running: | |
self.websocket = client.connect('wss://gateway.discord.gg?encoding=json&v=6') | |
hrt = loads(self.websocket.recv()) | |
self.heartbeat_timer.init(period=hrt['d']['heartbeat_interval'],mode=Timer.PERIODIC,callback=lambda t: self.websocket.send(dumps({'op':1,'d':None if self.sequence==0 else self.sequence}))) | |
print("Received hello. Starting heartbeat every {}ms".format(hrt['d']['heartbeat_interval'])) | |
if not self.session_id: | |
print("No session id to resume. Sending identify.") | |
self.websocket.send(dumps({ | |
'op':2, | |
'd':{ | |
'token':token, | |
'properties':{ | |
"$os": "linux", | |
"$browser": "disco", | |
"$device": "disco" | |
} | |
} | |
})) | |
else: | |
print("Resuming...") | |
self.websocket.send(dumps({ | |
'op':6, | |
'd':{ | |
'token':token, | |
'session_id':self.session_id, | |
'seq':self.sequence | |
} | |
})) | |
self.token = token | |
print("Receiving messages") | |
while self.running: | |
try: | |
re = self.websocket.recv() | |
if not re: | |
print("Received empty message. Reconnecting to websocket") | |
break | |
if len(re) < 4 or re[-4:] != ZLIB_SUFFIX: | |
re = loads(re) | |
else: | |
re = loads(uzlib.decompress(re).decode('utf-8')) | |
self.sequence+=1 | |
if len(str(re['op']))==4: | |
print("Disconnected from the gateway with opcode {}. Attempting reconnect".format(re['op'])) | |
break | |
elif re['op']==0 and re['t']=='READY': | |
self.session_id = re['d']['session_id'] | |
print("Fetched session id ({})".format(self.session_id)) | |
elif re['op']==0 and re['t']=='MESSAGE_CREATE': | |
msg = Message(re['d']) | |
print("Received new message on channel {}".format(msg.channel_id)) | |
if msg.content.startswith(self.prefix): | |
com = msg.content.split(" ")[0][len(self.prefix):] | |
if com in self.commands: | |
try: | |
self.commands[com](msg) | |
except Exception as e: | |
print("An exception occured in command {}".format(com)) | |
sys.print_exception(e) | |
if re['t'] in self.events: | |
for i in self.events[re['t']]: | |
try: | |
i(re['d']) | |
except Exception as e: | |
print("An exception occured in event {}".format(re['t'])) | |
sys.print_exception(e) | |
if self.on_message: | |
self.on_message(msg) | |
except Exception as e: | |
sys.print_exception(e) | |
continue | |
self.heartbeat_timer.deinit() | |
class User: | |
def __init__(self,payload): | |
self.id = payload['id'] | |
self.name = payload['username'] | |
self.discriminator = payload['discriminator'] | |
class Message: | |
def __init__(self,payload): | |
self.id = payload['id'] | |
self.channel_id = payload['channel_id'] | |
self.author = User(payload['author']) | |
self.content = payload['content'] | |
self.type = payload['type'] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment