diff options
author | Grant Shangreaux <shshoshin@protonmail.com> | 2019-10-04 13:16:33 -0500 |
---|---|---|
committer | Grant Shangreaux <shshoshin@protonmail.com> | 2019-10-04 13:16:33 -0500 |
commit | 58f698906747f5285ce6f6344eea96e05a6931a6 (patch) | |
tree | 8dc4ca0b56266672cc2e826a3c218c2911849e2e | |
parent | b98b2f23185980df0592ada3631886d6e31834ce (diff) |
Clean: *room-id* special var refactoring handle-event generic
This addresses the conversation in issue #1. I went ahead and created the readme
file to document the `*room-id*` variable. Also this commit removes the
hardcoded value for the roshamo example bot, and provides a function to create
and login your roshambot instead.
-rw-r--r-- | README.org | 18 | ||||
-rw-r--r-- | examples/roshambot.lisp | 35 | ||||
-rw-r--r-- | granolin.lisp | 23 | ||||
-rw-r--r-- | package.lisp | 2 | ||||
-rw-r--r-- | utility-apps.lisp | 40 |
5 files changed, 60 insertions, 58 deletions
diff --git a/README.org b/README.org new file mode 100644 index 0000000..0c5c20d --- /dev/null +++ b/README.org @@ -0,0 +1,18 @@ +* Granolin + +Build better bots, for matrix! + +* Event Handlers +** Special Variables +*** *room-id* + +The special variable =*room-id*= is available in your =handle-event= methods. +It will have the value of the Matrix room id in which the event occured. It +will be =nil= if the event is not a room state nor timeline/message event. + +For example: + +#+begin_src common-lisp +(defmethod handle-event :after ((cli echo-bot) (ev text-message-event)) + (send-text-message cli *room-id* (msg-body ev))) +#+end_src diff --git a/examples/roshambot.lisp b/examples/roshambot.lisp index 1062302..48ed49d 100644 --- a/examples/roshambot.lisp +++ b/examples/roshambot.lisp @@ -4,12 +4,6 @@ (defpackage #:roshambot (:use :cl :granolin)) - ;; (:import-from :granolin - ;; :handle-event - ;; :find-contact - ;; :text-message-event - ;; :send-text-message - ;; :let-cond)) (in-package :roshambot) @@ -58,14 +52,14 @@ (defun roshambo-move!? (str) (nth-value 0 (ppcre:scan-to-strings +roshambo-move-regex+ str))) -(defmethod handle-event :after ((bot roshambot) (event text-message-event) &optional room-id) +(defmethod handle-event :after ((bot roshambot) (event text-message-event)) (let ((text (granolin:msg-body event))) (let-cond (challenged (you-wanna-piece-of-this!? text) - (handle-new-challenge bot room-id (granolin:sender event) challenged)) - (roshambo-match (challenger-made-move!? bot room-id (granolin::sender event) text) + (handle-new-challenge bot *room-id* (granolin:sender event) challenged)) + (roshambo-match (challenger-made-move!? bot *room-id* (granolin::sender event) text) (handle-match-state-change bot roshambo-match)) - (roshambo-match (challenged-made-move!? bot room-id (granolin::sender event) text) + (roshambo-match (challenged-made-move!? bot *room-id* (granolin::sender event) text) (handle-match-state-change bot roshambo-match))))) (defun challenger-made-move!? (bot room-id sender text) @@ -207,19 +201,14 @@ (defclass roshambo-bot (granolin:client granolin:server-directory roshambot auto-joiner) ()) -;; (defmethod handle-event :after ((bot roshambot-bot) (ev timeline-event) &optional room-id) -;; (format t "~a - ~a:~% ~a~%" room-id (granolin::sender ev) (granolin:msg-body ev))) +(defmethod handle-event :after ((bot roshambo-bot) (ev text-message-event)) + (format t "~a - ~a:~% ~a~%" *room-id* (granolin::sender ev) (granolin:msg-body ev))) -(defmethod handle-event :after ((bot roshambo-bot) (ev text-message-event) &optional room-id) - (format t "~a - ~a:~% ~a~%" room-id (granolin::sender ev) (granolin:msg-body ev))) - -(defmethod handle-event :after ((bot roshambo-bot) - (ev granolin::account-data-event) - &optional room-id) +(defmethod handle-event :after ((bot roshambo-bot) (ev granolin::account-data-event)) (format t "~a ~a" (event-type ev) (event-content ev))) - -(defvar *roshambot* (make-instance 'roshambo-bot - :homeserver "https://matrix.hrlo.world")) - - +;; creates and authenticates the bot, returns the bot instance +(defun roshambot (homeserver user password) + (let ((bot (make-instance 'roshambo-bot :homeserver homeserver))) + (login bot user password) + bot)) diff --git a/granolin.lisp b/granolin.lisp index f743734..0460ac2 100644 --- a/granolin.lisp +++ b/granolin.lisp @@ -105,9 +105,9 @@ (when (and (hardcopy client) (probe-file (hardcopy client))) (load-client-state client))) -(defgeneric handle-event (client event &optional room-id) +(defgeneric handle-event (client event) (:documentation "Implemented on handlers that need to respond to events.") - (:method ((client client) event &optional room-id) t)) + (:method ((client client) event) t)) (defgeneric clean-up (client) (:documentation "To be run before the client crashes or is killed.") @@ -126,6 +126,8 @@ "Dynamic variable holding response status headers.") (defvar *response-object* nil "Dynamic variable holding a RESPONSE-OBJECT struct.") +(defvar *room-id* nil + "Dynamic variable holding id of the room whose event is being processed.") ;;; Utilities for working with parsed JSON data @@ -383,28 +385,27 @@ (defun process-joined-events (client) (loop :for (room-id room . ignore) :on (joined-rooms *response-object*) :by #'cddr :do - ;; room-id should be a string - (setf room-id (symbol-name room-id)) + (let ((*room-id* (symbol-name room-id))) ;; room-id should be a string ;; handle the timeline events (aka room events) (dolist (ob (getob room :|timeline| :|events|)) (handle-event client - (categorize-and-set-timeline-event ob) - room-id)) + (categorize-and-set-timeline-event ob))) ;; handle state chnage events (aka state events) (dolist (ob (getob room :|state| :|events|)) (setf (room-state-event-data *state-event*) ob) - (handle-event client *state-event* room-id)))) + (handle-event client *state-event*))))) ;; TODO add global cache variable for invite event (defun process-invited-room-events (client) (let ((invite-event (make-invitation-event :data nil))) (loop :for (room-id room . ignore) :on (invited-rooms *response-object*) :by #'cddr :do - (setf room-id (symbol-name room-id)) - (dolist (ob (getob room :|invite_state| :|events|)) - (setf (invitation-event-data invite-event) ob) - (handle-event client invite-event room-id))))) + (let ((*room-id* (symbol-name room-id))) + + (dolist (ob (getob room :|invite_state| :|events|)) + (setf (invitation-event-data invite-event) ob) + (handle-event client invite-event)))))) (defun process-account-data-events (client) (dolist (ob (account-data-events *response-object*)) diff --git a/package.lisp b/package.lisp index c88d8f6..0368c9c 100644 --- a/package.lisp +++ b/package.lisp @@ -88,4 +88,6 @@ #:start #:stop + ;; special variables + #:*room-id* )) diff --git a/utility-apps.lisp b/utility-apps.lisp index 8395805..d9834ad 100644 --- a/utility-apps.lisp +++ b/utility-apps.lisp @@ -19,11 +19,11 @@ (loop :for (k . v) :in alist :do (format stream "~a: ~a~%" k v))) -(defmethod handle-event :after ((log message-log) (event timeline-event) &optional room) +(defmethod handle-event :after ((log message-log) (event timeline-event)) (when (logging-p log) (print "Joined Room Message/Timeline Event" (output log)) (terpri (output log)) - (let ((fields `(("room" . ,room) + (let ((fields `(("room" . ,*room-id*) ("sender" . ,(sender event)) ("event type" . ,(event-type event)) ("message type" . ,(msg-type event)) @@ -33,11 +33,11 @@ (terpri (output log))))) -(defmethod handle-event :after ((log message-log) (event room-state-event) &optional room) +(defmethod handle-event :after ((log message-log) (event room-state-event)) (when (logging-p log) (print "Joined Room State Event" (output log)) (terpri (output log)) - (let ((fields `(("room" . ,room) + (let ((fields `(("room" . ,*room-id*) ("sender" . ,(sender event)) ("event type" . ,(event-type event)) ("state key" . ,(state-key event)) @@ -45,8 +45,7 @@ (print-assoc fields (output log)) (terpri (output log))))) -(defmethod handle-event :after ((log message-log) (event account-data-event) &optional room) - (declare (ignore room)) +(defmethod handle-event :after ((log message-log) (event account-data-event)) (when (logging-p log) (print "Account Data Event" (output log)) (terpri (output log)) @@ -56,11 +55,11 @@ (terpri (output log)))) -(defmethod handle-event :after ((log message-log) (event invitation-event) &optional room) +(defmethod handle-event :after ((log message-log) (event invitation-event)) (when (logging-p log) (print "Invitation Event" (output log)) (terpri (output log)) - (let ((fields `(("room" . ,room) + (let ((fields `(("room" . ,*room-id*) ("sender" . ,(sender event)) ("event type" . ,(event-type event)) ("state key" . ,(state-key event)) @@ -110,29 +109,22 @@ (defun update-room-aliases (client room-id member) (declare (ignore client room-id member))) -(defmethod handle-event :after ((client server-directory) - (event room-state-event) - &optional room-id) +(defmethod handle-event :after ((client server-directory) (event room-state-event)) (cond ((string= "m.room.name" (event-type event)) - (update-room-name client room-id (room-name event))) + (update-room-name client *room-id* (room-name event))) ((string= "m.room.member" (event-type event)) - (update-room-member client room-id (sender event))) + (update-room-member client *room-id* (sender event))) ((string= "m.room.aliases" (event-type event)) - (update-room-aliases client room-id (room-aliases event))))) + (update-room-aliases client *room-id* (room-aliases event))))) -(defmethod handle-event :after ((client server-directory) - (event timeline-event) - &optional room-id) - (update-room-member client room-id (sender event))) +(defmethod handle-event :after ((client server-directory) (event timeline-event)) + (update-room-member client *room-id* (sender event))) -(defmethod handle-event :after ((client server-directory) - (event account-data-event) - &optional room-id) - (declare (ignore room-id)) +(defmethod handle-event :after ((client server-directory) (event account-data-event)) (when (equal "m.direct" (event-type event)) (setf (m-direct-event-content client) (event-content event)) (loop :for (user room-ids . more) :on (event-content event) :by #'cddr :do @@ -248,8 +240,8 @@ (defclass auto-joiner () ()) -(defmethod handle-event :after ((client auto-joiner) (event invitation-event) &optional room-id) +(defmethod handle-event :after ((client auto-joiner) (event invitation-event)) (when (equal "invite" (getf (event-content event) :|join_rule|)) - (join-room client room-id))) + (join-room client *room-id*))) |