-
Notifications
You must be signed in to change notification settings - Fork 18
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
Impl uploadv2 #90
Impl uploadv2 #90
Conversation
Generate files.getUploadURLExternal and files.completeUploadExternal.
and add new tests to api_test.ts.
Thanks for the contribution! Unfortunately we can't verify the commit author(s): kawasaki.taiga <k***@r***.n***.jp>. One possible solution is to add that email to your GitHub account. Alternatively you can change your commits to another email and force push the change. After getting your commits associated with your GitHub account, sign the Salesforce Inc. Contributor License Agreement and this Pull Request will be revalidated. |
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.
This is awesome 💯 @taiga533 thank you for the contribution 🥇
I left a few initial comments, there may be a few things to iron out since custom methods seem to be uncharted territory for this library
src/typed-method-types/files.ts
Outdated
@@ -0,0 +1,32 @@ | |||
import { BaseResponse } from "../types.ts"; | |||
|
|||
export type FileUploadV2 = { |
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.
What do you think about potentially implementing the type for FileUpload similar to the node sdk and then building this type from it?
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.
That's a good idea. By having separate types for FileUpload and FileUploadV2, the FileUpload type will be useful when trying to implement the old files.upload. Thanks for the advice.
I implemented.
}; | ||
|
||
export type FileUploadV2Args = { | ||
file_uploads: FileUploadV2[]; |
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.
@filmaj seems like the node-sdk has a deprecated additional field request_file_info since it does not appear here would we want to do something like FileUploadV2Args = FileUploadV2[]
?
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.
FileUploadV2Args might indeed be better as a FileUploadV2[] type. Is it okay to modify it that way? 😄
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.
While it may seem awkward to nest it under an additional property name, I believe having consistency across all SDKs is more important than a sense of property cleanliness. My vote would be to keep the structure as-is, to allow for easier conceptual movement from one language / bolt framework to another.
src/typed-method-types/files.ts
Outdated
/** @description Name of the file being uploaded. */ | ||
filename: string; | ||
/** @description Filetype of the file being uploaded. */ | ||
file: Blob | ReadableStream<Uint8Array> | string | ArrayBuffer; |
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 the content
field is missing from this type 🤔 (node sdk content field) was this omitted for a specific reason?
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 didn't implement the content field because it's not usable for file upload v2 (when uploading via getExternalUploadURL). In node-slack-sdk, whether you use the content or file field, the data is processed like the file field and an HTTP request is made. reference
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 learned from @filmaj that the content field is an important element! I was mistaken in my previous comment, so I will implement the content field. 🙇♂️
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #90 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 36 36
Lines 1091 1155 +64
Branches 13 22 +9
=========================================
+ Hits 1091 1155 +64 ☔ View full report in Codecov by Sentry. |
@WilliamBergamin My implementation, while referencing the node-slack-api, avoids implementing fields that will not be supported in the future and includes fields that will become mandatory as mandatory fields. Since node-slack-api has been around for a long time, there's a benefit to aligning the fields used in fileUploadV2 with those used in files.upload. However, in deno-slack-api, files.upload is currently not usable, so I thought there was no need to implement fields like content or filetype. |
Modify the definition of the FileUploadV2 type to extend the FileUpload type. And modify the FileUpload type so that it does not directly reference ReadableStream, ensuring npm build succeeds.
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.
Hey thanks for taking a stab at this! This is really great!
I have left some changes that I think we require in order to keep parity with the same method from the other SDKs.
Another request: would it be possible to somehow integrate this method so that it shows up under the client.files.*
property? I understand that everything under files
is a generated method, but I wanted to ask everyone involved in this discussion, @WilliamBergamin included, if perhaps we can come up with a way to:
- Place the method under the
files
property, and - Rename the method to
uploadV2
In this way, it would exactly match the "New Way" we describe the file uploading process in our node SDK docs.
) { | ||
const response = await fetch(uploadUrl, { | ||
headers: { | ||
"Content-Type": typeof file === "string" |
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 don't think this works the same way as the node SDK. If file
is a string in the node SDK, then the assumption is that the file
argument is a file path to the file data. This is why the content
parameter exists on the node SDK: so that users who do want to provide string-based file contents can do so.
Can we make this work the same way as the node SDK?
Also for reference: the code for how the python SDK handles these parameters.
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 had overlooked how the node SDK behaves when a string is passed to the file field 😮. It's definitely not good for the behavior to differ between SDKs. I will make corrections so that the handling of the content field and file field behaves the same as in other SDKs.
file: FileUploadV2["file"], | ||
) { | ||
const response = await fetch(uploadUrl, { | ||
headers: { |
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.
When actually POSTing the file contents to the URL provided by getUploadURLExternal
, we post the data as binary (raw bytes), or multipart-form-encoded (see the docs on this here).
As a result, I don't think we should be providing headers like Content-Type. The file-upload-external edge URL that we POST file data to will infer the content type based on the data uploaded.
In the node SDK, the headers are empty other than the token.
Similarly, in the python SDK, same thing.
I think the trick in implementing this API is to ensure we encode the POST data in the appropriate format, based on what is provided by the user. Assuming we support the content
parameter, like the other SDKs do, then the content
parameter, which is a string, should be encoded as UTF-8 bytes. Otherwise, if file
is a string, we should interpret that string as a file path, and read the raw bytes directly from that path. Finally, file
may also be a buffer-like object. In this situation, we should provide the raw buffer directly to fetch
as its data payload.
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.
OK. Indeed, delegating the setting of Content-Type to the fetch function is appropriate. Thank you for the detailed explanation 😊. Based on this, I will make the following modifications to the source code:
- When uploading a file to the URL obtained from getUploadURLExternal, do not set the Content-Type.
- Implement a content field, read its value as UTF-8, and pass it to the request body of the fetch function.
- When a string is passed to the file field, interpret it as a file path and read the file using Deno.readFileSync.
Is this still being worked on? |
Summary
testing
If you want to test with the actual Slack API, you could run a script like this.
Special notes
Based on this issue, I implemented it.
Requirements
deno task test
after making the changes.