1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize, Default)]
6#[serde(rename_all = "camelCase")]
7pub struct Message {
8 #[serde(skip_serializing_if = "Option::is_none")]
10 pub name: Option<String>,
11
12 #[serde(skip_serializing_if = "Option::is_none")]
14 pub data: Option<HashMap<String, String>>,
15
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub notification: Option<Notification>,
19
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub android: Option<AndroidConfig>,
23
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub webpush: Option<WebpushConfig>,
27
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub apns: Option<ApnsConfig>,
31
32 #[serde(skip_serializing_if = "Option::is_none")]
34 pub fcm_options: Option<FcmOptions>,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub token: Option<String>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
43 pub topic: Option<String>,
44
45 #[serde(skip_serializing_if = "Option::is_none")]
47 pub condition: Option<String>,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, Default)]
52#[serde(rename_all = "camelCase")]
53pub struct MulticastMessage {
54 pub tokens: Vec<String>,
56
57 #[serde(skip_serializing_if = "Option::is_none")]
59 pub data: Option<HashMap<String, String>>,
60
61 #[serde(skip_serializing_if = "Option::is_none")]
63 pub notification: Option<Notification>,
64
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub android: Option<AndroidConfig>,
68
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub webpush: Option<WebpushConfig>,
72
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub apns: Option<ApnsConfig>,
76
77 #[serde(skip_serializing_if = "Option::is_none")]
79 pub fcm_options: Option<FcmOptions>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, Default)]
84#[serde(rename_all = "camelCase")]
85pub struct Notification {
86 #[serde(skip_serializing_if = "Option::is_none")]
88 pub title: Option<String>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub body: Option<String>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub image: Option<String>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, Default)]
101#[serde(rename_all = "camelCase")]
102pub struct AndroidConfig {
103 #[serde(skip_serializing_if = "Option::is_none")]
105 pub collapse_key: Option<String>,
106
107 #[serde(skip_serializing_if = "Option::is_none")]
109 pub priority: Option<AndroidMessagePriority>,
110
111 #[serde(skip_serializing_if = "Option::is_none")]
113 pub ttl: Option<String>,
114
115 #[serde(skip_serializing_if = "Option::is_none")]
117 pub restricted_package_name: Option<String>,
118
119 #[serde(skip_serializing_if = "Option::is_none")]
121 pub data: Option<HashMap<String, String>>,
122
123 #[serde(skip_serializing_if = "Option::is_none")]
125 pub notification: Option<AndroidNotification>,
126
127 #[serde(skip_serializing_if = "Option::is_none")]
129 pub fcm_options: Option<AndroidFcmOptions>,
130
131 #[serde(skip_serializing_if = "Option::is_none")]
133 pub direct_boot_ok: Option<bool>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
138#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
139pub enum AndroidMessagePriority {
140 Normal,
142 High,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize, Default)]
148#[serde(rename_all = "camelCase")]
149pub struct AndroidNotification {
150 #[serde(skip_serializing_if = "Option::is_none")]
152 pub title: Option<String>,
153
154 #[serde(skip_serializing_if = "Option::is_none")]
156 pub body: Option<String>,
157
158 #[serde(skip_serializing_if = "Option::is_none")]
160 pub icon: Option<String>,
161
162 #[serde(skip_serializing_if = "Option::is_none")]
164 pub color: Option<String>,
165
166 #[serde(skip_serializing_if = "Option::is_none")]
168 pub sound: Option<String>,
169
170 #[serde(skip_serializing_if = "Option::is_none")]
172 pub tag: Option<String>,
173
174 #[serde(skip_serializing_if = "Option::is_none")]
176 pub click_action: Option<String>,
177
178 #[serde(skip_serializing_if = "Option::is_none")]
180 pub body_loc_key: Option<String>,
181
182 #[serde(skip_serializing_if = "Option::is_none")]
184 pub body_loc_args: Option<Vec<String>>,
185
186 #[serde(skip_serializing_if = "Option::is_none")]
188 pub title_loc_key: Option<String>,
189
190 #[serde(skip_serializing_if = "Option::is_none")]
192 pub title_loc_args: Option<Vec<String>>,
193
194 #[serde(skip_serializing_if = "Option::is_none")]
196 pub channel_id: Option<String>,
197
198 #[serde(skip_serializing_if = "Option::is_none")]
200 pub ticker: Option<String>,
201
202 #[serde(skip_serializing_if = "Option::is_none")]
204 pub sticky: Option<bool>,
205
206 #[serde(skip_serializing_if = "Option::is_none")]
208 pub event_time: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
212 pub local_only: Option<bool>,
213
214 #[serde(skip_serializing_if = "Option::is_none")]
216 pub notification_priority: Option<NotificationPriority>,
217
218 #[serde(skip_serializing_if = "Option::is_none")]
220 pub default_sound: Option<bool>,
221
222 #[serde(skip_serializing_if = "Option::is_none")]
224 pub default_vibrate_timings: Option<bool>,
225
226 #[serde(skip_serializing_if = "Option::is_none")]
228 pub default_light_settings: Option<bool>,
229
230 #[serde(skip_serializing_if = "Option::is_none")]
232 pub vibrate_timings: Option<Vec<String>>, #[serde(skip_serializing_if = "Option::is_none")]
236 pub visibility: Option<Visibility>,
237
238 #[serde(skip_serializing_if = "Option::is_none")]
240 pub notification_count: Option<i32>,
241
242 #[serde(skip_serializing_if = "Option::is_none")]
244 pub light_settings: Option<LightSettings>,
245
246 #[serde(skip_serializing_if = "Option::is_none")]
248 pub image: Option<String>,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize)]
253#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
254pub enum NotificationPriority {
255 PriorityUnspecified,
257 PriorityMin,
259 PriorityLow,
261 PriorityDefault,
263 PriorityHigh,
265 PriorityMax,
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize)]
271#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
272pub enum Visibility {
273 VisibilityUnspecified,
275 Private,
277 Public,
279 Secret,
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize, Default)]
285#[serde(rename_all = "camelCase")]
286pub struct LightSettings {
287 pub color: Option<Color>,
289 pub light_on_duration: Option<String>,
291 pub light_off_duration: Option<String>,
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize, Default)]
297#[serde(rename_all = "camelCase")]
298pub struct Color {
299 pub red: Option<f32>,
301 pub green: Option<f32>,
303 pub blue: Option<f32>,
305 pub alpha: Option<f32>,
307}
308
309#[derive(Debug, Clone, Serialize, Deserialize, Default)]
311#[serde(rename_all = "camelCase")]
312pub struct AndroidFcmOptions {
313 #[serde(skip_serializing_if = "Option::is_none")]
315 pub analytics_label: Option<String>,
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize, Default)]
320#[serde(rename_all = "camelCase")]
321pub struct WebpushConfig {
322 #[serde(skip_serializing_if = "Option::is_none")]
324 pub headers: Option<HashMap<String, String>>,
325
326 #[serde(skip_serializing_if = "Option::is_none")]
328 pub data: Option<HashMap<String, String>>,
329
330 #[serde(skip_serializing_if = "Option::is_none")]
332 pub notification: Option<serde_json::Value>, #[serde(skip_serializing_if = "Option::is_none")]
336 pub fcm_options: Option<WebpushFcmOptions>,
337}
338
339#[derive(Debug, Clone, Serialize, Deserialize, Default)]
341#[serde(rename_all = "camelCase")]
342pub struct WebpushFcmOptions {
343 #[serde(skip_serializing_if = "Option::is_none")]
345 pub link: Option<String>,
346 #[serde(skip_serializing_if = "Option::is_none")]
348 pub analytics_label: Option<String>,
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize, Default)]
353#[serde(rename_all = "camelCase")]
354pub struct ApnsConfig {
355 #[serde(skip_serializing_if = "Option::is_none")]
357 pub headers: Option<HashMap<String, String>>,
358
359 #[serde(skip_serializing_if = "Option::is_none")]
361 pub payload: Option<ApnsPayload>,
362
363 #[serde(skip_serializing_if = "Option::is_none")]
365 pub fcm_options: Option<ApnsFcmOptions>,
366}
367
368#[derive(Debug, Clone, Serialize, Deserialize, Default)]
370#[serde(rename_all = "camelCase")]
371pub struct ApnsPayload {
372 #[serde(skip_serializing_if = "Option::is_none")]
374 pub aps: Option<Aps>,
375
376 #[serde(flatten)]
378 pub custom_data: Option<HashMap<String, serde_json::Value>>,
379}
380
381#[derive(Debug, Clone, Serialize, Deserialize, Default)]
383#[serde(rename_all = "kebab-case")]
384pub struct Aps {
385 #[serde(skip_serializing_if = "Option::is_none")]
387 pub alert: Option<ApsAlert>,
388
389 #[serde(skip_serializing_if = "Option::is_none")]
391 pub badge: Option<i32>,
392
393 #[serde(skip_serializing_if = "Option::is_none")]
395 pub sound: Option<String>,
396
397 #[serde(skip_serializing_if = "Option::is_none")]
399 pub content_available: Option<i32>, #[serde(skip_serializing_if = "Option::is_none")]
403 pub mutable_content: Option<i32>, #[serde(skip_serializing_if = "Option::is_none")]
407 pub category: Option<String>,
408
409 #[serde(skip_serializing_if = "Option::is_none")]
411 pub thread_id: Option<String>,
412}
413
414#[derive(Debug, Clone, Serialize, Deserialize)]
416#[serde(untagged)]
417pub enum ApsAlert {
418 String(String),
420 Dictionary(ApsAlertDictionary),
422}
423
424#[derive(Debug, Clone, Serialize, Deserialize, Default)]
426#[serde(rename_all = "kebab-case")]
427pub struct ApsAlertDictionary {
428 #[serde(skip_serializing_if = "Option::is_none")]
430 pub title: Option<String>,
431 #[serde(skip_serializing_if = "Option::is_none")]
433 pub subtitle: Option<String>,
434 #[serde(skip_serializing_if = "Option::is_none")]
436 pub body: Option<String>,
437 #[serde(skip_serializing_if = "Option::is_none")]
439 pub loc_key: Option<String>,
440 #[serde(skip_serializing_if = "Option::is_none")]
442 pub loc_args: Option<Vec<String>>,
443 #[serde(skip_serializing_if = "Option::is_none")]
445 pub title_loc_key: Option<String>,
446 #[serde(skip_serializing_if = "Option::is_none")]
448 pub title_loc_args: Option<Vec<String>>,
449 #[serde(skip_serializing_if = "Option::is_none")]
451 pub subtitle_loc_key: Option<String>,
452 #[serde(skip_serializing_if = "Option::is_none")]
454 pub subtitle_loc_args: Option<Vec<String>>,
455 #[serde(skip_serializing_if = "Option::is_none")]
457 pub action_loc_key: Option<String>,
458 #[serde(skip_serializing_if = "Option::is_none")]
460 pub launch_image: Option<String>,
461}
462
463#[derive(Debug, Clone, Serialize, Deserialize, Default)]
465#[serde(rename_all = "camelCase")]
466pub struct ApnsFcmOptions {
467 #[serde(skip_serializing_if = "Option::is_none")]
469 pub analytics_label: Option<String>,
470 #[serde(skip_serializing_if = "Option::is_none")]
472 pub image: Option<String>,
473}
474
475#[derive(Debug, Clone, Serialize, Deserialize, Default)]
477#[serde(rename_all = "camelCase")]
478pub struct FcmOptions {
479 #[serde(skip_serializing_if = "Option::is_none")]
481 pub analytics_label: Option<String>,
482}
483
484#[derive(Debug, Clone, Serialize, Deserialize, Default)]
486#[serde(rename_all = "camelCase")]
487pub struct TopicManagementResponse {
488 pub success_count: usize,
490 pub failure_count: usize,
492 pub errors: Vec<TopicManagementError>,
494}
495
496#[derive(Debug, Clone, Serialize, Deserialize)]
498#[serde(rename_all = "camelCase")]
499pub struct TopicManagementError {
500 pub index: usize,
502 pub reason: String,
504}
505
506#[derive(Debug, Clone, Default)]
508pub struct BatchResponse {
509 pub success_count: usize,
511 pub failure_count: usize,
513 pub responses: Vec<SendResponse>,
515}
516
517#[derive(Debug, Clone)]
519pub struct SendResponse {
520 pub success: bool,
522 pub message_id: Option<String>,
524 pub error: Option<String>,
526}
527
528#[derive(Debug, Deserialize)]
529pub(crate) struct SendResponseInternal {
530 pub name: String,
531}