diff options
Diffstat (limited to 'discord')
-rw-r--r-- | discord/consts.lua | 45 | ||||
-rw-r--r-- | discord/pylon.lua | 92 | ||||
-rw-r--r-- | discord/the.lua | 24 |
3 files changed, 161 insertions, 0 deletions
diff --git a/discord/consts.lua b/discord/consts.lua new file mode 100644 index 0000000..4727ef6 --- /dev/null +++ b/discord/consts.lua @@ -0,0 +1,45 @@ +local function flip(t) +for k,v in pairs(t) do t[v]=k end return t end + +local opcodes = flip { +[0] = "dispatch", +[1] = "heartbeat", +[2] = "identify", +[3] = "presence update", +[4] = "voice state update", +[6] = "resume", +[7] = "reconnect", +[8] = "request guild members", +[9] = "invalid session", +[10] = "hello", +[11] = "heartbeat ack", +[31] = "request soundboard sounds", +} + +local intents = flip { +guilds = 1 << 0, +guild_members = 1 << 1, +guild_moderation = 1 << 2, +guild_expressions = 1 << 3, +guild_integrations = 1 << 4, +guild_webhooks = 1 << 5, +guild_invites = 1 << 6, +guild_voice_states = 1 << 7, +guild_presences = 1 << 8, +guild_messages = 1 << 9, +guild_message_reactions = 1 << 10, +guild_message_typing = 1 << 11, +direct_messages = 1 << 12, +direct_message_reactions = 1 << 13, +direct_message_typing = 1 << 14, +message_content = 1 << 15, +guild_scheduled_events = 1 << 16, +auto_moderation_configuration = 1 << 20, +auto_moderation_execution = 1 << 21, +guild_message_polls = 1 << 24, +direct_message_polls = 1 << 25, +} +return { + opcodes = opcodes, + intents = intents, +} diff --git a/discord/pylon.lua b/discord/pylon.lua new file mode 100644 index 0000000..7f7549b --- /dev/null +++ b/discord/pylon.lua @@ -0,0 +1,92 @@ +local consts = require'discord.consts' +local opcodes = consts.opcodes +local websocket = require'http.websocket' +local json = require 'dkjson' +local Queue = require 'queue' +local exec_webhook = require'discord.the' +local cqueues = require 'cqueues' +local pylon = require 'pylon' +local pprint = require 'pprint' +local Channel = require 'channel' + +local Discord = pylon.subclass "discord" + +function Discord.init(self) + self:check_config "token" +end + +local function identify_payload(token) + local I = consts.intents + return json.encode{ + op = opcodes.identify, + d = { + properties = { + os = "wilson", browser = "wilson", device = "wilson", + }, + intents = I.guilds + I.guild_messages + I.message_content, + token = token, + } + } +end + +function Discord._connect(self) + local uri = "wss://gateway.discord.gg/?v=10&encoding=json" + self.ws = websocket.new_from_uri(uri) + assert(self.ws:connect()) + self.ws:send(identify_payload(self.token), 'text') +end + +function Discord._heartbeat(self, interval_ms) + local interval = interval_ms / 1000 + cqueues.sleep(interval * math.random()) + while true do + self.ws:send(json.encode{ + op = opcodes.heartbeat, + d = self.sequence_number, + }) + cqueues.sleep(interval) + end +end + +function Discord.recving(self) + for packet in self.ws:each() do + local event = json.decode(packet) + print(event.s, event.op, event.t) + if event.op ~= opcodes.dispatch then + pprint(event.d) + end + + if event.s then self.sequence_number = event.s end + + if event.op == opcodes.hello then + self.cq:wrap(self._heartbeat, self, event.d.heartbeat_interval) + elseif event.op == opcodes.dispatch then + self:handle_dispatch(event) + end + end +end + +function Discord.handle_dispatch(self, event) + local d = event.d + if event.t == 'MESSAGE_CREATE' then + if d.author.id == '293066066605768714' then + self.wilson:deliver(Channel(self, d.channel_id), { + body = d.content, + sender = '[d]' .. d.author.username + }) + end + end +end + +function Discord.sending(self) + for dest_channel, message in self.inbox:iter() do + print('DDD',message.sender,message.body) + exec_webhook(self.temp_wh, { + username = message.sender, + content = message.body, + }) + end +end + +return Discord + diff --git a/discord/the.lua b/discord/the.lua new file mode 100644 index 0000000..d3aaf58 --- /dev/null +++ b/discord/the.lua @@ -0,0 +1,24 @@ +local http_request = require'http.request' +local dkjson = require'dkjson' + +local function exec_webhook(url, payload, debug) + local req = http_request.new_from_uri(url) + req.headers:upsert('content-type','application/json') + req.headers:upsert(':method','POST') + req:set_body(dkjson.encode(payload)) + local resp_head, resp_body = assert(req:go()) + local status = resp_head:get':status' + if debug then + resp_head:dump() + print() + print(resp_body:get_body_as_string()) + end + assert(status:sub(1,1) == '2', 'status was '..status..' not 2xx') +end + +return exec_webhook +-- return { grom = function(from,body) print(body) exec_webhook(url, { +-- content=body, +-- username=from, +-- }, true) end } + |