-
Notifications
You must be signed in to change notification settings - Fork 4
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
deprecate file.upload and implement new apis #11
Conversation
I feel like this change with additional |
lib/api.ml
Outdated
|
||
val get_upload_url_external : ctx:Context.t -> req:get_upload_url_ext_req -> get_upload_url_ext_res slack_response Lwt.t | ||
val complete_upload_external : ctx:Context.t -> req:complete_upload_ext_req -> complete_upload_ext_res slack_response Lwt.t | ||
val upload_file_v2 : ctx:Context.t -> file:files_upload_req -> files_upload_res slack_response Lwt.t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know other slack SDK have used the v2
naming scheme, but since we have the exact same type, I don't see the point. What downside is there to just replacing upload_file
?
lib/api.ml
Outdated
there is upload_file_v2 convenience function"] | ||
|
||
val get_upload_url_external : ctx:Context.t -> req:get_upload_url_ext_req -> get_upload_url_ext_res slack_response Lwt.t | ||
val complete_upload_external : ctx:Context.t -> req:complete_upload_ext_req -> complete_upload_ext_res slack_response Lwt.t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why expose the substeps ? If we do not, it can also be remove from the api_local implementation.
Is it in the case that you want to do multiple uploads of the same file ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It gives us the flexibility to upload multiple files* simultaneously if that's desired in the future. But I see your point, to cut down on the extra cruft I'll hide it from the signature
lib/api_remote.ml
Outdated
~name:(sprintf "files.completeUploadExternal (%s)" @@ Slack_j.string_of_files_v2 req.files) | ||
~body `POST "files.completeUploadExternal" Slack_j.read_complete_upload_ext_res | ||
|
||
(** NOTE: this api only can specify one channel_id unlike in the deprecated version *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can actually specify multiple channels. The channel_id field only excpects 1, but there is a channels field where you can add multiples. https://api.slack.com/methods/files.completeUploadExternal
d721cda
to
0435af8
Compare
0435af8
to
33299ba
Compare
3f022a4
to
bf2d4ac
Compare
bf2d4ac
to
dab5247
Compare
abd61c3
to
4cdc6f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please revisit this code and add support for snippets that don't come from a file and better error handling.
Add tests to the backlog, if it will take you too much time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these kinds of changes should be sent directly to master. These are unrelated to the PR
let json = | ||
req |> Slack_j.string_of_get_upload_url_ext_req |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string | ||
in | ||
printf "getting upload url for %s\n" req.filename; | ||
printf "%s\n" json; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this debugging logic?
Are you adding tests to these functions? it seems that this logic should live in the test file?
(same below, for complete_upload_external)
let args = www_form_of_get_upload_url_ext req in | ||
let data = Web.make_url_args args in | ||
let body = `Raw ("application/x-www-form-urlencoded", data) in | ||
log#info "data to upload req: %s" data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should these be log#debug
? I'm not sure that the users want to log this data for all requests
log#info "completing upload url for %s" @@ Slack_j.string_of_files_v2 req.files; | ||
let data = Slack_j.string_of_complete_upload_ext_req req in | ||
let body = `Raw ("application/json", data) in | ||
log#info "data to upload req: %s" data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
match file.filename, file.content with | ||
| None, _ | _, None -> Exn.fail "need to supply both filename and content" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think it would make more sense to separate the concerns regarding the file itself and the upload config. These are all "crammed" in files_upload_req
, but could easily be separated.
Or don't call the argument file
, which it's not.
| Error e -> Lwt.return_error e | ||
| Ok { upload_url; file_id; _ } -> | ||
let raw_file_contents = In_channel.with_open_bin filename (fun ic -> input_all ic) in | ||
let body = `Raw ("", raw_file_contents) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let body = `Raw ("", raw_file_contents) in | |
let body = `Raw ("text/plain", raw_content) in |
let req = Slack_j.make_get_upload_url_ext_req ~filename ~length () in | ||
( match%lwt get_upload_url_external ~ctx ~req with | ||
| Error e -> Lwt.return_error e | ||
| Ok { upload_url; file_id; _ } -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slack api fails with a 200 OK response but sends the ok
property of the payload as false and includes an error
property on the response.
Error responses aren't properly handled here or below, after the complete_upload_external
response.
let req = Slack_j.make_complete_upload_ext_req ~files ?channels:file.channels ?thread_ts:file.thread_ts () in | ||
( match%lwt complete_upload_external ~ctx ~req with | ||
| Error e -> Lwt.return_error e | ||
| Ok { files; _ } -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment above regarding slack failing with 200 OK
log#info "getting upload url for %s" req.filename; | ||
let args = www_form_of_get_upload_url_ext req in | ||
let data = Web.make_url_args args in | ||
let body = `Raw ("application/x-www-form-urlencoded", data) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you want to use application/x-www-form-urlencoded
here instead of text/plain
, you should use `Form instead of `Raw
@@ -113,6 +100,72 @@ let get_permalink ~(ctx : Context.t) ~(req : Slack_t.get_permalink_req) = | |||
~name:(sprintf "chat.getPermalink (%s, %s)" req.channel req.message_ts) | |||
~ctx `GET api_path Slack_j.read_get_permalink_res | |||
|
|||
let www_form_of_get_upload_url_ext (req : Slack_t.get_upload_url_ext_req) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this function used elsewhere? i don't think it's worth having this function out of get_upload_url_external
. Just declare the fields
variable and inside of it.
Related to #5
I did some initial scaffolding work around this. Haven't done any testing yet so it probably doesn't work.
Some caveats about the new api is that it is a three step query process
Also with the new api, we cannot specify multiple channels in
3.
and you can only call it once which I guess means once you upload it once, it gets thrown away after. https://api.slack.com/methods/files.getUploadURLExternal#markdown I thought about multiplexing the request by getting multiple upload urls but I don't know if this will work as expected and slack will give back multiple unique ids to upload to. That's also kinda inefficient to duplicate the upload work.In any case, feel free to take over this PR