1use 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 #[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 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 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 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}