Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send files via pathanmes #19

Draft
wants to merge 3 commits into
base: clos-everywhere
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/message.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -381,6 +379,23 @@ 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
options))

(defmethod send-audio (bot chat (audio string)
&rest options
&key caption parse-mode caption-entities
Expand Down
41 changes: 21 additions & 20 deletions src/network.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,37 @@
(:report (lambda (condition stream)
(format stream "Request error: ~A" (what condition)))))

(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."
"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)))
(log:debug "Posting data to"
(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))
(multipart-required (find-if #'pathnamep options))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it will be better to use `(some #'pathnamep options) here, because we don't need a pathname as the result:

CL-USER> (some #'pathnamep (list 1 2 #P"foo" #P"bar" 5 6))
T
CL-USER> (find-if #'pathnamep (list 1 2 #P"foo" #P"bar" 5 6))
#P"foo"

(processed-options (process-options options multipart-required))
(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 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*)))
(data (jonathan:parse response)))
(unless (getf data :|ok|)
(log:error "Wrong data received from the server" data)
Expand Down