1mod attachment;
10mod message;
11
12pub use self::attachment::Attachment;
13pub use self::message::{Message, MessageId};
14
15use crate::api;
16use af_core::prelude::*;
17
18pub async fn permalink_to<'a>(client: &api::Client, id: &MessageId) -> Result<String> {
20 #[derive(Serialize)]
21 struct Params<'a> {
22 channel: &'a str,
23 message_ts: &'a str,
24 }
25
26 #[derive(Deserialize)]
27 struct Response {
28 permalink: String,
29 }
30
31 let params = Params { channel: &id.channel, message_ts: &id.ts };
32 let res = client.get::<_, Response>("chat.getPermalink", ¶ms).await?;
33
34 match res {
35 Ok(res) => Ok(res.permalink),
36 Err(err) => match err.error.as_str() {
37 "channel_not_found" => Err(Error::ChannelNotFound),
38 _ => Err(Error::Other(err)),
39 },
40 }
41}
42
43pub async fn post<'a>(
45 client: &api::Client,
46 channel: impl AsRef<str>,
47 message: impl Into<Message<'a>>,
48) -> Result<MessageId> {
49 #[derive(Serialize)]
50 struct Request<'a> {
51 channel: &'a str,
52 #[serde(flatten)]
53 message: Message<'a>,
54 }
55
56 let req = Request { channel: channel.as_ref(), message: message.into() };
57 let res = client.post::<_, MessageId>("chat.postMessage", &req).await?;
58
59 match res {
60 Ok(id) => Ok(id),
61 Err(err) => match err.error.as_str() {
62 "channel_not_found" => Err(Error::ChannelNotFound),
63 "not_in_channel" => Err(Error::NotInChannel),
64 _ => Err(Error::Other(err)),
65 },
66 }
67}
68
69pub async fn reply<'a>(
71 client: &api::Client,
72 thread_id: &MessageId,
73 message: impl Into<Message<'a>>,
74) -> Result<MessageId> {
75 #[derive(Serialize)]
76 struct Request<'a> {
77 channel: &'a str,
78 #[serde(flatten)]
79 message: Message<'a>,
80 thread_ts: &'a str,
81 }
82
83 let req =
84 Request { channel: &thread_id.channel, message: message.into(), thread_ts: &thread_id.ts };
85 let res = client.post::<_, MessageId>("chat.postMessage", &req).await?;
86
87 match res {
88 Ok(id) => Ok(id),
89 Err(err) => match err.error.as_str() {
90 "channel_not_found" => Err(Error::ChannelNotFound),
91 "not_in_channel" => Err(Error::NotInChannel),
92 _ => Err(Error::Other(err)),
93 },
94 }
95}
96
97#[derive(Debug, Error)]
99pub enum Error {
100 #[error("channel not found")]
102 ChannelNotFound,
103 #[error("not in channel")]
105 NotInChannel,
106 #[error("api error: {0}")]
108 ApiError(#[from] api::Error),
109 #[error("{0:#}")]
111 Other(api::ErrorResponse),
112}
113
114pub type Result<T = (), E = Error> = std::result::Result<T, E>;