From d31f620f9a3132da3104a517dc344019d2c71185 Mon Sep 17 00:00:00 2001 From: rtmpdavid Date: Fri, 16 Feb 2024 16:46:03 +0300 Subject: [PATCH 1/3] Add a way of sending multi-part data with pathnames --- src/network.lisp | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/network.lisp b/src/network.lisp index a5bbcde..7effc2e 100644 --- a/src/network.lisp +++ b/src/network.lisp @@ -23,9 +23,21 @@ (:report (lambda (condition stream) (format stream "Request error: ~A" (what condition))))) +(defun process-options (&rest options &key (pathname-p nil) &allow-other-keys) + (loop for (key value) + on (alexandria:remove-from-plist options :timeout :streamp :pathname-p) + by #'cddr + when value + if pathname-p + collect (cons (kebab:to-snake-case key) value) + else + collect (kebab:to-snake-case key) + and + collect value)) -(defun make-request (bot name &rest options &key (streamp nil) (timeout 3) &allow-other-keys) - "Perform HTTP request to 'name API method with 'options JSON-encoded object." + +(defun make-request (bot name &rest options &key (streamp nil) (timeout 3) (pathname-p nil) &allow-other-keys) + "Perform HTTP request to 'name API method with 'options JSON-encoded object or multi-part form-data." (declare (ignore streamp)) (let ((url (concatenate 'string (get-endpoint bot) name))) @@ -33,26 +45,14 @@ (obfuscate url) options) (let* ((max-timeout (* timeout 10)) - (processed-options (loop for (key value) - on (alexandria:remove-from-plist options :timeout :streamp) - by #'cddr - when value - collect (kebab:to-snake-case key) - and - collect value)) + (processed-options (apply #'process-options options)) (response - (if *proxy* - (dexador:post url - :headers '(("Content-Type" . "application/json")) - :content (jonathan:to-json processed-options) - :read-timeout max-timeout - :connect-timeout max-timeout - :proxy *proxy*) - (dexador:post url - :headers '(("Content-Type" . "application/json")) - :content (jonathan:to-json processed-options) - :read-timeout max-timeout - :connect-timeout max-timeout))) + (dexador:post url + :headers (unless pathname-p '(("Content-Type" . "application/json"))) + :content (if pathname-p processed-options (jonathan:to-json processed-options)) + :read-timeout max-timeout + :connect-timeout max-timeout + :proxy (if *proxy* *proxy* dex:*default-proxy*))) (data (jonathan:parse response))) (unless (getf data :|ok|) (log:error "Wrong data received from the server" data) From 2c462bfb0aea58416871299657f768e92e359904 Mon Sep 17 00:00:00 2001 From: rtmpdavid Date: Fri, 16 Feb 2024 16:47:20 +0300 Subject: [PATCH 2/3] Add file-based method of sending photos --- src/message.lisp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/message.lisp b/src/message.lisp index 6d02471..fae0ed5 100644 --- a/src/message.lisp +++ b/src/message.lisp @@ -355,8 +355,6 @@ the file.") allow-sending-without-reply reply-markup) "A method for photo sending based on photo ID. -The file-based method does not work yet. - https://core.telegram.org/bots/api#sendphoto" (declare (ignorable caption parse-mode caption-entities disable-notification protect-content reply-to-message-id @@ -381,6 +379,24 @@ https://core.telegram.org/bots/api#sendphoto" (log:debug "Sending photo" chat (get-file-name photo)) (apply #'send-photo bot chat (get-file-id photo) options)) +(defmethod send-photo (bot chat (photo pathname) + &rest options + &key caption parse-mode caption-entities + disable-notification protect-content reply-to-message-id + allow-sending-without-reply reply-markup) + "A method for photo sending based on pathname. + +https://core.telegram.org/bots/api#sendphoto" + (declare (ignorable caption parse-mode caption-entities + disable-notification protect-content reply-to-message-id + allow-sending-without-reply reply-markup)) + (log:debug "Sending photo" chat photo) + (apply #'make-request bot "sendPhoto" + :|chat_id| (get-chat-id chat) + :|photo| photo + :pathname-p t + options)) + (defmethod send-audio (bot chat (audio string) &rest options &key caption parse-mode caption-entities From 9ed8cd7c973579bace1575348fff80a443de2ebf Mon Sep 17 00:00:00 2001 From: rtmpdavid Date: Sat, 24 Feb 2024 23:38:53 +0300 Subject: [PATCH 3/3] Figure out if we need a multi-part request in the request function --- src/message.lisp | 1 - src/network.lisp | 35 ++++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/message.lisp b/src/message.lisp index fae0ed5..81d9dd3 100644 --- a/src/message.lisp +++ b/src/message.lisp @@ -394,7 +394,6 @@ https://core.telegram.org/bots/api#sendphoto" (apply #'make-request bot "sendPhoto" :|chat_id| (get-chat-id chat) :|photo| photo - :pathname-p t options)) (defmethod send-audio (bot chat (audio string) diff --git a/src/network.lisp b/src/network.lisp index 7effc2e..1b95e81 100644 --- a/src/network.lisp +++ b/src/network.lisp @@ -23,20 +23,18 @@ (:report (lambda (condition stream) (format stream "Request error: ~A" (what condition))))) -(defun process-options (&rest options &key (pathname-p nil) &allow-other-keys) - (loop for (key value) - on (alexandria:remove-from-plist options :timeout :streamp :pathname-p) - by #'cddr - when value - if pathname-p - collect (cons (kebab:to-snake-case key) value) - else - collect (kebab:to-snake-case key) - and - collect value)) - - -(defun make-request (bot name &rest options &key (streamp nil) (timeout 3) (pathname-p nil) &allow-other-keys) +(defun process-options (options return-alist-p) + "Process request options, returning alist if required" + (let* ((options (alexandria:remove-from-plist options :timeout :streamp)) + (sanitized-options (loop for (key value) on options by #'cddr + when value + collect (kebab:to-snake-case key) + and collect value))) + (if return-alist-p + (alexandria:plist-alist sanitized-options) + sanitized-options))) + +(defun make-request (bot name &rest options &key (streamp nil) (timeout 3) &allow-other-keys) "Perform HTTP request to 'name API method with 'options JSON-encoded object or multi-part form-data." (declare (ignore streamp)) @@ -45,11 +43,14 @@ (obfuscate url) options) (let* ((max-timeout (* timeout 10)) - (processed-options (apply #'process-options options)) + (multipart-required (find-if #'pathnamep options)) + (processed-options (process-options options multipart-required)) (response (dexador:post url - :headers (unless pathname-p '(("Content-Type" . "application/json"))) - :content (if pathname-p processed-options (jonathan:to-json processed-options)) + :headers (unless multipart-required '(("Content-Type" . "application/json"))) + :content (if multipart-required + processed-options + (jonathan:to-json processed-options)) :read-timeout max-timeout :connect-timeout max-timeout :proxy (if *proxy* *proxy* dex:*default-proxy*)))