(in-package :cl-user) (defpackage chatikbot.plugins.zsd (:use :cl :chatikbot.common)) (in-package :chatikbot.plugins.zsd) (defparameter +api-uri+ "https://mcabinet.nch-spb.com/onyma/system/api/json") (defparameter +auth-uri+ "https://mcabinet.nch-spb.com/onyma/system/api/jsonex?function=open_session") (defparameter +method-prefix+ "onm_api_toll_api_") ;; poller methods (defmethod poller-request ((module (eql :zsd)) method &rest params) (agets (json-request +api-uri+ :parameters (append `(("function" . ,(concatenate 'string +method-prefix+ method)) ("auth_token" . ,*poller-token*)) (rest-parameters params))) "return")) (defmethod poller-validate ((module (eql :zsd)) response) response) (defmethod poller-get-token ((module (eql :zsd)) secret) (destructuring-bind (username . password) secret (agets (json-request +auth-uri+ :method :post :content (plist-json (list :realm "WHSD" :user username :pass password))) "return"))) ;; API (defun pan () (poller-call :zsd "mobile_pan")) (defun contract () (poller-call :zsd "contract_info")) (defun wall (&optional (offset 0) (limit 5)) (poller-call :zsd "mobile_wall" :rows-skip offset :rows-limit limit)) (defun format-wall (item pans) (let* ((pan (aget "pan" item)) (alias (aget "alias" (find pan pans :test #'equal :key (lambda (el) (aget "pan" el))))) (event (parse-integer (aget "event_type" item))) (amount (aget "amount" item)) (entry (aget "entry_place" item)) (place (aget "place" item)) (cdt (aget "cdt" item))) (case event (1 (format nil "~A *~aр.*: 🚗 ~a, _~a → ~a_" cdt amount (or alias pan) entry place)) (101 (format nil "~A *~aр.*: 💶 _~a_" cdt amount place))))) (defun format-changes (wall-diff contract pans) (format nil "ЗСД остаток: *~$р.*~%~%~{~A~^~%~}" (parse-float (aget "remainder" (car contract))) (loop for item in wall-diff collect (format-wall item pans)))) (defcron process-zsd (:minute '(member 0 5 10 15 20 25 30 35 40 45 50 55)) (poller-poll-lists :zsd #'wall #'(lambda (diff) (bot-send-message (format-changes diff (contract) (pan)) :parse-mode "markdown")) :key #'(lambda (w) (local-time:timestamp-to-universal (local-time:parse-timestring (aget "dt" w)))))) (defun handle-set-cron (enable) (lists-set-entry :zsd *chat-id* enable) (bot-send-message (if enable "Включил рассылку. '/zsd off' чтобы выключить, /zsd - показать последние." "Без рассылки. '/zsd on' - включить, /zsd - последние."))) (defun handle-auth (login pass) (handler-case (progn (poller-authenticate :zsd (cons login pass)) (handle-set-cron t)) (poller-cant-authenticate () (bot-send-message "Чот не смог, пропробуй другие.")))) (defun handle-recent () (bot-send-message (handler-case (format-changes (wall) (contract) (pan)) (poller-error () "Нужен логин-пароль. /zsd ")) :parse-mode "markdown")) (def-message-cmd-handler handle-cmd-zsd (:zsd) (cond ((= 1 (length *args*)) (handle-set-cron (equal "on" (car *args*)))) ((= 2 (length *args*)) (apply 'handle-auth *args*)) (:otherwise (handle-recent))))