-
Notifications
You must be signed in to change notification settings - Fork 662
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
Add files.uploadv2 support (fixing #1541) #1544
Conversation
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.
Great work! Here are my quick review comments.
packages/web-api/src/WebClient.ts
Outdated
fileUploadsURLRes.forEach((res, idx) => { | ||
const { status } = res; | ||
if (status === 'rejected') { | ||
this.logger.error(`Error initiating upload for ${fileUploads[idx].filename}`); |
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.
For all the patterns that you print error-level logs like this, I think that we can immediately throw an exception as we don't want to proceed with the following code (say, if you failed uploading any of the files, posting a message with some of the files is not an expected behavior, right?).
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.
@seratch - Hmm... I think that made an assumption that each file_upload was independent, and so my initial instinct was that users would find this useful, because having all 10 uploads fail because one upload is incorrect seemed annoying. But then I do see that this pattern is supported in your implementation:
# New way with multiple files!
response = client.files_upload_v2(
file_uploads=[
{
"file": "./logo.png",
"title": "New company logo",
},
{
"content": "Minutes ....",
"filename": "team-meeting-minutes-2022-03-01.md",
"title": "Team meeting minutes (2022-03-01)",
},
],
channel="C12345",
initial_comment="Here is the latest version of our new company logo :wave:",
)
Which sounds like the scenario where you'd want the entire upload to fail IF there are multiple uploads associated with a single initial_comment / message. Currently my changes don't account for this.
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.
@srajiang I think that developers would like to know any of the files are not properly uploaded because it's a partial failure. Also, I haven't checked this yet but when any of the file IDs that are passed to the complete API call (= sharing the files) fails, the sharing process may not work as you expect.
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.
Okay - it's true that it's simpler to fail the moment there's a single failure.
I do still need to add some logic to support a single initial_comment / message + multiple file uploads at the same time so I will work on those both tomorrow.
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.
@seratch Now we are immediately throwing an exception when there's a failure in any step, and have added changes to support the multiple file uploads pattern above.
packages/web-api/src/WebClient.ts
Outdated
* @param fileUploads | ||
* @returns | ||
*/ | ||
private async postCompletedFileUploads(fileUploads: FileUploadV2Entry[]): |
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.
Can you add files.info API call for each file (for better compatibility with v1)? The response from complete API includes only file ID an its title. With that, we still have some issues like slackapi/python-slack-sdk#1277. That being said, I still believe that attaching full metadata should be less surprising to developers.
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.
@seratch - The separate files:read
scope is required to make files.info
call. Bolt can't assume that this is something that the app has configured, so would it make sense for the developer to handle this in this case?
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've added a getFileInfo
method for now, but can remove it if we decide not to make the additional files.info call. If we decide to keep that functionality to match v1 (as I do agree it would be nice to have), I supposed I could also handle the exception thrown and if due to missing scope I suppose I could log that a scope is needed. Seems a little unusual to be doing that though.
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.
@srajiang Indeed, the necessity of files:read
too is another difference from the v1 method (mentioned in this thread actually - slackapi/python-slack-sdk#1165 (comment) ) but I believe that it's safe enough to assume an app handling files tends to have both read and write scopes. I would like to keep having it.
If we receive requests to customize the behavior in the future, we can consider adding a flag to disable the last files.info API calls. Perhaps, the flag can be full_file_into_required: boolean (default: true)
or something like that.
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.
Left some initial comments for review.
@@ -319,7 +320,21 @@ describe('WebClient', function () { | |||
const warnClient = new WebClient(token, { logLevel: LogLevel.WARN, logger }); | |||
return warnClient.apiCall(method, args) | |||
.then(() => { | |||
assert.isTrue(logger.warn.callCount === 4); | |||
// assume no warning about thread_ts has been sent |
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 test is unrelated related to the added features for files.uploadV2 support. It was failing when I added additional warnings re: ☝️. I realized that the test wasn't really specifically validating that the thread_ts warning was being logged, just counting the total number of overall warning loggings - this change should be a small improvement.
@@ -341,10 +356,46 @@ describe('WebClient', function () { | |||
const warnClient = new WebClient(token, { logLevel: LogLevel.WARN, logger }); | |||
return warnClient.apiCall(method, args) | |||
.then(() => { | |||
assert.isTrue(logger.warn.calledThrice); | |||
logger.warn.getCalls().forEach((call) => { |
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 comment as ☝️
4ad5ddb
to
a0ceece
Compare
@seratch - Thanks for the initial comments! I've gone ahead and made updates based on your suggestions. |
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.
Thanks for the great work. It looks almost done! I don't think we should support sharing in multiple channels in v2 as it may not be supported by design (this means the behavior may be changed in the future).
packages/web-api/src/WebClient.ts
Outdated
* @param fileUploads | ||
* @returns | ||
*/ | ||
private async postCompletedFileUploads(fileUploads: FileUploadV2Entry[]): |
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.
@srajiang Indeed, the necessity of files:read
too is another difference from the v1 method (mentioned in this thread actually - slackapi/python-slack-sdk#1165 (comment) ) but I believe that it's safe enough to assume an app handling files tends to have both read and write scopes. I would like to keep having it.
If we receive requests to customize the behavior in the future, we can consider adding a flag to disable the last files.info API calls. Perhaps, the flag can be full_file_into_required: boolean (default: true)
or something like that.
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.
Thank you! Everything looks great now
Summary
Adds files.uploadV2 support to node-slack-sdk.
Please refer to slackapi/python-slack-sdk#1272 for more context.
Fixes #1541
Requirements (place an
x
in each[ ]
)