diff options
| author | Andrei <andreisva2023@gmail.com> | 2026-02-16 22:23:10 -0800 |
|---|---|---|
| committer | Andrei <andreisva2023@gmail.com> | 2026-02-16 22:23:10 -0800 |
| commit | 2d07d8be96fa2e3a58b524a85245d802c54bc63b (patch) | |
| tree | ca688e7f29ec8f0216f1491eed35ba8084d88d39 /src/api.lisp | |
| parent | 8c9f8f8fac956f88acea75f805965788a947581d (diff) | |
Add some more api functions and atom feed integration
Diffstat (limited to 'src/api.lisp')
| -rw-r--r-- | src/api.lisp | 98 |
1 files changed, 73 insertions, 25 deletions
diff --git a/src/api.lisp b/src/api.lisp index fb4cc20..3ed133a 100644 --- a/src/api.lisp +++ b/src/api.lisp @@ -1,4 +1,6 @@ -;; readers beware: this is currently a very barebones library +;; readers beware: this is currently a very barebones (and amateurish) library +;; +;; In the future it might be packaged into its own thing (defpackage nullbot/matrix-api (:use #:cl @@ -17,10 +19,15 @@ #:sendmsg #:on-event #:start - #:stop)) + #:stop + #:whoami + #:request + #:join + #:leave + #:room-id)) (in-package #:nullbot/matrix-api) -(defclass matrix-user () +(defclass matrix-client () ((homeserver :type string :initarg :homeserver @@ -45,11 +52,30 @@ :initform (bt2:make-lock) :reader lock))) -(defclass matrix-bot (matrix-user) () +;; these are not perfect functions by any means but matrix has +;; many different room versions with different formats +;; this is what the official matrix-bot-sdk does as well +(defun room-id-p (object) + (and (stringp object) + (> (length object) 0) + (equal (aref object 0) #\!))) + +(defun room-alias-p (object) + (and (stringp object) + (> (length object) 0) + (equal (aref object 0) #\#))) + +(deftype room-id () + '(and string (satisfies room-id-p))) + +(deftype room-alias () + '(and string (satisfies room-alias-p))) + +(defclass matrix-bot (matrix-client) () (:default-initargs :name "matrix-bot")) (defgeneric request (obj endpoint &rest rest) - (:method ((obj matrix-user) endpoint &rest rest &aux (headers)) + (:method ((obj matrix-client) endpoint &rest rest &aux (headers)) (declare (type string endpoint)) (when (>= (length rest) 3) (setf headers (car (last rest)))) @@ -63,7 +89,7 @@ :verbose nil)))) (defgeneric on-event (obj event room-id) - (:method ((obj matrix-user) event room-id) + (:method ((obj matrix-client) event room-id) (format t "Event Received: ~a~%" event))) (defun randint (start end) @@ -75,7 +101,7 @@ (fs:octets-to-string arr)) (defgeneric sendmsg (obj room-id content) - (:method ((obj matrix-user) room-id content + (:method ((obj matrix-client) room-id content &aux (msg (make-hash-table :test #'equal)) (encoded-room-id (quri:url-encode room-id)) @@ -89,8 +115,30 @@ msg '(("Content-Type" . "application/json"))))) +(defgeneric whoami (obj) + (:method ((obj matrix-client)) + (request obj "/account/whoami" :get))) + +(defgeneric directory-room (obj room-alias) + (:method ((obj matrix-client) room-alias) + (check-type room-alias room-alias) + )) + +(defgeneric join (obj room) + (:method ((obj matrix-client) room) + (request obj (format nil "/rooms/~a/join" + (quri:url-encode room)) + :get))) + +(defgeneric leave (obj room-id) + (:method ((obj matrix-client) room-id) + (check-type room-id room-id) + (request obj (format nil "/rooms/~a/leave" + (quri:url-encode room-id)) + :post))) + (defgeneric get-events (obj rooms-join room-id) - (:method ((obj matrix-user) rooms-join room-id + (:method ((obj matrix-client) rooms-join room-id &aux (room-table (gethash room-id rooms-join)) (events @@ -100,23 +148,23 @@ (on-event obj event room-id))))) (defgeneric start (obj) - (:method-combination progn) - (:method ((obj matrix-user)) - (setf (listening obj) t) - (bt2:make-thread (lambda (&aux - (since) - (sync-route "/sync?timeout=30000")) - (loop while (bt2:with-lock-held ((lock obj)) (listening obj)) do - (when since - (setf sync-route (format nil "/sync?timeout=30000&since=~a" since))) - (let* ((response (request obj sync-route :get)) - (rooms-join (hash-get response '("rooms" "join")))) - (when rooms-join (loop for room-id being each hash-key of rooms-join - do (when since (get-events obj rooms-join room-id)))) - (setf since (gethash "next_batch" response)))) - (format t "Shutting down...~%")) - :name (format nil "~a Poll Thread" (name obj))))) + (:method ((obj matrix-client)) + (unless (listening obj) + (setf (listening obj) t) + (bt2:make-thread (lambda (&aux + (since) + (sync-route "/sync?timeout=30000")) + (loop while (bt2:with-lock-held ((lock obj)) (listening obj)) do + (when since + (setf sync-route (format nil "/sync?timeout=30000&since=~a" since))) + (let* ((response (request obj sync-route :get)) + (rooms-join (hash-get response '("rooms" "join")))) + (when rooms-join (loop for room-id being each hash-key of rooms-join + do (when since (get-events obj rooms-join room-id)))) + (setf since (gethash "next_batch" response)))) + (format t "Shutting down...~%")) + :name (format nil "~a Poll Thread" (name obj)))))) (defgeneric stop (obj) - (:method ((obj matrix-user)) + (:method ((obj matrix-client)) (bt2:with-lock-held ((lock obj)) (setf (listening obj) nil)))) |
