slack_rust/conversations/
history.rs

1use crate::chat::message::Message;
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 HistoryRequest {
10    pub channel: String,
11    pub cursor: Option<String>,
12    pub inclusive: Option<bool>,
13    pub latest: Option<String>,
14    pub limit: Option<i32>,
15    pub oldest: Option<String>,
16}
17
18#[skip_serializing_none]
19#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
20pub struct HistoryResponse {
21    pub ok: bool,
22    pub error: Option<String>,
23    pub response_metadata: Option<ResponseMetadata>,
24    pub messages: Option<Vec<Message>>,
25    pub has_more: Option<bool>,
26    pub pin_count: Option<i32>,
27}
28
29pub async fn history<T>(
30    client: &T,
31    param: &HistoryRequest,
32    bot_token: &str,
33) -> Result<HistoryResponse, Error>
34where
35    T: SlackWebAPIClient,
36{
37    let url = get_slack_url("conversations.history");
38    let json = serde_json::to_string(&param)?;
39
40    client
41        .post_json(&url, &json, bot_token)
42        .await
43        .and_then(|result| {
44            serde_json::from_str::<HistoryResponse>(&result).map_err(Error::SerdeJsonError)
45        })
46}
47
48#[cfg(test)]
49mod test {
50    use super::*;
51    use crate::http_client::MockSlackWebAPIClient;
52
53    #[test]
54    fn convert_request() {
55        let request = HistoryRequest {
56            channel: "C1234567890".to_string(),
57            cursor: Some("dXNlcjpVMDYxTkZUVDI=".to_string()),
58            inclusive: Some(true),
59            latest: Some("1234567890.123456".to_string()),
60            limit: Some(20),
61            oldest: Some("1234567890.123456".to_string()),
62        };
63        let json = r##"{
64  "channel": "C1234567890",
65  "cursor": "dXNlcjpVMDYxTkZUVDI=",
66  "inclusive": true,
67  "latest": "1234567890.123456",
68  "limit": 20,
69  "oldest": "1234567890.123456"
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::<HistoryRequest>(json).unwrap();
76        assert_eq!(request, s);
77    }
78
79    #[test]
80    fn convert_response() {
81        let response = HistoryResponse {
82            ok: true,
83            messages: Some(vec![
84                Message {
85                    type_file: Some("message".to_string()),
86                    text: Some(
87                        "I find you punny and would like to smell your nose letter".to_string(),
88                    ),
89                    user: Some("U012AB3CDE".to_string()),
90                    ts: Some("1512085950.000216".to_string()),
91                    ..Default::default()
92                },
93                Message {
94                    type_file: Some("message".to_string()),
95                    text: Some("What, you want to smell my shoes better?".to_string()),
96                    user: Some("U061F7AUR".to_string()),
97                    ts: Some("1512104434.000490".to_string()),
98                    ..Default::default()
99                },
100            ]),
101            has_more: Some(true),
102            pin_count: Some(0),
103            ..Default::default()
104        };
105        let json = r##"{
106  "ok": true,
107  "messages": [
108    {
109      "type": "message",
110      "text": "I find you punny and would like to smell your nose letter",
111      "user": "U012AB3CDE",
112      "ts": "1512085950.000216"
113    },
114    {
115      "type": "message",
116      "text": "What, you want to smell my shoes better?",
117      "user": "U061F7AUR",
118      "ts": "1512104434.000490"
119    }
120  ],
121  "has_more": true,
122  "pin_count": 0
123}"##;
124
125        let j = serde_json::to_string_pretty(&response).unwrap();
126        assert_eq!(json, j);
127
128        let s = serde_json::from_str::<HistoryResponse>(json).unwrap();
129        assert_eq!(response, s);
130    }
131
132    #[async_std::test]
133    async fn test_history() {
134        let param = HistoryRequest {
135            channel: "C1234567890".to_string(),
136            cursor: Some("dXNlcjpVMDYxTkZUVDI=".to_string()),
137            inclusive: Some(true),
138            latest: Some("1512104434.000490".to_string()),
139            limit: Some(20),
140            oldest: Some("1512085950.000216".to_string()),
141        };
142
143        let mut mock = MockSlackWebAPIClient::new();
144        mock.expect_post_json().returning(|_, _, _| {
145            Ok(r##"{
146  "ok": true,
147  "messages": [
148    {
149      "type": "message",
150      "text": "I find you punny and would like to smell your nose letter",
151      "user": "U012AB3CDE",
152      "ts": "1512085950.000216"
153    },
154    {
155      "type": "message",
156      "text": "What, you want to smell my shoes better?",
157      "user": "U061F7AUR",
158      "ts": "1512104434.000490"
159    }
160  ],
161  "has_more": true,
162  "pin_count": 0
163}"##
164            .to_string())
165        });
166
167        let response = history(&mock, &param, &"test_token".to_string())
168            .await
169            .unwrap();
170        let expect = HistoryResponse {
171            ok: true,
172            messages: Some(vec![
173                Message {
174                    type_file: Some("message".to_string()),
175                    text: Some(
176                        "I find you punny and would like to smell your nose letter".to_string(),
177                    ),
178                    user: Some("U012AB3CDE".to_string()),
179                    ts: Some("1512085950.000216".to_string()),
180                    ..Default::default()
181                },
182                Message {
183                    type_file: Some("message".to_string()),
184                    text: Some("What, you want to smell my shoes better?".to_string()),
185                    user: Some("U061F7AUR".to_string()),
186                    ts: Some("1512104434.000490".to_string()),
187                    ..Default::default()
188                },
189            ]),
190            has_more: Some(true),
191            pin_count: Some(0),
192            ..Default::default()
193        };
194
195        assert_eq!(expect, response);
196    }
197}