瀏覽代碼

Use VK.com API instead of twitter. Add post url. Implement random anek

Innocenty Enikeew 10 年之前
父節點
當前提交
8b51540bcf
共有 2 個文件被更改,包括 67 次插入23 次删除
  1. 37 23
      chatikbot.lisp
  2. 30 0
      vk.lisp

+ 37 - 23
chatikbot.lisp

@@ -45,18 +45,16 @@
                         (split-sequence:split-sequence
                          #\Space (subseq text (1+ (position #\Space text)))))))
             (case cmd
+              (:postakb (handle-cmd-post-akb chat-id id args))
               (:akb (handle-cmd-akb chat-id id args))
-              (:lastakb (handle-cmd-last-akb chat-id id args))
               (otherwise (send-dont-understand chat-id text))))
           (send-dont-understand chat-id text)))))
 
-(defparameter +akb-user-id+ "3021296351" "Twitter user id of 'B-category anecdotes'")
-(defvar *akb-max-count* 5 "Max number of tweets to return per run")
-(defvar *akb-last-id* nil "id of last AKB tweet")
+(defparameter +akb-vk-domain+ "baneks" "VK.com username of 'B-category anekdotes'")
 (defvar *akb-send-to* nil "List of chat-id's to send AKBs to")
 
-(defun handle-cmd-akb (chat-id message-id args)
-  (log:info "handle-cmd-akb" chat-id message-id args)
+(defun handle-cmd-post-akb (chat-id message-id args)
+  (log:info "handle-cmd-post-akb" chat-id message-id args)
   (let ((message "Хуярим аники"))
     (if (member chat-id *akb-send-to*)
         (setf message "Не хуярим больше аники"
@@ -65,28 +63,44 @@
         (setf *akb-send-to* (cons chat-id *akb-send-to*)))
     (telegram-send-message chat-id message)))
 
+(defvar *akb-max-count* 5 "Max number of tweets to return per run")
+(defvar *akb-last-id* 0 "id of last AKB tweet")
+
+(defun format-akb (post)
+  (let* ((id (aget "id" post))
+         (url (format nil "https://vk.com/~A?w=wall~A_~A"
+                      +akb-vk-domain+ (aget "from_id" post) id)))
+    (format nil "~A~%~A" (aget "text" post) url)))
+
 (defun process-latest-akb ()
   (log:info "Getting latest AKBs")
-  (loop for (id . text) in (get-tweets +akb-user-id+
-                                       :since-id *akb-last-id*
-                                       :count *akb-max-count*)
-     do (send-akb text)
-     do (setf *akb-last-id* (max (or *akb-last-id* 0) id))))
+  (dolist (post (reverse (aget "items" (vk-wall-get :domain +akb-vk-domain+
+                                                    :count *akb-max-count*))))
+    (let ((id (aget "id" post)))
+      (when (> id *akb-last-id*)
+        (send-akb (format-akb post))
+        (setf *akb-last-id* id)))))
 
 (defun send-akb (text)
   (log:info "send-akb: ~A" text)
-  (loop for chat-id in *akb-send-to*
-     do (telegram-send-message chat-id
-                               (replace-all text " / " (coerce '(#\Newline) 'string))
-                               :disable-web-preview 1)))
-
-(defun handle-cmd-last-akb (chat-id message-id args)
-  (log:info "handle-cmd-last-akb" chat-id message-id args)
-  (loop for (id . text) in (get-tweets +akb-user-id+
-                                       :count (or (car args) 1))
-     do (telegram-send-message chat-id
-                               (replace-all text " / " (coerce '(#\Newline) 'string))
-                               :disable-web-preview 1)))
+  (dolist (chat-id *akb-send-to*)
+    (handler-case
+        (telegram-send-message chat-id text
+                               :disable-web-preview 1)
+      (error (e) (log:error e)))))
+
+(defun handle-cmd-akb (chat-id message-id args)
+  (log:info "handle-cmd-akb" chat-id message-id args)
+  (let ((total-aneks
+         (aget "count" (vk-wall-get :domain +akb-vk-domain+ :count 1 :offset 10000000))))
+    (dolist (post (aget "items" (vk-wall-get :domain +akb-vk-domain+
+                                             :count (or (ignore-errors (parse-integer (car args))) 1)
+                                             :offset (random total-aneks))))
+      (handler-case
+          (telegram-send-message chat-id
+                                 (format-akb post)
+                                 :disable-web-preview 1)
+        (error (e) (log:error e))))))
 
 
 (defun start ()

+ 30 - 0
vk.lisp

@@ -0,0 +1,30 @@
+(in-package #:chatikbot)
+
+(defparameter +vk-api-url+ "https://api.vk.com/method/~A?v=5.34" "VK.com API endpoint")
+
+(defun %vk-api-call (method &optional args)
+  (let* ((params (loop for (k . v) in args
+                    when v
+                    collect (cons
+                             (princ-to-string k)
+                             (princ-to-string v))))
+         (response (yason:parse
+                    (flexi-streams:octets-to-string
+                     (drakma:http-request (format nil +vk-api-url+ method)
+                                          :method :post
+                                          :parameters params
+                                          :external-format-out :utf8)
+                     :external-format :utf8)
+                    :object-as :alist)))
+    (when (aget "error" response)
+      (error (aget "error_msg" (aget "error" response))))
+    (aget "response" response)))
+
+(defun vk-wall-get (&key owner-id domain offset count filter extended)
+  (%vk-api-call "wall.get"
+                (list (cons "owner_id" owner-id)
+                      (cons "domain" domain)
+                      (cons "offset" offset)
+                      (cons "count" count)
+                      (cons "filter" filter)
+                      (cons "extended" extended))))