summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Shangreaux <shshoshin@protonmail.com>2019-10-04 13:16:33 -0500
committerGrant Shangreaux <shshoshin@protonmail.com>2019-10-04 13:16:33 -0500
commit58f698906747f5285ce6f6344eea96e05a6931a6 (patch)
tree8dc4ca0b56266672cc2e826a3c218c2911849e2e
parentb98b2f23185980df0592ada3631886d6e31834ce (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.org18
-rw-r--r--examples/roshambot.lisp35
-rw-r--r--granolin.lisp23
-rw-r--r--package.lisp2
-rw-r--r--utility-apps.lisp40
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*)))