slack_morphism/api/
files.rs

1//!
2//! Support for Slack Files API methods
3//!
4
5use rsb_derive::Builder;
6use rvstruct::ValueStruct;
7use serde::{Deserialize, Serialize, Serializer};
8use serde_with::skip_serializing_none;
9
10use crate::api::{
11    SlackApiUsersConversationsRequest, SlackApiUsersConversationsResponse,
12    SlackApiUsersProfileSetRequest, SlackApiUsersProfileSetResponse,
13};
14use crate::models::*;
15use crate::multipart_form::FileMultipartData;
16use crate::ratectl::*;
17use crate::SlackClientSession;
18use crate::{ClientResult, SlackClientHttpConnector};
19
20impl<'a, SCHC> SlackClientSession<'a, SCHC>
21where
22    SCHC: SlackClientHttpConnector + Send,
23{
24    ///
25    /// https://api.slack.com/methods/files.upload
26    ///
27    #[deprecated(
28        note = "Deprecated by Slack. Use `getUploadURLExternal/files_upload_via_url/completeUploadExternal` instead."
29    )]
30    pub async fn files_upload(
31        &self,
32        req: &SlackApiFilesUploadRequest,
33    ) -> ClientResult<SlackApiFilesUploadResponse> {
34        let maybe_file = req.binary_content.as_ref().map(|file_data| {
35            let filename = req.filename.clone().unwrap_or("file".to_string());
36            let file_content_type = req.file_content_type.clone().unwrap_or_else(|| {
37                let file_mime = mime_guess::MimeGuess::from_path(&filename).first_or_octet_stream();
38                file_mime.to_string()
39            });
40            FileMultipartData {
41                name: filename,
42                content_type: file_content_type,
43                data: file_data.as_slice(),
44            }
45        });
46        self.http_session_api
47            .http_post_multipart_form(
48                "files.upload",
49                maybe_file,
50                &vec![
51                    (
52                        "channels",
53                        req.channels
54                            .as_ref()
55                            .map(|xs| {
56                                xs.iter()
57                                    .map(|x| x.to_string())
58                                    .collect::<Vec<String>>()
59                                    .join(",")
60                            })
61                            .as_ref(),
62                    ),
63                    ("content", req.content.as_ref()),
64                    ("filename", req.filename.as_ref()),
65                    ("filetype", req.filetype.as_ref().map(|x| x.value())),
66                    ("initial_comment", req.initial_comment.as_ref()),
67                    ("thread_ts", req.thread_ts.as_ref().map(|x| x.value())),
68                    ("title", req.title.as_ref()),
69                ],
70                Some(&SLACK_TIER2_METHOD_CONFIG),
71            )
72            .await
73    }
74
75    ///
76    /// https://api.slack.com/methods/files.getUploadURLExternal
77    ///
78    pub async fn get_upload_url_external(
79        &self,
80        req: &SlackApiFilesGetUploadUrlExternalRequest,
81    ) -> ClientResult<SlackApiFilesGetUploadUrlExternalResponse> {
82        self.http_session_api
83            .http_get(
84                "files.getUploadURLExternal",
85                &vec![
86                    ("filename", Some(&req.filename)),
87                    ("length", Some(&req.length.to_string())),
88                    ("alt_txt", req.alt_txt.as_ref()),
89                    ("snippet_type", req.snippet_type.as_ref().map(|v| v.value())),
90                ],
91                Some(&SLACK_TIER4_METHOD_CONFIG),
92            )
93            .await
94    }
95
96    pub async fn files_upload_via_url(
97        &self,
98        req: &SlackApiFilesUploadViaUrlRequest,
99    ) -> ClientResult<SlackApiFilesUploadViaUrlResponse> {
100        self.http_session_api
101            .http_post_uri_binary(
102                req.upload_url.value().clone(),
103                req.content_type.clone(),
104                &req.content,
105                Some(&SLACK_TIER4_METHOD_CONFIG),
106            )
107            .await
108    }
109
110    ///
111    /// https://api.slack.com/methods/files.completeUploadExternal
112    ///
113    pub async fn files_complete_upload_external(
114        &self,
115        req: &SlackApiFilesCompleteUploadExternalRequest,
116    ) -> ClientResult<SlackApiFilesCompleteUploadExternalResponse> {
117        self.http_session_api
118            .http_post(
119                "files.completeUploadExternal",
120                req,
121                Some(&SLACK_TIER4_METHOD_CONFIG),
122            )
123            .await
124    }
125
126    ///
127    /// https://api.slack.com/methods/files.delete
128    ///
129    pub async fn files_delete(
130        &self,
131        req: &SlackApiFilesDeleteRequest,
132    ) -> ClientResult<SlackApiFilesDeleteResponse> {
133        self.http_session_api
134            .http_post("files.delete", req, Some(&SLACK_TIER3_METHOD_CONFIG))
135            .await
136    }
137}
138
139#[skip_serializing_none]
140#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
141pub struct SlackApiFilesUploadRequest {
142    #[serde(serialize_with = "to_csv")]
143    pub channels: Option<Vec<SlackChannelId>>,
144    pub content: Option<String>,
145    pub binary_content: Option<Vec<u8>>,
146    pub filename: Option<String>,
147    pub filetype: Option<SlackFileType>,
148    pub initial_comment: Option<String>,
149    pub thread_ts: Option<SlackTs>,
150    pub title: Option<String>,
151    pub file_content_type: Option<String>,
152}
153
154#[skip_serializing_none]
155#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
156pub struct SlackApiFilesUploadResponse {
157    pub file: SlackFile,
158}
159
160#[skip_serializing_none]
161#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
162pub struct SlackApiFilesGetUploadUrlExternalRequest {
163    pub filename: String,
164    pub length: usize,
165    pub alt_txt: Option<String>,
166    pub snippet_type: Option<SlackFileSnippetType>,
167}
168
169#[skip_serializing_none]
170#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
171pub struct SlackApiFilesGetUploadUrlExternalResponse {
172    pub upload_url: SlackFileUploadUrl,
173    pub file_id: SlackFileId,
174}
175
176#[skip_serializing_none]
177#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
178pub struct SlackApiFilesUploadViaUrlRequest {
179    pub upload_url: SlackFileUploadUrl,
180    pub content: Vec<u8>,
181    pub content_type: String,
182}
183
184#[skip_serializing_none]
185#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
186pub struct SlackApiFilesUploadViaUrlResponse {}
187
188#[skip_serializing_none]
189#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
190pub struct SlackApiFilesCompleteUploadExternalRequest {
191    pub files: Vec<SlackApiFilesComplete>,
192    pub channel_id: Option<SlackChannelId>,
193    pub initial_comment: Option<String>,
194    pub thread_ts: Option<SlackTs>,
195}
196
197#[skip_serializing_none]
198#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
199pub struct SlackApiFilesCompleteUploadExternalResponse {
200    pub files: Vec<SlackFile>,
201}
202
203#[skip_serializing_none]
204#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
205pub struct SlackApiFilesComplete {
206    pub id: SlackFileId,
207    pub title: Option<String>,
208}
209
210#[skip_serializing_none]
211#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
212pub struct SlackApiFilesDeleteRequest {
213    pub file: SlackFileId,
214}
215
216#[skip_serializing_none]
217#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
218pub struct SlackApiFilesDeleteResponse {}
219
220fn to_csv<S: Serializer>(x: &Option<Vec<SlackChannelId>>, s: S) -> Result<S::Ok, S::Error> {
221    match x {
222        None => s.serialize_none(),
223        Some(ids) => {
224            let y: Vec<String> = ids.iter().map(|v| v.0.clone()).collect();
225            y.join(",").serialize(s)
226        }
227    }
228}