botx_api/api/v4/notification/direct/
models.rs1use std::collections::HashMap;
2
3use serde::{Serialize, Deserialize};
4use uuid::Uuid;
5
6use crate::api::models::*;
7
8#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct DirectNotificationResponse {
10 pub sync_id: Option<Uuid>,
12 pub result: DirectNotificationResult,
13}
14
15#[derive(Debug, Serialize, Deserialize, Clone)]
16pub struct DirectNotificationResult {
17 pub sync_id: Option<Uuid>,
19}
20
21#[derive(Debug, Serialize, Deserialize, Clone)]
22#[serde(tag = "reason")]
23pub enum DirectNotificationExpressError {
24 #[serde(rename(serialize = "chat_not_found", deserialize = "chat_not_found"))]
25 ChatNotFound(ChatNotFoundWithEventId),
26 #[serde(rename(serialize = "error_from_messaging_service", deserialize = "error_from_messaging_service"))]
27 ErrorFromMessagingService(ErrorFromMessagingServiceWithEventId),
28 #[serde(rename(serialize = "bot_is_not_a_chat_member", deserialize = "bot_is_not_a_chat_member"))]
29 BotIsNotAChatMember(BotIsNotAChatMember),
30 #[serde(rename(serialize = "stealth_mode_disabled", deserialize = "stealth_mode_disabled"))]
31 StealthModeDisabled(StealthModeDisabled),
32 #[serde(rename(serialize = "event_recipients_list_is_empty", deserialize = "event_recipients_list_is_empty"))]
33 EventRecipientsListIsEmpty(EventRecipientsListIsEmpty),
34 #[serde(rename(serialize = "flow_processing_error", deserialize = "flow_processing_error"))]
35 FlowProcessingError(FlowProcessingError),
36 #[serde(rename(serialize = "unexpected_error", deserialize = "unexpected_error"))]
37 UnexpectedError(UnexpectedError),
38
39 #[serde(other)]
41 Other,
42}
43
44#[derive(Debug, Serialize, Deserialize, Clone)]
45pub struct StealthModeDisabled {
46 pub sync_id: Uuid,
47 pub errors: Vec<String>,
48 pub error_data: StealthModeDisabledData,
49}
50
51#[derive(Debug, Serialize, Deserialize, Clone)]
52pub struct StealthModeDisabledData {
53 pub group_chat_id: Uuid,
54 pub bot_id: Uuid,
55 pub error_description: String,
56}
57
58#[derive(Debug, Serialize, Deserialize, Clone)]
59pub struct FlowProcessingError {
60 pub sync_id: Uuid,
61 pub errors: Vec<String>,
62 pub error_data: FlowProcessingErrorData,
63}
64
65#[derive(Debug, Serialize, Deserialize, Clone)]
66pub struct FlowProcessingErrorData {
67 pub error_description: String,
68}
69
70#[derive(Debug, Serialize, Deserialize, Clone)]
71pub struct UnexpectedError {
72 pub sync_id: Uuid,
73 pub errors: Vec<String>,
74 pub error_data: UnexpectedErrorData,
75}
76
77#[derive(Debug, Serialize, Deserialize, Clone)]
78pub struct UnexpectedErrorData {
79 pub error_description: String,
80}
81
82#[derive(Debug, Serialize, Deserialize, Clone)]
83pub struct DirectNotificationExpressErrorData {
84
85 pub bot_id: Option<Uuid>,
86
87 pub group_chat_id: Option<Uuid>,
88
89 pub error_description: Option<String>,
91
92 pub reason: Option<String>,
93
94 pub recipients_param: Option<Vec<Uuid>>,
95
96 #[serde(flatten)]
97 pub other: HashMap<String, String>,
98}
99
100#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder)]
101#[builder(setter(into, prefix = "with", strip_option))]
102pub struct DirectNotificationRequest {
103 pub group_chat_id: Uuid,
105
106 #[builder(default)]
109 pub recipients: Option<Vec<Uuid>>,
110
111 #[builder(default)]
113 pub notification: EventPayload,
114
115 #[builder(default)]
118 pub file: Option<File>,
119
120 #[builder(default)]
122 pub opts: PayloadOptions,
123}
124
125#[cfg(test)]
126mod tests {
127 use crate::api::result::{ExpressResult, BotXApiResult, BotXApiError};
128
129 use super::{DirectNotificationResponse, DirectNotificationExpressError};
130
131 #[test]
132 fn deserialize_result_ok()
133 {
134 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
135 "status": "ok",
136 "result": {
137 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36"
138 }
139 }"#).unwrap();
140
141 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
142 let res = res.ok().unwrap();
143
144 assert_eq!(res.result.sync_id.unwrap(), uuid::Uuid::parse_str("f0f105d2-101f-59b0-9e10-e432efce2c36").unwrap())
145 }
146
147 #[test]
148 fn deserialize_error_chat_not_found_ok()
149 {
150 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
151 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36",
152 "status": "error",
153 "reason": "chat_not_found",
154 "errors": [],
155 "error_data": {
156 "group_chat_id": "705df263-6bfd-536a-9d51-13524afaab5c",
157 "error_description": "Chat with specified id not found"
158 }
159 }"#).unwrap();
160
161 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
162 let err = res.err().unwrap();
163
164 let BotXApiError::ExpressError(err) = err else {
165 panic!("Некорректное десериализация ошибки {:#?}", err);
166 };
167
168 let DirectNotificationExpressError::ChatNotFound(err) = err else {
169 panic!("Некорректное определение типа ошибки");
170 };
171
172 assert_eq!(err.error_data.group_chat_id, uuid::Uuid::parse_str("705df263-6bfd-536a-9d51-13524afaab5c").unwrap())
173 }
174
175 #[test]
176 fn deserialize_error_error_from_messaging_service_ok()
177 {
178 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
179 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36",
180 "status": "error",
181 "reason": "error_from_messaging_service",
182 "errors": [],
183 "error_data": {
184 "group_chat_id": "705df263-6bfd-536a-9d51-13524afaab5c",
185 "reason": "some_error",
186 "error_description": "Messaging service returns error. Check BotX container logs (level :warn or upper) for more info."
187 }
188 }"#).unwrap();
189
190 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
191 let err = res.err().unwrap();
192
193 let BotXApiError::ExpressError(err) = err else {
194 panic!("Некорректное десериализация ошибки {:#?}", err);
195 };
196
197 let DirectNotificationExpressError::ErrorFromMessagingService(err) = err else {
198 panic!("Некорректное определение типа ошибки");
199 };
200
201 assert_eq!(err.error_data.group_chat_id, uuid::Uuid::parse_str("705df263-6bfd-536a-9d51-13524afaab5c").unwrap())
202 }
203
204 #[test]
205 fn deserialize_error_bot_is_not_a_chat_member_ok()
206 {
207 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
208 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36",
209 "status": "error",
210 "reason": "bot_is_not_a_chat_member",
211 "errors": [],
212 "error_data": {
213 "group_chat_id": "705df263-6bfd-536a-9d51-13524afaab5c",
214 "bot_id": "b165f00f-3154-412c-7f11-c120164257da",
215 "error_description": "Bot is not a chat member"
216 }
217 }"#).unwrap();
218
219 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
220 let err = res.err().unwrap();
221
222 let BotXApiError::ExpressError(err) = err else {
223 panic!("Некорректное десериализация ошибки {:#?}", err);
224 };
225
226 let DirectNotificationExpressError::BotIsNotAChatMember(err) = err else {
227 panic!("Некорректное определение типа ошибки");
228 };
229
230 assert_eq!(err.error_data.group_chat_id, uuid::Uuid::parse_str("705df263-6bfd-536a-9d51-13524afaab5c").unwrap())
231 }
232
233 #[test]
234 fn deserialize_error_stealth_mode_disabled_ok()
235 {
236 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
237 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36",
238 "status": "error",
239 "reason": "stealth_mode_disabled",
240 "errors": [],
241 "error_data": {
242 "group_chat_id": "705df263-6bfd-536a-9d51-13524afaab5c",
243 "bot_id": "b165f00f-3154-412c-7f11-c120164257da",
244 "error_description": "Stealth mode disabled in specified chat"
245 }
246 }"#).unwrap();
247
248 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
249 let err = res.err().unwrap();
250
251 let BotXApiError::ExpressError(err) = err else {
252 panic!("Некорректное десериализация ошибки {:#?}", err);
253 };
254
255 let DirectNotificationExpressError::StealthModeDisabled(err) = err else {
256 panic!("Некорректное определение типа ошибки");
257 };
258
259 assert_eq!(err.error_data.group_chat_id, uuid::Uuid::parse_str("705df263-6bfd-536a-9d51-13524afaab5c").unwrap())
260 }
261
262 #[test]
263 fn deserialize_error_event_recipients_list_is_empty_ok()
264 {
265 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
266 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36",
267 "status": "error",
268 "reason": "event_recipients_list_is_empty",
269 "errors": [],
270 "error_data": {
271 "group_chat_id": "705df263-6bfd-536a-9d51-13524afaab5c",
272 "bot_id": "b165f00f-3154-412c-7f11-c120164257da",
273 "recipients_param": ["b165f00f-3154-412c-7f11-c120164257da"],
274 "error_description": "Event recipients list is empty"
275 }
276 }"#).unwrap();
277
278 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
279 let err = res.err().unwrap();
280
281 let BotXApiError::ExpressError(err) = err else {
282 panic!("Некорректное десериализация ошибки");
283 };
284
285 let DirectNotificationExpressError::EventRecipientsListIsEmpty(err) = err else {
286 panic!("Некорректное определение типа ошибки {:#?}", err);
287 };
288
289 assert_eq!(err.error_data.bot_id, uuid::Uuid::parse_str("b165f00f-3154-412c-7f11-c120164257da").unwrap())
290 }
291
292 #[test]
293 fn deserialize_error_flow_processing_error_ok()
294 {
295 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
296 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36",
297 "status": "error",
298 "reason": "flow_processing_error",
299 "errors": ["{error1}", "{error2}"],
300 "error_data": {
301 "error_description": "Got error on flow processing. Check BotX container logs (level :info or upper) for more info"
302 }
303 }"#).unwrap();
304
305 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
306 let err = res.err().unwrap();
307
308 let BotXApiError::ExpressError(err) = err else {
309 panic!("Некорректное десериализация ошибки {:#?}", err);
310 };
311
312 let DirectNotificationExpressError::FlowProcessingError(err) = err else {
313 panic!("Некорректное определение типа ошибки");
314 };
315
316 assert_eq!(err.error_data.error_description, "Got error on flow processing. Check BotX container logs (level :info or upper) for more info".to_string())
317 }
318
319 #[test]
320 fn deserialize_error_unexpected_error_ok()
321 {
322 let res = serde_json::from_str::<ExpressResult<DirectNotificationResponse, DirectNotificationExpressError>>(r#"{
323 "sync_id": "f0f105d2-101f-59b0-9e10-e432efce2c36",
324 "status": "error",
325 "reason": "unexpected_error",
326 "errors": ["{error1}", "{error2}"],
327 "error_data": {
328 "error_description": "Got unexpected error. Check BotX container logs (level :error or upper) for more info"
329 }
330 }"#).unwrap();
331
332 let res: BotXApiResult<DirectNotificationResponse, DirectNotificationExpressError> = res.into();
333 let err = res.err().unwrap();
334
335 let BotXApiError::ExpressError(err) = err else {
336 panic!("Некорректное десериализация ошибки {:#?}", err);
337 };
338
339 let DirectNotificationExpressError::UnexpectedError(err) = err else {
340 panic!("Некорректное определение типа ошибки");
341 };
342
343 assert_eq!(err.error_data.error_description, "Got unexpected error. Check BotX container logs (level :error or upper) for more info".to_string())
344 }
345}