When I received an email, I wanted to upload the email attachment to Slack and tried to use Microsoft (Office365) Flow to perform that task.
Microsoft (Office365) Flow has a Slack connector, so I thought it would be easy to create one, Unfortunately, Flow's Slack connector is for posting text messages only, and files cannot be uploaded to Slack.
We had no choice but to upload the file directly via Slack's API using Flow's HTTP action.
Here is a summary of the procedure for uploading files from that Microsoft (Office365) Flow to Slack.
How to upload files in Slack
This is a rough requirement for Slack's file upload method.
Slack API Documentation
Elements
Upload the file with "multipart/form-data" by "POST" to the URL "
https://slack.com/api/files.upload
".- It is the same method as the so-called html file upload form
- Specify the contents of the file in "file.
The "contents-type" must be specified for the file type.
- Without "contents-type," files can be uploaded, but their contents will be corrupted.
The API is authenticated by a bearer token, and the token is set to "Bearer \
" in the "authorization" header. - One space is required between "Beare" and the token.
- Tokens are obtained in advance.
- The "files:write:user" privilege is required for file uploads.
- The destination for posting is "channels", which specifies the channel ID.
There are many points to get into using Slack's API, which we have summarized in a separate article, so please refer to that for more details.
Flow Settings
The above Slack API call is made in a Flow HTTP action.
- Set the method to "POST" and the URI to "
https://slack.com/api/files.upload
". - Authentication is specified as "Bearer \
" in the "authorization" header.
After that, I set "content-type" to "multipart/form-data" in the header settings, set the file and Slack's channelID, and then POST... but that was not the end of it, The "multipart/form-data" POST method was a bit tricky.
To "multipart/form-data" in an HTTP action, the "content-type" should not be set in the header, but should be described in the body as JSON along with the data to be sent.
The JSON will look like the following, which is pasted into the body of the message.
{ "$content-type": "multipart/form-data", "$multipart": [ { "headers": { "Content-Disposition": "form-data; name=file; filename=@{items('Apply_to_each')?['Name']}" }, "body": { "$content-type": "@{items('Apply_to_each')?['ContentType']}", "$content": @{items('Apply_to_each')?['ContentBytes']} } }, { "headers": { "Content-Disposition": "form-data; name=channels" }, "body": "xxx" } ] }
Supplementary Explanation and Notes
Parameters required for file upload
The file is uploaded from the file object by setting three values: "file content (file)," "file type (content-type)," and "file name (filename).
Regarding JSON description contents
There are unfamiliar objects such as "@{items('Apply_to_each')? ['Name']}" and other unfamiliar objects, When pasted into the body, they refer to information about the file, as you can see from the fact that "Attachment Name" appears in the Flow editor.
Flow uses the "@{items('Apply_to_each')? ['Name']}" in the internal process, but the GUI displays a different "Attachment Name" to make it easier for the user to understand.
When working with Flow, we often get into trouble if we do not know these relationships, so we have compiled a separate article on how to reference data in Flow.
Since the contents of the file must be sent in binary, "@{items('Apply_to_each')? ['ContentBytes']}" should be written directly without " ".
Also, in the sample, I put the list of attachments into "Apply to each" and took out the files one by one, so I used notation like "items('Apply_to_each')", The "triggerBody()? ['Attachments'][0]" can also be used to directly retrieve the files, and the notation will vary depending on where the files to be uploaded are to be obtained.
The meaning of those notations and how to find out what they are supposed to be are also summarized in the above article "Organize how to reference data in Microsoft (Office365) Flow".
Regarding Slack settings
I set the Slack posting ID to "channels" to send it to, and I am doing that setup below.
{ "headers": { "Content-Disposition": "form-data; name=channels" }, "body": "xxx" }
The "name=\~" is the name of the argument, and the "body" value is the Slack channel ID you wish to post to.
In the same way, "initial_comment" and "title" can be set to specify the comment and title when uploaded.
execution
After executing the above, the file was successfully uploaded!
Impressions, etc.
At first, I was trying to set "content-type" and "multipart/form-data" in the header and write data solidly in the body.
Actually, this will allow you to upload the file, but the contents of the file will be corrupted.
Then, when data was written solidly in the body, the body data seemed to be judged as String, and the contents of the file were forcibly converted to String by "base64ToString()", which caused the file to be corrupted.
But is it really true that only String data can be sent in HTTP actions? It is hard to believe, so I checked the manual and found that there is no such specification, but rather, it describes exactly how to send "multipart/form-data" data...
When passed in this way, "@{items('Apply_to_each')? ['ContentBytes']}" was successfully passed in binary. Oh no, I should have looked at this first: .......
Since HTTP actions are made to be generic, it seems that any API can be hit using HTTP actions.
But I want to have fun using the connectors that are available, so I want Slack to provide a file upload connector!