;; SPDX-License-Identifier: EUPL-1.2 ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs (defpackage :ukkoclot/transport (:use :c2cl) (:import-from :anaphora :aand :acond :it) (:import-from :cl+ssl) (:import-from :dex) (:import-from :log) (:import-from :ukkoclot/serializing :fixup-args :parse-value) (:import-from :ukkoclot/state :bot-base-uri) (:local-nicknames (:jzon :com.inuoe.jzon)) (:export :do-call)) (in-package :ukkoclot/transport) (defun req (uri method content) (let ((retrier (dex:retry-request 5 :interval 1)) ;; This is needed to avoid hangs, ;; see https://github.com/fukamachi/dexador/issues/91#issuecomment-1093472364 (cl+ssl:*default-unwrap-stream-p* nil)) (handler-case (dex:request uri :method method :content content :read-timeout 60 :connect-timeout 60) ;; We deal with too many requests manually (dex:http-request-too-many-requests (e) (dex:ignore-and-continue e)) (dex:http-request-failed (e) (funcall retrier e)) (cl+ssl::ssl-error (e) (funcall retrier e))))) (defun do-call% (method uri out-type args-encoded) (let ((body (req uri method args-encoded))) (let ((hash (jzon:parse body))) (acond ((gethash "ok" hash) (parse-value out-type (gethash "result" hash))) ((aand (gethash "parameters" hash) (gethash "retry_after" it)) (log:info "Should sleep for ~A seconds" it) (sleep it) (log:info "Good morning!") (do-call% method uri out-type args-encoded)) (t (error "TG error ~A: ~A ~:A" (gethash "error_code" hash) (gethash "description" hash) (gethash "parameters" hash))))))) (defun do-call (bot method path out-type args) (let ((uri (concatenate 'string (bot-base-uri bot) path)) (args-encoded (fixup-args args))) (log:debug "~A .../~A ~S" method path args-encoded) (do-call% method uri out-type args-encoded)))