Make sico work with the new matrix-api
parent
1cefe5b105
commit
941b0aa867
110
sico.el
110
sico.el
|
@ -63,6 +63,10 @@ Matrix/Emacs robot butler."
|
|||
:type '(repeat string)
|
||||
:group 'sico)
|
||||
|
||||
(defcustom sico-username nil
|
||||
"What is the username of sico"
|
||||
:type 'string :group 'sico)
|
||||
|
||||
(defcustom sico-capture-note-regexp "^!note\\b\\(.*\\)"
|
||||
"Regular expression defining how to capture notes.
|
||||
|
||||
|
@ -93,56 +97,95 @@ single argument."
|
|||
"Hello, my name is Sico and I am pleased to be of service."
|
||||
"The message the bot says upon joining each room.")
|
||||
|
||||
(defvar sico-current-end-token nil)
|
||||
(defvar sico-running nil)
|
||||
(defvar sico-active-connection nil)
|
||||
|
||||
(defclass sico-connection (matrix-connection)
|
||||
((running :initarg :running
|
||||
:initform nil
|
||||
:documentation "BOOL specifiying if the event listener is currently running.")
|
||||
(rooms :initarg :rooms
|
||||
:initform nil
|
||||
:documentation "List of matrix-room objects")
|
||||
(end-token :initarg :end-token)))
|
||||
|
||||
(defun sico-start ()
|
||||
"Start Assitant and connect it to the Matrix homeserver."
|
||||
(interactive)
|
||||
(unless matrix-token
|
||||
(matrix-client-login))
|
||||
(unless sico-active-connection
|
||||
(setq sico-active-connection (sico-connection matrix-homeserver-base-url :base-url matrix-homeserver-base-url))
|
||||
(sico-login sico-active-connection sico-username))
|
||||
(sico-join-rooms)
|
||||
(sico-start-polling)
|
||||
(setq sico-running t))
|
||||
|
||||
(defmethod sico-login ((con sico-connection) username)
|
||||
(let* ((auth-source-creation-prompts
|
||||
'((username . "Matrix identity: ")
|
||||
(secret . "Matrix password for %u (homeserver: %h): ")))
|
||||
(found (nth 0 (auth-source-search :max 1
|
||||
:host (oref con :base-url)
|
||||
:user username
|
||||
:require '(:user :secret)
|
||||
:create t))))
|
||||
(when (and
|
||||
found
|
||||
(matrix-login-with-password con
|
||||
(plist-get found :user)
|
||||
(let ((secret (plist-get found :secret)))
|
||||
(if (functionp secret)
|
||||
(funcall secret)
|
||||
secret)))
|
||||
(let ((save-func (plist-get found :save-function)))
|
||||
(when save-func (funcall save-func)))))))
|
||||
|
||||
(defun sico-stop ()
|
||||
"Tell sico to stop polling."
|
||||
(setq sico-running nil))
|
||||
(interactive)
|
||||
(oset sico-active-connection :running nil)
|
||||
(setq sico-active-connection nil))
|
||||
|
||||
(defun sico-start-polling ()
|
||||
"Begin polling for events with the [`sico-poll-callback'] as the handler."
|
||||
(matrix-event-poll sico-current-end-token
|
||||
10
|
||||
'sico-poll-callback))
|
||||
(let* ((con sico-active-connection)
|
||||
(next (and (slot-boundp con :end-token)
|
||||
(oref con :end-token))))
|
||||
(matrix-sync con next (if next nil t) 10
|
||||
(apply-partially #'sico-sync-handler con))))
|
||||
|
||||
(defun sico-join-rooms ()
|
||||
"Join the rooms that Sico is configured to be in."
|
||||
(dolist (room sico-rooms)
|
||||
(matrix-join-room room)
|
||||
(matrix-send-message room sico-connection-string)))
|
||||
(matrix-join-room sico-active-connection room)
|
||||
(when (> (length sico-connection-string) 0)
|
||||
(matrix-send-message sico-active-connection room sico-connection-string))))
|
||||
|
||||
(defun sico-poll-callback (data)
|
||||
"The callback triggered by [`matrix-event-poll'].
|
||||
(defmethod sico-sync-handler ((con sico-connection) data)
|
||||
(mapc
|
||||
(lambda (room-data)
|
||||
(let* ((room-id (symbol-name (car room-data)))
|
||||
(room-events (cdr room-data))
|
||||
(handler (lambda (item)
|
||||
(dolist (cell sico-listeners)
|
||||
(let ((content (matrix-get 'content item))
|
||||
(type (matrix-get 'type item)))
|
||||
(when (and content
|
||||
(string= type "m.room.message")
|
||||
(string-match (car cell)
|
||||
(matrix-get 'body content)))
|
||||
(message "match %s: %s" content cell)
|
||||
(funcall (cdr cell) con room-id item)))))))
|
||||
(mapc handler
|
||||
(matrix-get 'events (matrix-get 'state room-events)))
|
||||
(mapc handler
|
||||
(matrix-get 'events (matrix-get 'timeline room-events)))))
|
||||
(matrix-get 'join (matrix-get 'rooms data)))
|
||||
(let ((next (matrix-get 'next_batch data)))
|
||||
(oset con :end-token next)
|
||||
(when (and (slot-boundp con :running)
|
||||
(oref con :running))
|
||||
(sico-start-polling))))
|
||||
|
||||
DATA comes directly from the Matrix homeserver, massaged in to a
|
||||
sexp by [`json-parse']"
|
||||
(if (eq (car data) 'error)
|
||||
(message "%s" data)
|
||||
(let* ((chunk (matrix-get 'chunk data)))
|
||||
(setq sico-current-end-token (matrix-get 'end data))
|
||||
(mapc (lambda (item)
|
||||
(dolist (cell sico-listeners)
|
||||
(let ((content (matrix-get 'content item))
|
||||
(type (matrix-get 'type item)))
|
||||
(when (and content
|
||||
(string= type "m.room.message")
|
||||
(string-match (car cell)
|
||||
(matrix-get 'body content)))
|
||||
(funcall (cdr cell) item))))) chunk)))
|
||||
(when sico-running
|
||||
(sico-start-polling)))
|
||||
|
||||
(defun sico-capture-note (event)
|
||||
(defun sico-capture-note (con room-id event)
|
||||
"Capture a note from EVENT."
|
||||
(let* ((content (matrix-get 'content event))
|
||||
(body (matrix-get 'body content))
|
||||
|
@ -150,11 +193,14 @@ sexp by [`json-parse']"
|
|||
(match (match-string 1 body))
|
||||
(user-id (matrix-get 'sender event))
|
||||
(room-id (matrix-get 'room_id event)))
|
||||
(message "matchdata: %s %s %s" body match sico-capture-note-regexp)
|
||||
(when (member user-id sico-users)
|
||||
(message "userid %s: %s" user-id sico-users)
|
||||
(kill-new match)
|
||||
(org-capture nil sico-capture-note-template)
|
||||
(matrix-send-message room-id
|
||||
(matrix-send-message sico-active-connection room-id
|
||||
(format "I have captured: \"%s\"" match)))))
|
||||
|
||||
(provide 'sico)
|
||||
;;; sico.el ends here
|
||||
|
||||
|
|
Loading…
Reference in New Issue