(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: ~A" message) (when text (if (equal #\/ (char text 0)) (let ((cmd (intern (string-upcase (subseq text 1)) "KEYWORD"))) (case cmd (:akb (toggle-akb chat-id id)) (otherwise (send-dont-understand chat-id id)))) (send-dont-understand chat-id id))))) (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 toggle-akb (chat-id message-id) (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 () (loop for (id . text) in (get-tweets +akb-user-id+ :since-id *akb-last-id* :count *akb-max-count*) do (handle-akb text) do (setf *akb-last-id* (max (or *akb-last-id* 0) id)))) (defun handle-akb (text) (log:info "handle-akb: ~A" text) (loop for chat-id in *akb-send-to* do (telegram-send-message chat-id (replace-all text " / " (coerce '(#\Newline) 'string))))) (defvar *crons* (list (list #'process-latest-akb '(:minute (member 0 5 10 15 20 25 30 35 40 45 50 55))) ) "List of cron functions with their schedules") (defvar *cron-timers* nil) (defun start () (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)))