diff options
Diffstat (limited to 'quaddle')
| -rw-r--r-- | quaddle/pylon.lua | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/quaddle/pylon.lua b/quaddle/pylon.lua new file mode 100644 index 0000000..d176260 --- /dev/null +++ b/quaddle/pylon.lua @@ -0,0 +1,101 @@ +local websocket = require'http.websocket' +local request = require'http.request' +local json = require 'dkjson' +local class = require 'r.class' + +local BasePylon = require 'pylon' +local Channel = require 'channel' + +local Quaddle = class.extend(BasePylon) +function Quaddle.init(self) + self:_check_fields "base_url bot_name bot_password" +end + +-- https://codeberg.org/QWD/Quaddle/src/branch/main/doc/api.md + +function Quaddle._req(self, url, payload) + local req = request.new_from_uri(self.base_url..url) + req.headers:upsert(':method',payload and 'POST' or 'GET') + if self.token then req.headers:upsert('authorization',self.token) end + req.headers:upsert('user-agent','wilson (https://g.gh0.pw/wilson/, v0.0)') + if payload then + req.headers:upsert('content-type','application/json') + req:set_body(assert(json.encode(payload))) end + + local head,body = assert(req:go()) + local status = head:get':status' + local bod = body:get_body_as_string() + + assert(status:match"^2", 'status was '..status..' body '..bod) + + if #bod == 0 then return nil end + local val, _, err = json.decode(bod) + if err then error(err) else return val end +end + +function Quaddle._connect(self) + local r = assert(self:_req("auth/login", { name=self.bot_name, password=self.bot_password })) + self.token = r.token + + self.ws = websocket.new_from_uri(self.base_url:gsub("^http","ws").."app") + assert(self.ws:connect()) + self.ws:send(json.encode{ op="identify", token=self.token }, 'text') + + for busname, bus in pairs(self.wilson.busses) do + for _, channel in ipairs(bus) do + if channel.pylon == self then + self:add_channel(channel) + end + end + end +end + +function Quaddle.add_channel(self, channel) + self.log("Subscribing to channel",channel.descriptor) + self.ws:send(json.encode{ op="subscribe", channel_id=channel.descriptor }) +end + +function Quaddle.recving(self) + for packet in self.ws:each() do + local event = json.decode(packet) + self.log:debug('event', event.event) + if event.event == "ready" then + -- self.session_id = event.session_id + self.bot_user = event.user + self.log("Logged in as id",self.bot_user.id,"name",self.bot_user.name) + elseif event.event == "error" then + self.log:error("Error from server:",event.reasons) + elseif event.event == "message_create" then + self:handle_message(event.message) + elseif event.event == "message_edit" then + -- TODO: wilson doesn't have edits yet + self:handle_message(event.message) + -- elseif event.event == "message_delete" then + -- TODO + else + self.log:debug("Unhandled Quaddle event:",json.encode(event)) + end + end +end + +function Quaddle.handle_message(self, msg) + self.log:proto('<',msg.channel_id,msg.author.username,msg.content) + if msg.author.id ~= self.bot_user.id then + self.wilson:deliver(Channel(self, msg.channel), { + body = msg.content, + sender = '[q]' .. msg.author.name, + }) + end +end + +function Quaddle.sending(self) + for dest_channel, message in self.inbox:iter() do + self.log:proto('>', dest_channel, message.sender, message.body) + + self:_req('channels/'..dest_channel.descriptor..'/messages', { + content = message.sender..": "..message.body, + }) + end +end + +return Quaddle |
