(in-package #:chatikbot) (defparameter *fsq-checkins-url* "https://api.foursquare.com/v2/checkins/recent" "URL of recent checkins API") (defvar *fsq-access-token* nil "Access token for a user under which the process is run") (defvar *fsq-last-timestamp* nil "Timestamp of the last checkin. To only fetch latest") (defun fsq-fetch-checkins (&optional after-timestamp) (let* ((resp (yason:parse (flexi-streams:octets-to-string (handler-case (bordeaux-threads:with-timeout (5) (drakma:http-request *fsq-checkins-url* :parameters (list (cons "oauth_token" *fsq-access-token*) (cons "afterTimestamp" (or after-timestamp "0")) (cons "v" "20150811")))) (bordeaux-threads:timeout (e) (declare (ignore e)) (error "Timeout"))) :external-format :utf-8) :object-as :alist)) (meta (aget "meta" resp))) (when (not (= 200 (aget "code" meta))) (error (format nil "Foursquare API error, code ~A, errorType '~A', errorDetail '~A'" (aget "code" meta) (aget "errorType" meta) (aget "errorDetail" meta)))) (aget "recent" (aget "response" resp)))) (defun fsq-fetch-new-checkins () (let ((recent (fsq-fetch-checkins *fsq-last-timestamp*))) (when (first recent) (setf *fsq-last-timestamp* (princ-to-string (1+ (aget "createdAt" (first recent)))))) recent)) (defun fsq-format-checkin (checkin &optional with-dates) (when checkin (let ((user (aget "user" checkin)) (venue (aget "venue" checkin))) (format nil "📍 ~@[~A~]~@[ ~A~]~@[ в ~A~]~@[ (~A)~]~@[ 📢 ~A~]~:[~; ~A~]" (aget "firstName" user) (aget "lastName" user) (aget "name" venue) (first (aget "formattedAddress" (aget "location" venue))) (aget "shout" checkin) with-dates (local-time:format-timestring nil (local-time:unix-to-timestamp (aget "createdAt" checkin)) :format '(:year "-" (:month 2) "-" (:day 2) " " (:hour 2) ":" (:min 2)))))))