From 38c3b2875a78dae47aa1c2f92ddaa0b995b6a593 Mon Sep 17 00:00:00 2001 From: adnanjpg Date: Mon, 22 Jan 2024 16:14:07 +0300 Subject: [PATCH] Revert "feat: build new api" This reverts commit 069246e247c64a61422c4b03287333913d0d7923. --- a.sh | 1 - examples/simple_sender.rs | 37 ++-- src/android/android_config.rs | 73 -------- src/android/android_fcm_options.rs | 21 --- src/android/android_message_priority.rs | 10 - src/android/android_notification.rs | 234 ------------------------ src/android/color.rs | 43 ----- src/android/light_settings.rs | 43 ----- src/android/mod.rs | 229 ++++++++++++++++++++++- src/android/notification_priority.rs | 14 -- src/android/visibility.rs | 12 -- src/apns/apns_config.rs | 37 ---- src/apns/apns_fcm_options.rs | 29 --- src/apns/mod.rs | 30 ++- src/client/mod.rs | 24 +-- src/lib.rs | 1 - src/message/fcm_options.rs | 21 --- src/message/mod.rs | 128 +++++++++---- src/message/target.rs | 9 - src/message/tests.rs | 136 ++++---------- src/notification/mod.rs | 45 +++-- src/notification/tests.rs | 50 ++++- src/web/mod.rs | 35 +++- src/web/webpush_config.rs | 44 ----- src/web/webpush_fcm_options.rs | 30 --- 25 files changed, 498 insertions(+), 838 deletions(-) delete mode 100644 a.sh delete mode 100644 src/android/android_config.rs delete mode 100644 src/android/android_fcm_options.rs delete mode 100644 src/android/android_message_priority.rs delete mode 100644 src/android/android_notification.rs delete mode 100644 src/android/color.rs delete mode 100644 src/android/light_settings.rs delete mode 100644 src/android/notification_priority.rs delete mode 100644 src/android/visibility.rs delete mode 100644 src/apns/apns_config.rs delete mode 100644 src/apns/apns_fcm_options.rs delete mode 100644 src/message/fcm_options.rs delete mode 100644 src/message/target.rs delete mode 100644 src/web/webpush_config.rs delete mode 100644 src/web/webpush_fcm_options.rs diff --git a/a.sh b/a.sh deleted file mode 100644 index 5d89ab970..000000000 --- a/a.sh +++ /dev/null @@ -1 +0,0 @@ -cargo run --example simple_sender -- -t fP0EXs_HQ4Gj1sE5xBP6LP:APA91bGxDOk4GzvIvvGFPa6kDWOOHm2zYA3tUN1jYwErSBq_s27NioYjYWfUpgUW3_LIsreSw1pbtTjEpCK_cKR6AHxo1PGZ1Yd3S8lyX148I_LgKaTNYorG2QtkcwfB9Nm5yKGJwLaG \ No newline at end of file diff --git a/examples/simple_sender.rs b/examples/simple_sender.rs index fb7cedc28..6a634b801 100644 --- a/examples/simple_sender.rs +++ b/examples/simple_sender.rs @@ -1,8 +1,11 @@ -// cargo run --example simple_sender -- -t - use argparse::{ArgumentParser, Store}; -use fcm::{fcm_options::FcmOptions, target::Target, Client, Message, Notification}; -use serde_json::json; +use fcm::{Client, MessageBuilder, Target}; +use serde::Serialize; + +#[derive(Serialize)] +struct CustomData { + message: &'static str, +} #[tokio::main] async fn main() -> Result<(), Box> { @@ -19,28 +22,12 @@ async fn main() -> Result<(), Box> { } let client = Client::new(); + let data = CustomData { message: "howdy" }; + + let mut builder = MessageBuilder::new(Target::Token(device_token)); + builder.data(&data)?; - let data = json!({ - "key": "value", - }); - - let builder = Message { - data: Some(data), - notification: Some(Notification { - title: Some("Hello".to_string()), - body: Some(format!("it's {}", chrono::Utc::now())), - image: None, - }), - target: Target::Token(device_token), - android: None, - webpush: None, - apns: None, - fcm_options: Some(FcmOptions { - analytics_label: "analytics_label".to_string(), - }), - }; - - let response = client.send(builder).await?; + let response = client.send(builder.finalize()).await?; println!("Sent: {:?}", response); Ok(()) diff --git a/src/android/android_config.rs b/src/android/android_config.rs deleted file mode 100644 index 800a840e5..000000000 --- a/src/android/android_config.rs +++ /dev/null @@ -1,73 +0,0 @@ -use serde::Serialize; -use serde_json::Value; - -use super::{ - android_fcm_options::{AndroidFcmOptions, AndroidFcmOptionsInternal}, - android_message_priority::AndroidMessagePriority, - android_notification::{AndroidNotification, AndroidNotificationInternal}, -}; - -#[derive(Serialize, Debug)] -//https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidconfig -pub struct AndroidConfigInternal { - // An identifier of a group of messages that can be collapsed, so that only the last message gets - // sent when delivery can be resumed. - #[serde(skip_serializing_if = "Option::is_none")] - collapse_key: Option, - - // Message priority. - #[serde(skip_serializing_if = "Option::is_none")] - priority: Option, - - // How long (in seconds) the message should be kept in FCM storage if the device is offline. - // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration - #[serde(skip_serializing_if = "Option::is_none")] - ttl: Option, - - // Package name of the application where the registration token must match in order to receive the message. - #[serde(skip_serializing_if = "Option::is_none")] - restricted_package_name: Option, - - // Arbitrary key/value payload. - #[serde(skip_serializing_if = "Option::is_none")] - data: Option, - - // Notification to send to android devices. - #[serde(skip_serializing_if = "Option::is_none")] - notification: Option, - - // Options for features provided by the FCM SDK for Android. - #[serde(skip_serializing_if = "Option::is_none")] - fcm_options: Option, - - // If set to true, messages will be allowed to be delivered to the app while the device is in direct boot mode. - #[serde(skip_serializing_if = "Option::is_none")] - direct_boot_ok: Option, -} - -#[derive(Debug)] -pub struct AndroidConfig { - pub collapse_key: Option, - pub priority: Option, - pub ttl: Option, - pub restricted_package_name: Option, - pub data: Option, - pub notification: Option, - pub fcm_options: Option, - pub direct_boot_ok: Option, -} - -impl AndroidConfig { - pub fn finalize(self) -> AndroidConfigInternal { - AndroidConfigInternal { - collapse_key: self.collapse_key, - priority: self.priority, - ttl: self.ttl, - restricted_package_name: self.restricted_package_name, - data: self.data, - notification: self.notification.map(|n| n.finalize()), - fcm_options: self.fcm_options.map(|f| f.finalize()), - direct_boot_ok: self.direct_boot_ok, - } - } -} diff --git a/src/android/android_fcm_options.rs b/src/android/android_fcm_options.rs deleted file mode 100644 index 81a32de7a..000000000 --- a/src/android/android_fcm_options.rs +++ /dev/null @@ -1,21 +0,0 @@ -use serde::Serialize; - -#[derive(Serialize, Debug)] -//https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidconfig -pub struct AndroidFcmOptionsInternal { - // Label associated with the message's analytics data. - analytics_label: String, -} - -#[derive(Debug)] -pub struct AndroidFcmOptions { - pub analytics_label: String, -} - -impl AndroidFcmOptions { - pub fn finalize(self) -> AndroidFcmOptionsInternal { - AndroidFcmOptionsInternal { - analytics_label: self.analytics_label, - } - } -} diff --git a/src/android/android_message_priority.rs b/src/android/android_message_priority.rs deleted file mode 100644 index 046466294..000000000 --- a/src/android/android_message_priority.rs +++ /dev/null @@ -1,10 +0,0 @@ -use serde::Serialize; - -#[allow(dead_code)] -#[derive(Serialize, Debug)] -#[serde(rename_all = "UPPERCASE")] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidmessagepriority -pub enum AndroidMessagePriority { - Normal, - High, -} diff --git a/src/android/android_notification.rs b/src/android/android_notification.rs deleted file mode 100644 index 0656c13fe..000000000 --- a/src/android/android_notification.rs +++ /dev/null @@ -1,234 +0,0 @@ -use serde::Serialize; - -use super::{ - light_settings::{LightSettings, LightSettingsInternal}, - notification_priority::NotificationPriority, - visibility::Visibility, -}; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidnotification -pub struct AndroidNotificationInternal { - // The notification's title. - #[serde(skip_serializing_if = "Option::is_none")] - title: Option, - - // The notification's body text. - #[serde(skip_serializing_if = "Option::is_none")] - body: Option, - - // The notification's icon. - #[serde(skip_serializing_if = "Option::is_none")] - icon: Option, - - // The notification's icon color, expressed in #rrggbb format. - #[serde(skip_serializing_if = "Option::is_none")] - color: Option, - - // The sound to play when the device receives the notification. - #[serde(skip_serializing_if = "Option::is_none")] - sound: Option, - - // Identifier used to replace existing notifications in the notification drawer. - #[serde(skip_serializing_if = "Option::is_none")] - tag: Option, - - // The action associated with a user click on the notification. - #[serde(skip_serializing_if = "Option::is_none")] - click_action: Option, - - // The key to the body string in the app's string resources to use to localize the body text to the user's - // current localization. - #[serde(skip_serializing_if = "Option::is_none")] - body_loc_key: Option, - - // Variable string values to be used in place of the format specifiers in body_loc_key to use to localize the - // body text to the user's current localization. - #[serde(skip_serializing_if = "Option::is_none")] - body_loc_args: Option>, - - // The key to the title string in the app's string resources to use to localize the title text to the user's - // current localization. - #[serde(skip_serializing_if = "Option::is_none")] - title_loc_key: Option, - - // Variable string values to be used in place of the format specifiers in title_loc_key to use to localize the - // title text to the user's current localization. - #[serde(skip_serializing_if = "Option::is_none")] - title_loc_args: Option>, - - // The notification's channel id (new in Android O). - #[serde(skip_serializing_if = "Option::is_none")] - channel_id: Option, - - // Sets the "ticker" text, which is sent to accessibility services. - #[serde(skip_serializing_if = "Option::is_none")] - ticker: Option, - - // When set to false or unset, the notification is automatically dismissed when the user clicks it in the panel. - #[serde(skip_serializing_if = "Option::is_none")] - sticky: Option, - - // Set the time that the event in the notification occurred. Notifications in the panel are sorted by this time. - // Timestamp format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Timestamp - #[serde(skip_serializing_if = "Option::is_none")] - event_time: Option, - - // Set whether or not this notification is relevant only to the current device. - #[serde(skip_serializing_if = "Option::is_none")] - local_only: Option, - - // Set the relative priority for this notification. - #[serde(skip_serializing_if = "Option::is_none")] - notification_priority: Option, - - // If set to true, use the Android framework's default sound for the notification. - #[serde(skip_serializing_if = "Option::is_none")] - default_sound: Option, - - // If set to true, use the Android framework's default vibrate pattern for the notification. - #[serde(skip_serializing_if = "Option::is_none")] - default_vibrate_timings: Option, - - // If set to true, use the Android framework's default LED light settings for the notification. - #[serde(skip_serializing_if = "Option::is_none")] - default_light_settings: Option, - - // Set the vibration pattern to use - // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration - #[serde(skip_serializing_if = "Option::is_none")] - vibrate_timings: Option>, - - // Set the Notification.visibility of the notification. - #[serde(skip_serializing_if = "Option::is_none")] - visibility: Option, - - // Sets the number of items this notification represents. - #[serde(skip_serializing_if = "Option::is_none")] - notification_count: Option, - - // Settings to control the notification's LED blinking rate and color if LED is available on the device. - #[serde(skip_serializing_if = "Option::is_none")] - light_settings: Option, - - // Contains the URL of an image that is going to be displayed in a notification. - #[serde(skip_serializing_if = "Option::is_none")] - image: Option, -} - -#[derive(Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidnotification -pub struct AndroidNotification { - // The notification's title. - pub title: Option, - - // The notification's body text. - pub body: Option, - - // The notification's icon. - pub icon: Option, - - // The notification's icon color, expressed in #rrggbb format. - pub color: Option, - - // The sound to play when the device receives the notification. - pub sound: Option, - - // Identifier used to replace existing notifications in the notification drawer. - pub tag: Option, - - // The action associated with a user click on the notification. - pub click_action: Option, - - // The key to the body string in the app's string resources to use to localize the body text to the user's - // current localization. - pub body_loc_key: Option, - - // Variable string values to be used in place of the format specifiers in body_loc_key to use to localize the - // body text to the user's current localization. - pub body_loc_args: Option>, - - // The key to the title string in the app's string resources to use to localize the title text to the user's - // current localization. - pub title_loc_key: Option, - - // Variable string values to be used in place of the format specifiers in title_loc_key to use to localize the - // title text to the user's current localization. - pub title_loc_args: Option>, - - // The notification's channel id (new in Android O). - pub channel_id: Option, - - // Sets the "ticker" text, which is sent to accessibility services. - pub ticker: Option, - - // When set to false or unset, the notification is automatically dismissed when the user clicks it in the panel. - pub sticky: Option, - - // Set the time that the event in the notification occurred. Notifications in the panel are sorted by this time. - // Timestamp format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Timestamp - pub event_time: Option, - - // Set whether or not this notification is relevant only to the current device. - pub local_only: Option, - - // Set the relative priority for this notification. - pub notification_priority: Option, - - // If set to true, use the Android framework's default sound for the notification. - pub default_sound: Option, - - // If set to true, use the Android framework's default vibrate pattern for the notification. - pub default_vibrate_timings: Option, - - // If set to true, use the Android framework's default LED light settings for the notification. - pub default_light_settings: Option, - - // Set the vibration pattern to use - // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration - pub vibrate_timings: Option>, - - // Set the Notification.visibility of the notification. - pub visibility: Option, - - // Sets the number of items this notification represents. - pub notification_count: Option, - - // Settings to control the notification's LED blinking rate and color if LED is available on the device. - pub light_settings: Option, - - // Contains the URL of an image that is going to be displayed in a notification. - pub image: Option, -} - -impl AndroidNotification { - pub fn finalize(self) -> AndroidNotificationInternal { - AndroidNotificationInternal { - title: self.title, - body: self.body, - icon: self.icon, - color: self.color, - sound: self.sound, - tag: self.tag, - click_action: self.click_action, - body_loc_key: self.body_loc_key, - body_loc_args: self.body_loc_args, - title_loc_key: self.title_loc_key, - title_loc_args: self.title_loc_args, - channel_id: self.channel_id, - ticker: self.ticker, - sticky: self.sticky, - event_time: self.event_time, - local_only: self.local_only, - notification_priority: self.notification_priority, - default_sound: self.default_sound, - default_vibrate_timings: self.default_vibrate_timings, - default_light_settings: self.default_light_settings, - vibrate_timings: self.vibrate_timings, - visibility: self.visibility, - notification_count: self.notification_count, - light_settings: self.light_settings.map(|x| x.finalize()), - image: self.image, - } - } -} diff --git a/src/android/color.rs b/src/android/color.rs deleted file mode 100644 index 9520607f3..000000000 --- a/src/android/color.rs +++ /dev/null @@ -1,43 +0,0 @@ -use serde::Serialize; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#Color -pub struct ColorInternal { - // The amount of red in the color as a value in the interval [0, 1]. - red: f32, - - // The amount of green in the color as a value in the interval [0, 1]. - green: f32, - - // The amount of blue in the color as a value in the interval [0, 1]. - blue: f32, - - // The fraction of this color that should be applied to the pixel. - alpha: f32, -} - -#[derive(Debug)] -pub struct Color { - // The amount of red in the color as a value in the interval [0, 1]. - pub red: f32, - - // The amount of green in the color as a value in the interval [0, 1]. - pub green: f32, - - // The amount of blue in the color as a value in the interval [0, 1]. - pub blue: f32, - - // The fraction of this color that should be applied to the pixel. - pub alpha: f32, -} - -impl Color { - pub fn finalize(self) -> ColorInternal { - ColorInternal { - red: self.red, - green: self.green, - blue: self.blue, - alpha: self.alpha, - } - } -} diff --git a/src/android/light_settings.rs b/src/android/light_settings.rs deleted file mode 100644 index 43cd7b01b..000000000 --- a/src/android/light_settings.rs +++ /dev/null @@ -1,43 +0,0 @@ -use serde::Serialize; - -use super::color::{Color, ColorInternal}; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#LightSettings -pub struct LightSettingsInternal { - // Set color of the LED with google.type.Color. - color: ColorInternal, - - // Along with light_off_duration, define the blink rate of LED flashes - // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration - light_on_duration: String, - - // Along with light_on_duration, define the blink rate of LED flashes. - // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration - light_off_duration: String, -} - -#[derive(Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#LightSettings -pub struct LightSettings { - // Set color of the LED with google.type.Color. - pub color: Color, - - // Along with light_off_duration, define the blink rate of LED flashes - // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration - pub light_on_duration: String, - - // Along with light_on_duration, define the blink rate of LED flashes. - // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration - pub light_off_duration: String, -} - -impl LightSettings { - pub fn finalize(self) -> LightSettingsInternal { - LightSettingsInternal { - color: self.color.finalize(), - light_on_duration: self.light_on_duration, - light_off_duration: self.light_off_duration, - } - } -} diff --git a/src/android/mod.rs b/src/android/mod.rs index b4ba2e81b..a0f1778a0 100644 --- a/src/android/mod.rs +++ b/src/android/mod.rs @@ -1,8 +1,221 @@ -pub mod android_config; -pub mod android_fcm_options; -pub mod android_message_priority; -pub mod android_notification; -pub mod color; -pub mod light_settings; -pub mod notification_priority; -pub mod visibility; +use serde::Serialize; +use serde_json::Value; + +#[derive(Serialize, Debug)] +//https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidconfig +pub struct AndroidConfig { + // An identifier of a group of messages that can be collapsed, so that only the last message gets + // sent when delivery can be resumed. + #[serde(skip_serializing_if = "Option::is_none")] + collapse_key: Option, + + // Message priority. + #[serde(skip_serializing_if = "Option::is_none")] + priority: Option, + + // How long (in seconds) the message should be kept in FCM storage if the device is offline. + // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration + #[serde(skip_serializing_if = "Option::is_none")] + ttl: Option, + + // Package name of the application where the registration token must match in order to receive the message. + #[serde(skip_serializing_if = "Option::is_none")] + restricted_package_name: Option, + + // Arbitrary key/value payload. + #[serde(skip_serializing_if = "Option::is_none")] + data: Option, + + // Notification to send to android devices. + #[serde(skip_serializing_if = "Option::is_none")] + notification: Option, + + // Options for features provided by the FCM SDK for Android. + #[serde(skip_serializing_if = "Option::is_none")] + fcm_options: Option, + + // If set to true, messages will be allowed to be delivered to the app while the device is in direct boot mode. + #[serde(skip_serializing_if = "Option::is_none")] + direct_boot_ok: Option, +} + +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#Color +pub struct Color { + // The amount of red in the color as a value in the interval [0, 1]. + red: f32, + + // The amount of green in the color as a value in the interval [0, 1]. + green: f32, + + // The amount of blue in the color as a value in the interval [0, 1]. + blue: f32, + + // The fraction of this color that should be applied to the pixel. + alpha: f32, +} + +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#LightSettings +pub struct LightSettings { + // Set color of the LED with google.type.Color. + color: Color, + + // Along with light_off_duration, define the blink rate of LED flashes + // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration + light_on_duration: String, + + // Along with light_on_duration, define the blink rate of LED flashes. + // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration + light_off_duration: String, +} + +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidnotification +pub struct AndroidNotification { + // The notification's title. + #[serde(skip_serializing_if = "Option::is_none")] + title: Option, + + // The notification's body text. + #[serde(skip_serializing_if = "Option::is_none")] + body: Option, + + // The notification's icon. + #[serde(skip_serializing_if = "Option::is_none")] + icon: Option, + + // The notification's icon color, expressed in #rrggbb format. + #[serde(skip_serializing_if = "Option::is_none")] + color: Option, + + // The sound to play when the device receives the notification. + #[serde(skip_serializing_if = "Option::is_none")] + sound: Option, + + // Identifier used to replace existing notifications in the notification drawer. + #[serde(skip_serializing_if = "Option::is_none")] + tag: Option, + + // The action associated with a user click on the notification. + #[serde(skip_serializing_if = "Option::is_none")] + click_action: Option, + + // The key to the body string in the app's string resources to use to localize the body text to the user's + // current localization. + #[serde(skip_serializing_if = "Option::is_none")] + body_loc_key: Option, + + // Variable string values to be used in place of the format specifiers in body_loc_key to use to localize the + // body text to the user's current localization. + #[serde(skip_serializing_if = "Option::is_none")] + body_loc_args: Option>, + + // The key to the title string in the app's string resources to use to localize the title text to the user's + // current localization. + #[serde(skip_serializing_if = "Option::is_none")] + title_loc_key: Option, + + // Variable string values to be used in place of the format specifiers in title_loc_key to use to localize the + // title text to the user's current localization. + #[serde(skip_serializing_if = "Option::is_none")] + title_loc_args: Option>, + + // The notification's channel id (new in Android O). + #[serde(skip_serializing_if = "Option::is_none")] + channel_id: Option, + + // Sets the "ticker" text, which is sent to accessibility services. + #[serde(skip_serializing_if = "Option::is_none")] + ticker: Option, + + // When set to false or unset, the notification is automatically dismissed when the user clicks it in the panel. + #[serde(skip_serializing_if = "Option::is_none")] + sticky: Option, + + // Set the time that the event in the notification occurred. Notifications in the panel are sorted by this time. + // Timestamp format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Timestamp + #[serde(skip_serializing_if = "Option::is_none")] + event_time: Option, + + // Set whether or not this notification is relevant only to the current device. + #[serde(skip_serializing_if = "Option::is_none")] + local_only: Option, + + // Set the relative priority for this notification. + #[serde(skip_serializing_if = "Option::is_none")] + notification_priority: Option, + + // If set to true, use the Android framework's default sound for the notification. + #[serde(skip_serializing_if = "Option::is_none")] + default_sound: Option, + + // If set to true, use the Android framework's default vibrate pattern for the notification. + #[serde(skip_serializing_if = "Option::is_none")] + default_vibrate_timings: Option, + + // If set to true, use the Android framework's default LED light settings for the notification. + #[serde(skip_serializing_if = "Option::is_none")] + default_light_settings: Option, + + // Set the vibration pattern to use + // Duration format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Duration + #[serde(skip_serializing_if = "Option::is_none")] + vibrate_timings: Option>, + + // Set the Notification.visibility of the notification. + #[serde(skip_serializing_if = "Option::is_none")] + visibility: Option, + + // Sets the number of items this notification represents. + #[serde(skip_serializing_if = "Option::is_none")] + notification_count: Option, + + // Settings to control the notification's LED blinking rate and color if LED is available on the device. + #[serde(skip_serializing_if = "Option::is_none")] + light_settings: Option, + + // Contains the URL of an image that is going to be displayed in a notification. + #[serde(skip_serializing_if = "Option::is_none")] + image: Option, +} + +#[derive(Serialize, Debug)] +//https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidconfig +pub struct AndroidFcmOptions { + // Label associated with the message's analytics data. + analytics_label: String, +} + +#[allow(dead_code)] +#[derive(Serialize, Debug)] +#[serde(rename_all = "UPPERCASE")] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#androidmessagepriority +pub enum AndroidMessagePriority { + Normal, + High, +} + +#[allow(dead_code)] +#[derive(Serialize, Debug)] +#[serde(rename_all = "UPPERCASE")] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#notificationpriority +pub enum NotificationPriority { + PriorityUnspecified, + PriorityMin, + PriorityLow, + PriorityDefault, + PriorityHigh, + PriorityMax, +} + +#[allow(dead_code)] +#[derive(Serialize, Debug)] +#[serde(rename_all = "UPPERCASE")] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#visibility +pub enum Visibility { + VisibilityUnspecified, + Private, + Public, + Secret, +} diff --git a/src/android/notification_priority.rs b/src/android/notification_priority.rs deleted file mode 100644 index bb1bdbf17..000000000 --- a/src/android/notification_priority.rs +++ /dev/null @@ -1,14 +0,0 @@ -use serde::Serialize; - -#[allow(dead_code)] -#[derive(Serialize, Debug)] -#[serde(rename_all = "UPPERCASE")] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#notificationpriority -pub enum NotificationPriority { - PriorityUnspecified, - PriorityMin, - PriorityLow, - PriorityDefault, - PriorityHigh, - PriorityMax, -} diff --git a/src/android/visibility.rs b/src/android/visibility.rs deleted file mode 100644 index cd8b56dd4..000000000 --- a/src/android/visibility.rs +++ /dev/null @@ -1,12 +0,0 @@ -use serde::Serialize; - -#[allow(dead_code)] -#[derive(Serialize, Debug)] -#[serde(rename_all = "UPPERCASE")] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#visibility -pub enum Visibility { - VisibilityUnspecified, - Private, - Public, - Secret, -} diff --git a/src/apns/apns_config.rs b/src/apns/apns_config.rs deleted file mode 100644 index 6d2b6b8e8..000000000 --- a/src/apns/apns_config.rs +++ /dev/null @@ -1,37 +0,0 @@ -use serde::Serialize; -use serde_json::Value; - -use super::apns_fcm_options::{ApnsFcmOptions, ApnsFcmOptionsInternal}; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#apnsconfig -pub struct ApnsConfigInternal { - // HTTP request headers defined in Apple Push Notification Service. - #[serde(skip_serializing_if = "Option::is_none")] - headers: Option, - - // APNs payload as a JSON object, including both aps dictionary and custom payload. - #[serde(skip_serializing_if = "Option::is_none")] - payload: Option, - - // Options for features provided by the FCM SDK for iOS. - #[serde(skip_serializing_if = "Option::is_none")] - fcm_options: Option, -} - -#[derive(Debug)] -pub struct ApnsConfig { - pub headers: Option, - pub payload: Option, - pub fcm_options: Option, -} - -impl ApnsConfig { - pub fn finalize(self) -> ApnsConfigInternal { - ApnsConfigInternal { - headers: self.headers, - payload: self.payload, - fcm_options: self.fcm_options.map(|fcm_options| fcm_options.finalize()), - } - } -} diff --git a/src/apns/apns_fcm_options.rs b/src/apns/apns_fcm_options.rs deleted file mode 100644 index 841fa6412..000000000 --- a/src/apns/apns_fcm_options.rs +++ /dev/null @@ -1,29 +0,0 @@ -use serde::Serialize; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#apnsfcmoptions -pub struct ApnsFcmOptionsInternal { - // Label associated with the message's analytics data. - analytics_label: Option, - - // Contains the URL of an image that is going to be displayed in a notification. - image: Option, -} - -#[derive(Debug)] -pub struct ApnsFcmOptions { - // Label associated with the message's analytics data. - pub analytics_label: Option, - - // Contains the URL of an image that is going to be displayed in a notification. - pub image: Option, -} - -impl ApnsFcmOptions { - pub fn finalize(self) -> ApnsFcmOptionsInternal { - ApnsFcmOptionsInternal { - analytics_label: self.analytics_label, - image: self.image, - } - } -} diff --git a/src/apns/mod.rs b/src/apns/mod.rs index 8cd464e28..bfd5a2f71 100644 --- a/src/apns/mod.rs +++ b/src/apns/mod.rs @@ -1,2 +1,28 @@ -pub mod apns_config; -pub mod apns_fcm_options; +use serde::Serialize; +use serde_json::Value; + +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#apnsconfig +pub struct ApnsConfig { + // HTTP request headers defined in Apple Push Notification Service. + #[serde(skip_serializing_if = "Option::is_none")] + headers: Option, + + // APNs payload as a JSON object, including both aps dictionary and custom payload. + #[serde(skip_serializing_if = "Option::is_none")] + payload: Option, + + // Options for features provided by the FCM SDK for iOS. + #[serde(skip_serializing_if = "Option::is_none")] + fcm_options: Option, +} + +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#apnsfcmoptions +pub struct ApnsFcmOptions { + // Label associated with the message's analytics data. + analytics_label: String, + + // Contains the URL of an image that is going to be displayed in a notification. + image: String, +} diff --git a/src/client/mod.rs b/src/client/mod.rs index b82ca8821..788fda83b 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -1,7 +1,7 @@ pub(crate) mod response; use crate::client::response::{ErrorReason, FcmError, FcmResponse, RetryAfter}; -use crate::{Message, MessageInternal}; +use crate::Message; use gauth::serv_account::ServiceAccount; use reqwest::header::RETRY_AFTER; use reqwest::{Body, StatusCode}; @@ -18,17 +18,9 @@ impl Default for Client { } } -// will be used to wrap the message in a "message" field -#[derive(Serialize)] -struct MessageWrapper<'a> { - #[serde(rename = "message")] - message: &'a MessageInternal, -} - -impl MessageWrapper<'_> { - fn new(message: &MessageInternal) -> MessageWrapper { - MessageWrapper { message } - } +#[derive(Serialize, Debug)] +pub struct MessageWrapper { + pub message: Message, } impl Client { @@ -115,8 +107,7 @@ impl Client { } pub async fn send(&self, message: Message) -> Result { - let fin = message.finalize(); - let wrapper = MessageWrapper::new(&fin); + let wrapper = MessageWrapper { message }; let payload = serde_json::to_vec(&wrapper).unwrap(); let project_id = match self.get_project_id() { @@ -140,11 +131,6 @@ impl Client { .body(Body::from(payload)) .build()?; - // print the body - let body = request.body().unwrap(); - let body = std::str::from_utf8(body.as_bytes().unwrap()).unwrap(); - println!("body: {}", body); - let response = self.http_client.execute(request).await?; let response_status = response.status(); diff --git a/src/lib.rs b/src/lib.rs index 58461c143..c44d0a4ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,6 @@ mod message; pub use crate::message::*; - mod notification; pub use crate::notification::*; mod android; diff --git a/src/message/fcm_options.rs b/src/message/fcm_options.rs deleted file mode 100644 index 8aa0cc7dc..000000000 --- a/src/message/fcm_options.rs +++ /dev/null @@ -1,21 +0,0 @@ -use serde::Serialize; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#fcmoptions -pub struct FcmOptionsInternal { - // Label associated with the message's analytics data. - analytics_label: String, -} - -#[derive(Debug)] -pub struct FcmOptions { - pub analytics_label: String, -} - -impl FcmOptions { - pub fn finalize(self) -> FcmOptionsInternal { - FcmOptionsInternal { - analytics_label: self.analytics_label, - } - } -} diff --git a/src/message/mod.rs b/src/message/mod.rs index 9abb1bcaf..988073154 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -1,25 +1,21 @@ -pub mod fcm_options; -pub mod target; -#[cfg(test)] -mod tests; - +use crate::android::AndroidConfig; +use crate::apns::ApnsConfig; +use crate::web::WebpushConfig; +use crate::Notification; use serde::ser::SerializeMap; -use serde::Serialize; -use serde::Serializer; +use serde::{Serialize, Serializer}; use serde_json::Value; -use crate::android::android_config::AndroidConfig; -use crate::android::android_config::AndroidConfigInternal; -use crate::apns::apns_config::ApnsConfig; -use crate::apns::apns_config::ApnsConfigInternal; -use crate::fcm_options::FcmOptions; -use crate::fcm_options::FcmOptionsInternal; -use crate::notification::Notification; -use crate::notification::NotificationInternal; -use crate::web::webpush_config::WebpushConfig; -use crate::web::webpush_config::WebpushConfigInternal; +#[cfg(test)] +mod tests; -use self::target::Target; +#[derive(Clone, Serialize, Debug, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum Target { + Token(String), + Topic(String), + Condition(String), +} fn output_target(target: &Target, s: S) -> Result where @@ -36,36 +32,43 @@ where #[derive(Serialize, Debug)] // https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#resource:-message -pub struct MessageInternal { +pub struct Message { // Arbitrary key/value payload, which must be UTF-8 encoded. #[serde(skip_serializing_if = "Option::is_none")] data: Option, // Basic notification template to use across all platforms. #[serde(skip_serializing_if = "Option::is_none")] - notification: Option, + notification: Option, // Android specific options for messages sent through FCM connection server. #[serde(skip_serializing_if = "Option::is_none")] - android: Option, + android: Option, // Webpush protocol options. #[serde(skip_serializing_if = "Option::is_none")] - webpush: Option, + webpush: Option, // Apple Push Notification Service specific options. #[serde(skip_serializing_if = "Option::is_none")] - apns: Option, + apns: Option, // Template for FCM SDK feature options to use across all platforms. #[serde(skip_serializing_if = "Option::is_none")] - fcm_options: Option, + fcm_options: Option, // Target to send a message to. #[serde(flatten, serialize_with = "output_target")] target: Target, } +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#fcmoptions +pub struct FcmOptions { + // Label associated with the message's analytics data. + analytics_label: String, +} + /// /// A builder to get a `Message` instance. /// @@ -79,26 +82,71 @@ pub struct MessageInternal { /// let message = builder.finalize(); /// ``` #[derive(Debug)] -pub struct Message { - pub data: Option, - pub notification: Option, - pub target: Target, - pub android: Option, - pub webpush: Option, - pub apns: Option, - pub fcm_options: Option, +pub struct MessageBuilder { + data: Option, + notification: Option, + target: Target, } -impl Message { +impl MessageBuilder { + /// Get a new instance of Message. You need to supply to. + pub fn new(target: Target) -> Self { + MessageBuilder { + data: None, + notification: None, + target, + } + } + + /// Use this to add custom key-value pairs to the message. This data + /// must be handled appropriately on the client end. The data can be + /// anything that Serde can serialize to JSON. + /// + /// # Examples: + /// ```rust + /// use fcm::{MessageBuilder, Target}; + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("message", "Howdy!"); + /// + /// let mut builder = MessageBuilder::new(Target::Token("token".to_string())); + /// builder.data(&map).expect("Should have been able to add data"); + /// let message = builder.finalize(); + /// ``` + pub fn data(&mut self, data: &dyn erased_serde::Serialize) -> Result<&mut Self, serde_json::Error> { + self.data = Some(serde_json::to_value(data)?); + Ok(self) + } + + /// Use this to set a `Notification` for the message. + /// # Examples: + /// ```rust + /// use fcm::{MessageBuilder, NotificationBuilder, Target}; + /// + /// let mut builder = NotificationBuilder::new(); + /// builder.title("Hey!".to_string()); + /// builder.body("Do you want to catch up later?".to_string()); + /// let notification = builder.finalize(); + /// + /// let mut builder = MessageBuilder::new(Target::Token("token".to_string())); + /// builder.notification(notification); + /// let message = builder.finalize(); + /// ``` + pub fn notification(&mut self, notification: Notification) -> &mut Self { + self.notification = Some(notification); + self + } + /// Complete the build and get a `Message` instance - pub fn finalize(self) -> MessageInternal { - MessageInternal { + pub fn finalize(self) -> Message { + Message { data: self.data, - notification: self.notification.map(|n| n.finalize()), - android: self.android.map(|a| a.finalize()), - webpush: self.webpush.map(|w| w.finalize()), - apns: self.apns.map(|a| a.finalize()), - fcm_options: self.fcm_options.map(|f| f.finalize()), + notification: self.notification, + android: None, + webpush: None, + apns: None, + fcm_options: None, target: self.target, } } diff --git a/src/message/target.rs b/src/message/target.rs deleted file mode 100644 index b90db8584..000000000 --- a/src/message/target.rs +++ /dev/null @@ -1,9 +0,0 @@ -use serde::Serialize; - -#[derive(Clone, Serialize, Debug, PartialEq)] -#[serde(rename_all = "lowercase")] -pub enum Target { - Token(String), - Topic(String), - Condition(String), -} diff --git a/src/message/tests.rs b/src/message/tests.rs index 0773b3433..c23e94e45 100644 --- a/src/message/tests.rs +++ b/src/message/tests.rs @@ -1,19 +1,18 @@ -use crate::{notification::Notification, target::Target, Message}; +use crate::notification::NotificationBuilder; +use crate::{MessageBuilder, Target}; +use serde::Serialize; use serde_json::json; +#[derive(Serialize)] +struct CustomData { + foo: &'static str, + bar: bool, +} + #[test] fn should_create_new_message() { let target = Target::Token("token".to_string()); - let msg = Message { - target: target.clone(), - data: None, - notification: None, - android: None, - webpush: None, - apns: None, - fcm_options: None, - } - .finalize(); + let msg = MessageBuilder::new(target.clone()).finalize(); assert_eq!(msg.target, target); } @@ -21,16 +20,7 @@ fn should_create_new_message() { #[test] fn should_leave_nones_out_of_the_json() { let target = Target::Token("token".to_string()); - let msg = Message { - target: target.clone(), - data: None, - notification: None, - android: None, - webpush: None, - apns: None, - fcm_options: None, - } - .finalize(); + let msg = MessageBuilder::new(target).finalize(); let payload = serde_json::to_string(&msg).unwrap(); let expected_payload = json!({ @@ -44,17 +34,11 @@ fn should_leave_nones_out_of_the_json() { #[test] fn should_add_custom_data_to_the_payload() { let target = Target::Token("token".to_string()); - let data = json!({ "foo": "bar", "bar": false }); - - let builder = Message { - target: target, - data: Some(data), - notification: None, - android: None, - webpush: None, - apns: None, - fcm_options: None, - }; + let mut builder = MessageBuilder::new(target); + + let data = CustomData { foo: "bar", bar: false }; + + builder.data(&data).unwrap(); let msg = builder.finalize(); let payload = serde_json::to_string(&msg).unwrap(); @@ -74,20 +58,9 @@ fn should_add_custom_data_to_the_payload() { #[test] fn should_be_able_to_render_a_full_token_message_to_json() { let target = Target::Token("token".to_string()); - let notification = Notification { - title: None, - body: None, - image: None, - }; - let builder = Message { - target: target.clone(), - data: None, - notification: Some(notification), - android: None, - webpush: None, - apns: None, - fcm_options: None, - }; + let mut builder = MessageBuilder::new(target); + + builder.notification(NotificationBuilder::new().finalize()); let payload = serde_json::to_string(&builder.finalize()).unwrap(); @@ -103,20 +76,9 @@ fn should_be_able_to_render_a_full_token_message_to_json() { #[test] fn should_be_able_to_render_a_full_topic_message_to_json() { let target = Target::Topic("my_topic".to_string()); - let notification = Notification { - title: None, - body: None, - image: None, - }; - let builder = Message { - target: target.clone(), - data: None, - notification: Some(notification), - android: None, - webpush: None, - apns: None, - fcm_options: None, - }; + let mut builder = MessageBuilder::new(target); + + builder.notification(NotificationBuilder::new().finalize()); let payload = serde_json::to_string(&builder.finalize()).unwrap(); @@ -132,20 +94,9 @@ fn should_be_able_to_render_a_full_topic_message_to_json() { #[test] fn should_be_able_to_render_a_full_condition_message_to_json() { let target = Target::Condition("my_condition".to_string()); - let notification = Notification { - title: None, - body: None, - image: None, - }; - let builder = Message { - target: target.clone(), - data: None, - notification: Some(notification), - android: None, - webpush: None, - apns: None, - fcm_options: None, - }; + let mut builder = MessageBuilder::new(target); + + builder.notification(NotificationBuilder::new().finalize()); let payload = serde_json::to_string(&builder.finalize()).unwrap(); @@ -161,34 +112,15 @@ fn should_be_able_to_render_a_full_condition_message_to_json() { #[test] fn should_set_notifications() { let target = Target::Token("token".to_string()); - let msg = Message { - target: target.clone(), - data: None, - notification: None, - android: None, - webpush: None, - apns: None, - fcm_options: None, - }; - - assert_eq!(msg.notification.is_none(), true); - - let nm = Notification { - title: None, - body: None, - image: None, - }; - - let builder = Message { - target: target.clone(), - data: None, - notification: Some(nm), - android: None, - webpush: None, - apns: None, - fcm_options: None, - }; + let msg = MessageBuilder::new(target.clone()).finalize(); + + assert_eq!(msg.notification, None); + + let nm = NotificationBuilder::new().finalize(); + + let mut builder = MessageBuilder::new(target); + builder.notification(nm); let msg = builder.finalize(); - assert_eq!(msg.notification.is_none(), false); + assert_ne!(msg.notification, None); } diff --git a/src/notification/mod.rs b/src/notification/mod.rs index 7be580c22..0ca5606a0 100644 --- a/src/notification/mod.rs +++ b/src/notification/mod.rs @@ -1,14 +1,14 @@ +use serde::Serialize; + #[cfg(test)] mod tests; -use serde::Serialize; - /// This struct represents a FCM notification. Use the /// corresponding `NotificationBuilder` to get an instance. You can then use /// this notification instance when sending a FCM message. #[derive(Serialize, Debug, PartialEq)] // https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#notification -pub struct NotificationInternal { +pub struct Notification { // The notification's title. #[serde(skip_serializing_if = "Option::is_none")] title: Option, @@ -34,17 +34,40 @@ pub struct NotificationInternal { /// builder.body("3 runs to win in 1 ball".to_string()); /// let notification = builder.finalize(); /// ``` -#[derive(Debug)] -pub struct Notification { - pub title: Option, - pub body: Option, - pub image: Option, +#[derive(Default)] +pub struct NotificationBuilder { + title: Option, + body: Option, + image: Option, } -impl Notification { +impl NotificationBuilder { + /// Get a new `NotificationBuilder` instance, with a title. + pub fn new() -> NotificationBuilder { + Self::default() + } + + // Set the title of the notification + pub fn title(&mut self, title: String) -> &mut Self { + self.title = Some(title); + self + } + + /// Set the body of the notification + pub fn body(&mut self, body: String) -> &mut Self { + self.body = Some(body); + self + } + + /// Set the image + pub fn image(&mut self, image: String) -> &mut Self { + self.image = Some(image); + self + } + /// Complete the build and get a `Notification` instance - pub fn finalize(self) -> NotificationInternal { - NotificationInternal { + pub fn finalize(self) -> Notification { + Notification { title: self.title, body: self.body, image: self.image, diff --git a/src/notification/tests.rs b/src/notification/tests.rs index 3bf593d87..36315ec1a 100644 --- a/src/notification/tests.rs +++ b/src/notification/tests.rs @@ -1,15 +1,16 @@ -use crate::Notification; +use crate::NotificationBuilder; use serde_json::json; #[test] fn should_be_able_to_render_a_full_notification_to_json() { - let not = Notification { - title: Some("foo".to_string()), - body: Some("bar".to_string()), - image: Some("https://my.image.com/test.jpg".to_string()), - }; + let mut builder = NotificationBuilder::new(); - let payload = serde_json::to_string(¬.finalize()).unwrap(); + builder + .title("foo".to_string()) + .body("bar".to_string()) + .image("https://my.image.com/test.jpg".to_string()); + + let payload = serde_json::to_string(&builder.finalize()).unwrap(); let expected_payload = json!({ "title": "foo", @@ -20,3 +21,38 @@ fn should_be_able_to_render_a_full_notification_to_json() { assert_eq!(expected_payload, payload); } + +#[test] +fn should_set_notification_title() { + let nm = NotificationBuilder::new().finalize(); + + assert_eq!(nm.title, None); + + let mut builder = NotificationBuilder::new(); + builder.title("title".to_string()); + let nm = builder.finalize(); + + assert_eq!(nm.title, Some("title".to_string())); +} + +#[test] +fn should_set_notification_body() { + let nm = NotificationBuilder::new().finalize(); + + assert_eq!(nm.body, None); + + let mut builder = NotificationBuilder::new(); + builder.body("body".to_string()); + let nm = builder.finalize(); + + assert_eq!(nm.body, Some("body".to_string())); +} + +#[test] +fn should_set_notification_image() { + let mut builder = NotificationBuilder::new(); + builder.image("https://my.image.com/test.jpg".to_string()); + let nm = builder.finalize(); + + assert_eq!(nm.image, Some("https://my.image.com/test.jpg".to_string())); +} diff --git a/src/web/mod.rs b/src/web/mod.rs index 52e1762c8..60d42990d 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -1,2 +1,33 @@ -pub mod webpush_config; -pub mod webpush_fcm_options; +use serde::Serialize; +use serde_json::Value; + +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#webpushconfig +pub struct WebpushConfig { + // HTTP headers defined in webpush protocol. + #[serde(skip_serializing_if = "Option::is_none")] + headers: Option, + + // Arbitrary key/value payload. + #[serde(skip_serializing_if = "Option::is_none")] + data: Option, + + // Web Notification options as a JSON object. + // Struct format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Struct + #[serde(skip_serializing_if = "Option::is_none")] + notification: Option, + + // Options for features provided by the FCM SDK for Web. + #[serde(skip_serializing_if = "Option::is_none")] + fcm_options: Option, +} + +#[derive(Serialize, Debug)] +// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#webpushfcmoptions +pub struct WebpushFcmOptions { + // The link to open when the user clicks on the notification. + link: String, + + // Label associated with the message's analytics data. + analytics_label: String, +} diff --git a/src/web/webpush_config.rs b/src/web/webpush_config.rs deleted file mode 100644 index e78bfd345..000000000 --- a/src/web/webpush_config.rs +++ /dev/null @@ -1,44 +0,0 @@ -use serde::Serialize; -use serde_json::Value; - -use super::webpush_fcm_options::{WebpushFcmOptions, WebpushFcmOptionsInternal}; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#webpushconfig -pub struct WebpushConfigInternal { - // HTTP headers defined in webpush protocol. - #[serde(skip_serializing_if = "Option::is_none")] - headers: Option, - - // Arbitrary key/value payload. - #[serde(skip_serializing_if = "Option::is_none")] - data: Option, - - // Web Notification options as a JSON object. - // Struct format: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?authuser=0#google.protobuf.Struct - #[serde(skip_serializing_if = "Option::is_none")] - notification: Option, - - // Options for features provided by the FCM SDK for Web. - #[serde(skip_serializing_if = "Option::is_none")] - fcm_options: Option, -} - -#[derive(Debug)] -pub struct WebpushConfig { - pub headers: Option, - pub data: Option, - pub notification: Option, - pub fcm_options: Option, -} - -impl WebpushConfig { - pub fn finalize(self) -> WebpushConfigInternal { - WebpushConfigInternal { - headers: self.headers, - data: self.data, - notification: self.notification, - fcm_options: self.fcm_options.map(|fcm_options| fcm_options.finalize()), - } - } -} diff --git a/src/web/webpush_fcm_options.rs b/src/web/webpush_fcm_options.rs deleted file mode 100644 index 45b78c673..000000000 --- a/src/web/webpush_fcm_options.rs +++ /dev/null @@ -1,30 +0,0 @@ -use serde::Serialize; - -#[derive(Serialize, Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#webpushfcmoptions -pub struct WebpushFcmOptionsInternal { - // The link to open when the user clicks on the notification. - link: String, - - // Label associated with the message's analytics data. - analytics_label: String, -} - -#[derive(Debug)] -// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?authuser=0#webpushfcmoptions -pub struct WebpushFcmOptions { - // The link to open when the user clicks on the notification. - pub link: String, - - // Label associated with the message's analytics data. - pub analytics_label: String, -} - -impl WebpushFcmOptions { - pub fn finalize(self) -> WebpushFcmOptionsInternal { - WebpushFcmOptionsInternal { - link: self.link, - analytics_label: self.analytics_label, - } - } -}