1use crate::{
2 client::async_client::Client,
3 error::Result,
4 transport::{build_webhook_url, parse_standard_api_text_response},
5 types::{
6 ActionCardButton, FeedCardLink,
7 internal::{
8 ActionCardContent, FeedCardContent, LinkContent, MarkdownContent, TextContent,
9 WebhookMessage, build_at,
10 },
11 },
12};
13
14#[derive(Clone)]
16pub struct WebhookService {
17 client: Client,
18 token: String,
19 secret: Option<String>,
20}
21
22impl WebhookService {
23 pub(crate) fn new(client: Client, token: impl Into<String>, secret: Option<String>) -> Self {
24 Self {
25 client,
26 token: token.into(),
27 secret,
28 }
29 }
30
31 async fn send_message(&self, message: &WebhookMessage) -> Result<String> {
32 let url = build_webhook_url(
33 self.client.webhook_base_url(),
34 &self.token,
35 self.secret.as_deref(),
36 )?;
37 let response = self
38 .client
39 .webhook_http()
40 .post(url.as_str())
41 .json(message)?
42 .send_response()
43 .await?;
44 parse_standard_api_text_response(response, self.client.body_snippet())
45 }
46
47 pub async fn send_text_message(
49 &self,
50 content: &str,
51 at_mobiles: Option<Vec<String>>,
52 at_user_ids: Option<Vec<String>>,
53 is_at_all: Option<bool>,
54 ) -> Result<String> {
55 let message = WebhookMessage::Text {
56 text: TextContent {
57 content: content.to_string(),
58 },
59 at: build_at(at_mobiles, at_user_ids, is_at_all),
60 };
61 self.send_message(&message).await
62 }
63
64 pub async fn send_link_message(
66 &self,
67 title: &str,
68 text: &str,
69 message_url: &str,
70 pic_url: Option<&str>,
71 ) -> Result<String> {
72 let message = WebhookMessage::Link {
73 link: LinkContent {
74 title: title.to_string(),
75 text: text.to_string(),
76 message_url: message_url.to_string(),
77 pic_url: pic_url.map(ToOwned::to_owned),
78 },
79 at: None,
80 };
81 self.send_message(&message).await
82 }
83
84 pub async fn send_markdown_message(
86 &self,
87 title: &str,
88 text: &str,
89 at_mobiles: Option<Vec<String>>,
90 at_user_ids: Option<Vec<String>>,
91 is_at_all: Option<bool>,
92 ) -> Result<String> {
93 let message = WebhookMessage::Markdown {
94 markdown: MarkdownContent {
95 title: title.to_string(),
96 text: text.to_string(),
97 },
98 at: build_at(at_mobiles, at_user_ids, is_at_all),
99 };
100 self.send_message(&message).await
101 }
102
103 pub async fn send_action_card_message_single(
105 &self,
106 title: &str,
107 text: &str,
108 single_title: &str,
109 single_url: &str,
110 btn_orientation: Option<&str>,
111 ) -> Result<String> {
112 let message = WebhookMessage::ActionCard {
113 action_card: ActionCardContent {
114 title: title.to_string(),
115 text: text.to_string(),
116 btn_orientation: btn_orientation.map(ToOwned::to_owned),
117 single_title: Some(single_title.to_string()),
118 single_url: Some(single_url.to_string()),
119 btns: None,
120 },
121 };
122 self.send_message(&message).await
123 }
124
125 pub async fn send_action_card_message_multi(
127 &self,
128 title: &str,
129 text: &str,
130 btns: Vec<ActionCardButton>,
131 btn_orientation: Option<&str>,
132 ) -> Result<String> {
133 let message = WebhookMessage::ActionCard {
134 action_card: ActionCardContent {
135 title: title.to_string(),
136 text: text.to_string(),
137 btn_orientation: btn_orientation.map(ToOwned::to_owned),
138 single_title: None,
139 single_url: None,
140 btns: Some(btns),
141 },
142 };
143 self.send_message(&message).await
144 }
145
146 pub async fn send_feed_card_message(&self, links: Vec<FeedCardLink>) -> Result<String> {
148 let message = WebhookMessage::FeedCard {
149 feed_card: FeedCardContent { links },
150 };
151 self.send_message(&message).await
152 }
153}