summaryrefslogtreecommitdiff
path: root/quaddle
diff options
context:
space:
mode:
Diffstat (limited to 'quaddle')
-rw-r--r--quaddle/pylon.lua101
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