(in-package #:chatikbot) ;; Load config file (alexandria:when-let (file (probe-file (merge-pathnames "config.lisp" (asdf:component-pathname (asdf:find-system '#:chatikbot))))) (load file)) (defvar *telegram-last-update* nil "Telegram last update_id") (defun process-updates () (loop for update in (telegram-get-updates :offset (and *telegram-last-update* (1+ *telegram-last-update*)) :timeout 60) do (handle-message (aget "message" update)) do (setf *telegram-last-update* (max (or *telegram-last-update* 0) (aget "update_id" update))))) (defun send-dont-understand (chat-id &optional reply-id) (telegram-send-message chat-id "Ну хуууй знает" :reply-to reply-id)) (defun handle-message (message) (let ((id (aget "message_id" message)) (chat-id (aget "id" (aget "chat" message))) (text (aget "text" message))) (log:info "handle-message" message) (when text (if (equal #\/ (char text 0)) (let ((cmd (intern (string-upcase (subseq text 1 (position #\Space text))) "KEYWORD")) (args (when (position #\Space text) (split-sequence:split-sequence #\Space (subseq text (1+ (position #\Space text))))))) (case cmd (:akb (handle-cmd-akb chat-id id args)) (:lastakb (handle-cmd-last-akb chat-id id args)) (otherwise (send-dont-understand chat-id id)))) (telegram-send-message chat-id (format nil "Сам ~A" (replace-all text "@chatikbot " ""))))))) (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") (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) (let ((message "Хуярим аники")) (if (member chat-id *akb-send-to*) (setf message "Не хуярим больше аники" *akb-send-to* (set-difference *akb-send-to* (list chat-id))) (setf *akb-send-to* (cons chat-id *akb-send-to*))) (telegram-send-message chat-id message :reply-to message-id))) (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)))) (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))) (defvar *crons* (list (list #'process-latest-akb '(:minute * :hour *))) "List of cron functions with their schedules") (defvar *cron-timers* nil) (defun start () (mapc #'sb-ext:unschedule-timer *cron-timers*) (setf *cron-timers* (loop for (function schedule) in *crons* do (log:info "Starting cron" function schedule) collect (clon:schedule-function (lambda () (funcall function)) (clon:make-scheduler (apply #'clon:make-typed-cron-schedule schedule) :allow-now-p t) :thread t))) (loop do (process-updates)))