| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- (in-package :cl-user)
- (defpackage chatikbot.macros
- (:use :cl :chatikbot.utils :chatikbot.telegram :chatikbot.crypto)
- (:export :def-db-init
- :with-parsed-message
- :def-message-handler
- :def-message-cmd-handler
- :def-message-admin-cmd-handler
- :with-parsed-callback
- :def-callback-handler
- :def-callback-section-handler
- :def-oauth-handler
- :def-oauth-section-handler
- :defcron))
- (in-package #:chatikbot.macros)
- (defmacro def-db-init (&body body)
- `(add-hook :db-init #'(lambda ()
- (handler-case (progn ,@body)
- (error (e) (log:error e)))
- (values))))
- (defmacro with-parsed-message (message &body body)
- `(let ((message-id (agets ,message "message_id"))
- (from-id (agets ,message "from" "id"))
- (chat-id (agets ,message "chat" "id"))
- (text (agets ,message "text")))
- (declare (ignorable message-id from-id chat-id text))
- ,@body))
- (defmacro def-message-handler (name (message &optional prio) &body body)
- `(progn
- (defun ,name (,message)
- (with-parsed-message ,message
- (handler-case (progn ,@body)
- (error (e)
- (log:error "~A" e)
- (bot-send-message chat-id
- (format nil "Ошибочка вышла~@[: ~A~]"
- (when (member chat-id *admins*) e)))))))
- (when ,prio (setf (get ',name :prio) ,prio))
- (add-hook :update-message ',name)))
- (defmacro def-message-cmd-handler (name (&rest commands) &body body)
- `(def-message-handler ,name (message)
- (when (and text (equal #\/ (char text 0)))
- (multiple-value-bind (cmd args) (parse-cmd text)
- (when (member cmd (list ,@commands))
- (log:info cmd message-id chat-id from-id args)
- ,@body
- t)))))
- (defmacro def-message-admin-cmd-handler (name (&rest commands) &body body)
- `(def-message-handler ,name (message)
- (when (and (member chat-id *admins*)
- text (equal #\/ (char text 0)))
- (multiple-value-bind (cmd args) (parse-cmd text)
- (when (member cmd (list ,@commands))
- (log:info cmd message-id chat-id from-id args)
- ,@body
- t)))))
- (defmacro with-parsed-callback (callback &body body)
- `(let* ((query-id (agets ,callback "id"))
- (from (agets ,callback "from"))
- (raw-data (agets ,callback "data"))
- (source-message (agets ,callback "message"))
- (inline-message-id (agets ,callback "inline_message_id"))
- (from-id (agets from "id"))
- (source-chat-id (agets source-message "chat" "id"))
- (source-message-id (agets source-message "message_id")))
- (declare (ignorable query-id from raw-data source-message inline-message-id
- from-id source-chat-id source-message-id))
- ,@body))
- (defmacro def-callback-handler (name (callback &optional prio) &body body)
- `(progn
- (defun ,name (,callback)
- (with-parsed-callback ,callback
- (handler-case (progn ,@body)
- (error (e)
- (log:error "~A" e)
- (bot-send-message (or source-chat-id from-id)
- (format nil "Ошибочка вышла~@[: ~A~]"
- (when (member source-chat-id *admins*) e)))))))
- (when ,prio (setf (get ',name :prio) ,prio))
- (add-hook :update-callback-query ',name)))
- (defmacro def-callback-section-handler (name (&rest sections) &body body)
- `(def-callback-handler ,name (callback)
- (when source-chat-id
- (multiple-value-bind (data section) (decode-callback-data source-chat-id raw-data)
- (when (member section (list ,@sections))
- (log:info query-id from-id source-chat-id source-message-id section data)
- ,@body
- t)))))
- (defmacro def-oauth-handler (name (code error state &optional prio) &body body)
- `(progn
- (defun ,name (,code ,error ,state)
- (declare (ignorable ,code ,error ,state))
- (handler-case (progn ,@body)
- (error (e)
- (log:error "~A" e)
- (hunchentoot:redirect "/error"))))
- (when ,prio (setf (get ',name :prio) ,prio))
- (add-hook :oauth ',name)))
- (defmacro def-oauth-section-handler (name (&rest sections) &body body)
- `(def-oauth-handler ,name (code error raw-state)
- (multiple-value-bind (state section) (decode-oauth-state raw-state)
- (when (member section (list ,@sections))
- ,@body
- t))))
- ;; Schedule
- (defmacro defcron (name (&rest schedule) &body body)
- (let ((schedule (or schedule '(:minute '* :hour '*)))
- (scheduler (symbol-append name '-scheduler)))
- `(progn
- (defun ,name ()
- (setf *random-state* (make-random-state t))
- (unwind-protect
- (handler-case (progn ,@body)
- (error (e) (log:error "~A" e)))
- (dex:clear-connection-pool)))
- (defun ,scheduler ()
- (clon:schedule-function
- ',name (clon:make-scheduler
- (clon:make-typed-cron-schedule
- ,@schedule)
- :allow-now-p t)
- :name ',name :thread t)
- (values))
- (add-hook :starting ',scheduler))))
|