diff options
| -rw-r--r-- | main.lua | 1 | ||||
| -rw-r--r-- | quaddle/pylon.lua | 101 | ||||
| -rw-r--r-- | todo.txt | 3 | ||||
| -rw-r--r-- | wilson.ini.example | 8 |
4 files changed, 113 insertions, 0 deletions
@@ -11,6 +11,7 @@ local pylon_classes = { xmpp = require'xmpp.pylon', discord = require'discord.pylon', nanochat = require'nanochat.pylon', + quaddle = require'quaddle.pylon', } local Wilson = class() 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 @@ -2,3 +2,6 @@ pylon.subclass should not have a pylon_type arg. is only used for logging. a pylon's _name_ should be used in log messages. pylons harcode prepend names with [x] [d] [n] etc. this is not robust and is weird it should be in some way dynamic? maybe pylons can have configured short names? but then what in the case of two channels with different users of the same nick? they should not be conflated.. + +discord and quaddle hard-depend on the configured url ending with a / +note that http does not conflate // into / in the path. diff --git a/wilson.ini.example b/wilson.ini.example index 303d8a2..2eb7708 100644 --- a/wilson.ini.example +++ b/wilson.ini.example @@ -26,9 +26,17 @@ server=gloop.woop.example port=44322 poll=5 +[pylon quaddle-boingy] +type=quaddle +base_url=https://boingy.example/ +bot_username=wilson +bot_password=seeeeeecret_password_here + + [bus test] xmpp-barbaz test@conference.example.org irc-boopbanana #test discord-foobar channel_id_here nanochat-gloop #test +quaddle-boingy channel_id_here |
