1use crate::channels::channel::Channel;
2use crate::error::Error;
3use crate::http_client::{get_slack_url, ResponseMetadata, SlackWebAPIClient};
4use serde::{Deserialize, Serialize};
5use serde_with::skip_serializing_none;
6
7#[skip_serializing_none]
8#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
9pub struct ConversationsRequest {
10 pub cursor: Option<String>,
11 pub exclude_archived: Option<bool>,
12 pub limit: Option<i32>,
13 pub team_id: Option<String>,
14 #[serde(rename = "type")]
15 pub type_filed: Option<String>,
16 pub user: Option<String>,
17}
18
19#[skip_serializing_none]
20#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
21pub struct ConversationsResponse {
22 pub ok: bool,
23 pub error: Option<String>,
24 pub response_metadata: Option<ResponseMetadata>,
25 pub channels: Option<Vec<Channel>>,
26}
27
28pub async fn conversations<T>(
29 client: &T,
30 param: &ConversationsRequest,
31 bot_token: &str,
32) -> Result<ConversationsResponse, Error>
33where
34 T: SlackWebAPIClient,
35{
36 let url = get_slack_url("users.conversations");
37 let json = serde_json::to_string(¶m)?;
38
39 client
40 .post_json(&url, &json, bot_token)
41 .await
42 .and_then(|result| {
43 serde_json::from_str::<ConversationsResponse>(&result).map_err(Error::SerdeJsonError)
44 })
45}
46
47#[cfg(test)]
48mod test {
49 use super::*;
50 use crate::channels::channel::{Purpose, Topic};
51 use crate::http_client::MockSlackWebAPIClient;
52
53 #[test]
54 fn convert_request() {
55 let request = ConversationsRequest {
56 cursor: Some("xxxxxxxxxx".to_string()),
57 exclude_archived: Some(true),
58 team_id: Some("xxxxxxxxxx".to_string()),
59 type_filed: Some("xxxxxxxxxx".to_string()),
60 limit: Some(1),
61 user: Some("xxxxxxxxxx".to_string()),
62 };
63 let json = r##"{
64 "cursor": "xxxxxxxxxx",
65 "exclude_archived": true,
66 "limit": 1,
67 "team_id": "xxxxxxxxxx",
68 "type": "xxxxxxxxxx",
69 "user": "xxxxxxxxxx"
70}"##;
71
72 let j = serde_json::to_string_pretty(&request).unwrap();
73 assert_eq!(json, j);
74
75 let s = serde_json::from_str::<ConversationsRequest>(json).unwrap();
76 assert_eq!(request, s);
77 }
78
79 #[test]
80 fn convert_response() {
81 let response = ConversationsResponse {
82 ok: true,
83 channels: Some(vec![Channel {
84 id: Some("C0EAQDV4Z".to_string()),
85 name: Some("endeavor".to_string()),
86 is_channel: Some(true),
87 created: Some(1504554479),
88 creator: Some("U0123456".to_string()),
89 is_archived: Some(false),
90 is_general: Some(false),
91 name_normalized: Some("endeavor".to_string()),
92 is_shared: Some(false),
93 is_org_shared: Some(false),
94 is_member: Some(false),
95 is_private: Some(false),
96 is_mpim: Some(false),
97 last_read: Some("0000000000.000000".to_string()),
98 unread_count: Some(0),
99 unread_count_display: Some(0),
100 topic: Some(Topic {
101 value: Some("".to_string()),
102 creator: Some("".to_string()),
103 last_set: Some(0),
104 }),
105 purpose: Some(Purpose {
106 value: Some("".to_string()),
107 creator: Some("".to_string()),
108 last_set: Some(0),
109 }),
110 previous_names: Some(vec![]),
111 priority: Some(0),
112 ..Default::default()
113 }]),
114 ..Default::default()
115 };
116 let json = r##"{
117 "ok": true,
118 "channels": [
119 {
120 "id": "C0EAQDV4Z",
121 "name": "endeavor",
122 "is_channel": true,
123 "created": 1504554479,
124 "creator": "U0123456",
125 "is_archived": false,
126 "is_general": false,
127 "name_normalized": "endeavor",
128 "is_shared": false,
129 "is_org_shared": false,
130 "is_member": false,
131 "is_private": false,
132 "is_mpim": false,
133 "last_read": "0000000000.000000",
134 "unread_count": 0,
135 "unread_count_display": 0,
136 "topic": {
137 "value": "",
138 "creator": "",
139 "last_set": 0
140 },
141 "purpose": {
142 "value": "",
143 "creator": "",
144 "last_set": 0
145 },
146 "previous_names": [],
147 "priority": 0
148 }
149 ]
150}"##;
151
152 let j = serde_json::to_string_pretty(&response).unwrap();
153 assert_eq!(json, j);
154
155 let s = serde_json::from_str::<ConversationsResponse>(json).unwrap();
156 assert_eq!(response, s);
157 }
158
159 #[async_std::test]
160 async fn test_conversations() {
161 let param = ConversationsRequest {
162 cursor: Some("xxxxxxxxxx".to_string()),
163 exclude_archived: Some(true),
164 team_id: Some("xxxxxxxxxx".to_string()),
165 type_filed: Some("xxxxxxxxxx".to_string()),
166 limit: Some(1),
167 user: Some("xxxxxxxxxx".to_string()),
168 };
169 let mut mock = MockSlackWebAPIClient::new();
170 mock.expect_post_json().returning(|_, _, _| {
171 Ok(r##"{
172 "ok": true,
173 "channels": [
174 {
175 "id": "C0EAQDV4Z",
176 "name": "endeavor",
177 "is_channel": true,
178 "created": 1504554479,
179 "creator": "U0123456",
180 "is_archived": false,
181 "is_general": false,
182 "name_normalized": "endeavor",
183 "is_shared": false,
184 "is_org_shared": false,
185 "is_member": false,
186 "is_private": false,
187 "is_mpim": false,
188 "last_read": "0000000000.000000",
189 "unread_count": 0,
190 "unread_count_display": 0,
191 "topic": {
192 "value": "",
193 "creator": "",
194 "last_set": 0
195 },
196 "purpose": {
197 "value": "",
198 "creator": "",
199 "last_set": 0
200 },
201 "previous_names": [],
202 "priority": 0
203 }
204 ]
205}"##
206 .to_string())
207 });
208
209 let response = conversations(&mock, ¶m, &"test_token".to_string())
210 .await
211 .unwrap();
212 let expect = ConversationsResponse {
213 ok: true,
214 channels: Some(vec![Channel {
215 id: Some("C0EAQDV4Z".to_string()),
216 name: Some("endeavor".to_string()),
217 is_channel: Some(true),
218 created: Some(1504554479),
219 creator: Some("U0123456".to_string()),
220 is_archived: Some(false),
221 is_general: Some(false),
222 name_normalized: Some("endeavor".to_string()),
223 is_shared: Some(false),
224 is_org_shared: Some(false),
225 is_member: Some(false),
226 is_private: Some(false),
227 is_mpim: Some(false),
228 last_read: Some("0000000000.000000".to_string()),
229 unread_count: Some(0),
230 unread_count_display: Some(0),
231 topic: Some(Topic {
232 value: Some("".to_string()),
233 creator: Some("".to_string()),
234 last_set: Some(0),
235 }),
236 purpose: Some(Purpose {
237 value: Some("".to_string()),
238 creator: Some("".to_string()),
239 last_set: Some(0),
240 }),
241 previous_names: Some(vec![]),
242 priority: Some(0),
243 ..Default::default()
244 }]),
245 ..Default::default()
246 };
247
248 assert_eq!(expect, response);
249 }
250}