Explorar el Código

[zsd] Initial commit

Innocenty Enikeev hace 8 años
padre
commit
3f4dbdbeb4
Se han modificado 1 ficheros con 74 adiciones y 0 borrados
  1. 74 0
      plugins/zsd.lisp

+ 74 - 0
plugins/zsd.lisp

@@ -0,0 +1,74 @@
+(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 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
+        (send-response chat-id (zsd/format-changes nil (zsd/load-data token)))
+        (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)
+                (send-response chat-id (zsd/format-changes nil (zsd/load-data token))))
+              (send-response chat-id "Can't auth")))
+        (send-response chat-id "Usage: /zsd-auth <username> <password>"))))