sfr_slack_api/api/
chat_post_message.rs

1//! The Slack API definition of `chat.postMessage`.
2//!
3//! <https://api.slack.com/methods/chat.postMessage>
4
5use sfr_types as st;
6
7pub use st::ChatPostMessageResponse;
8
9use crate::{Client, Request};
10
11/// The request object for <https://api.slack.com/methods/chat.postMessage>.
12#[derive(Debug)]
13pub struct ChatPostMessage(st::ChatPostMessageRequest);
14
15/// The code indicating the request handled in this file.
16const API_CODE: &str = "chat.postMessage";
17
18impl ChatPostMessage {
19    /// Requests `chat.postMessage` to Slack.
20    async fn request_inner(&self, client: &Client) -> Result<ChatPostMessageResponse, st::Error> {
21        #[allow(clippy::missing_docs_in_private_items)] // https://github.com/rust-lang/rust-clippy/issues/13298
22        const URL: &str = "https://slack.com/api/chat.postMessage";
23
24        let response = client
25            .client()
26            .post(URL)
27            .bearer_auth(client.token())
28            .json(&self.0)
29            .send()
30            .await
31            .map_err(|e| st::Error::failed_to_request_by_http(API_CODE, e))?;
32        tracing::debug!("response = {response:?}");
33
34        let body: serde_json::Value = response
35            .json()
36            .await
37            .map_err(|e| st::Error::failed_to_read_json(API_CODE, e))?;
38        tracing::debug!("body = {body:?}");
39
40        body.try_into()
41    }
42}
43
44impl From<st::ChatPostMessageRequest> for ChatPostMessage {
45    fn from(inner: st::ChatPostMessageRequest) -> Self {
46        Self(inner)
47    }
48}
49
50impl Request for ChatPostMessage {
51    type Response = ChatPostMessageResponse;
52
53    async fn request(self, client: &Client) -> Result<Self::Response, st::Error> {
54        self.request_inner(client).await
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn test_deserialize() {
64        let testdata = r#"
65          {
66            "channel": "ABC123ABC12",
67            "message": {
68              "app_id": "ABC123ABC12",
69              "blocks": [
70                {
71                  "block_id": "Cg=",
72                  "elements": [
73                    {
74                      "elements": [
75                        {
76                          "style": {
77                            "code": true
78                          },
79                          "text": "foo",
80                          "type": "text"
81                        },
82                        {
83                          "text": " bar ",
84                          "type": "text"
85                        },
86                        {
87                          "type": "user",
88                          "user_id": "ABC123ABC"
89                        },
90                        {
91                          "text": ".",
92                          "type": "text"
93                        }
94                      ],
95                      "type": "rich_text_section"
96                    }
97                  ],
98                  "type": "rich_text"
99                }
100              ],
101              "bot_id": "ABC123ABC12",
102              "bot_profile": {
103                "app_id": "ABC123ABC12",
104                "deleted": false,
105                "icons": {
106                  "image_36": "https://avatars.slack-edge.com/1901-01-01/1234567890123_1234567890abcdef1234_36.png",
107                  "image_48": "https://avatars.slack-edge.com/1901-01-01/1234567890123_1234567890abcdef1234_48.png",
108                  "image_72": "https://avatars.slack-edge.com/1901-01-01/1234567890123_1234567890abcdef1234_72.png"
109                },
110                "id": "ABC123ABC12",
111                "name": "dummy-app-name",
112                "team_id": "ABC123ABC",
113                "updated": 1234567890
114              },
115              "team": "ABC123ABC",
116              "text": "`foo` bar <@ABC123ABC|buz>.",
117              "ts": "1234567890.123456",
118              "type": "message",
119              "user": "ABC123ABC12"
120            },
121            "ok": true,
122            "response_metadata": {"warnings": ["missing_charset"]},
123            "ts": "1234567890.123456",
124            "warning": "missing_charset"
125          }
126        "#;
127
128        let deserialized: serde_json::Value = serde_json::from_str(&testdata).unwrap();
129        let _: ChatPostMessageResponse = deserialized.try_into().unwrap();
130    }
131}