(in-package #:chatikbot) (defparameter +zsd-api-url+ "https://mcabinet.nch-spb.com/onyma/system/api/json") (defparameter +zsd-auth-url+ "https://mcabinet.nch-spb.com/onyma/system/api/jsonex?function=open_session") (defun %zsd/api (token method &optional args) (let* ((f (concatenate 'string "onm_api_toll_api_" method)) (params (loop for (k . v) in args when v collect (cons (princ-to-string k) (princ-to-string v)))) (response (json-request +zsd-api-url+ :parameters (append params `(("function" . ,f) ("auth_token" . ,token)))))) (values (aget "return" response) (aget "more_rows" response)))) (defun zsd/auth (login password) (aget "return" (json-request +zsd-auth-url+ :method :post :content (plist-json (list :realm "WHSD" :user login :pass password))))) (defun zsd/pan (token) (%zsd/api token "mobile_pan")) (defun zsd/contract (token) (%zsd/api token "contract_info")) (defun zsd/wall (token &optional (offset 0) (limit 5)) (%zsd/api token "mobile_wall" `(("rows_skip" . ,offset) ("rows_limit" . ,limit)))) (defun zsd/load-data (token &optional (limit 5)) `(("contract" . ,(zsd/contract token)) ("pan" . ,(zsd/pan token)) ("wall" . ,(zsd/wall token 0 limit)))) (defun %zsd/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 zsd/format-changes (old new) (let ((wall-diff (set-difference (aget "wall" new) (aget "wall" old) :test #'equal))) (when wall-diff (format nil "ZSD balance: *~A*~%~%~{~A~^~%~}" (aget "remainder" (car (aget "contract" new))) (loop for item in (reverse wall-diff) collect (%zsd/format-wall item (aget "pan" new))))))) (def-message-cmd-handler handle-cmd-zsd (:zsd) (secret/with (token `(:zsd ,chat-id)) (if token (bot-send-message chat-id (zsd/format-changes nil (zsd/load-data token)) :parse-mode "markdown") (send-response chat-id "/zsd-auth")))) (def-message-cmd-handler handle-cmd-zsd-auth (:zsd-auth) (destructuring-bind (login password) args (if (and login password) (let ((token (zsd/auth login password))) (if token (progn (secret/set `(:zsd ,chat-id) token) (bot-send-message chat-id (zsd/format-changes nil (zsd/load-data token)) :parse-mode "markdown")) (send-response chat-id "Can't auth"))) (send-response chat-id "Usage: /zsd-auth "))))