Skip to content

Commit

Permalink
feat: build new api
Browse files Browse the repository at this point in the history
  • Loading branch information
adnanjpg committed Jan 22, 2024
1 parent a8babd2 commit 069246e
Show file tree
Hide file tree
Showing 25 changed files with 838 additions and 498 deletions.
1 change: 1 addition & 0 deletions a.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cargo run --example simple_sender -- -t fP0EXs_HQ4Gj1sE5xBP6LP:APA91bGxDOk4GzvIvvGFPa6kDWOOHm2zYA3tUN1jYwErSBq_s27NioYjYWfUpgUW3_LIsreSw1pbtTjEpCK_cKR6AHxo1PGZ1Yd3S8lyX148I_LgKaTNYorG2QtkcwfB9Nm5yKGJwLaG
37 changes: 25 additions & 12 deletions examples/simple_sender.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use argparse::{ArgumentParser, Store};
use fcm::{Client, MessageBuilder, Target};
use serde::Serialize;
// cargo run --example simple_sender -- -t <device_token>

#[derive(Serialize)]
struct CustomData {
message: &'static str,
}
use argparse::{ArgumentParser, Store};
use fcm::{fcm_options::FcmOptions, target::Target, Client, Message, Notification};
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
Expand All @@ -22,12 +19,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
}

let client = Client::new();
let data = CustomData { message: "howdy" };

let mut builder = MessageBuilder::new(Target::Token(device_token));
builder.data(&data)?;

let response = client.send(builder.finalize()).await?;
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?;
println!("Sent: {:?}", response);

Ok(())
Expand Down
73 changes: 73 additions & 0 deletions src/android/android_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
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<String>,

// Message priority.
#[serde(skip_serializing_if = "Option::is_none")]
priority: Option<AndroidMessagePriority>,

// 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<String>,

// 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<String>,

// Arbitrary key/value payload.
#[serde(skip_serializing_if = "Option::is_none")]
data: Option<Value>,

// Notification to send to android devices.
#[serde(skip_serializing_if = "Option::is_none")]
notification: Option<AndroidNotificationInternal>,

// Options for features provided by the FCM SDK for Android.
#[serde(skip_serializing_if = "Option::is_none")]
fcm_options: Option<AndroidFcmOptionsInternal>,

// 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<bool>,
}

#[derive(Debug)]
pub struct AndroidConfig {
pub collapse_key: Option<String>,
pub priority: Option<AndroidMessagePriority>,
pub ttl: Option<String>,
pub restricted_package_name: Option<String>,
pub data: Option<Value>,
pub notification: Option<AndroidNotification>,
pub fcm_options: Option<AndroidFcmOptions>,
pub direct_boot_ok: Option<bool>,
}

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,
}
}
}
21 changes: 21 additions & 0 deletions src/android/android_fcm_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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,
}
}
}
10 changes: 10 additions & 0 deletions src/android/android_message_priority.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
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,
}
234 changes: 234 additions & 0 deletions src/android/android_notification.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
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<String>,

// The notification's body text.
#[serde(skip_serializing_if = "Option::is_none")]
body: Option<String>,

// The notification's icon.
#[serde(skip_serializing_if = "Option::is_none")]
icon: Option<String>,

// The notification's icon color, expressed in #rrggbb format.
#[serde(skip_serializing_if = "Option::is_none")]
color: Option<String>,

// The sound to play when the device receives the notification.
#[serde(skip_serializing_if = "Option::is_none")]
sound: Option<String>,

// Identifier used to replace existing notifications in the notification drawer.
#[serde(skip_serializing_if = "Option::is_none")]
tag: Option<String>,

// The action associated with a user click on the notification.
#[serde(skip_serializing_if = "Option::is_none")]
click_action: Option<String>,

// 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<String>,

// 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<Vec<String>>,

// 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<String>,

// 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<Vec<String>>,

// The notification's channel id (new in Android O).
#[serde(skip_serializing_if = "Option::is_none")]
channel_id: Option<String>,

// Sets the "ticker" text, which is sent to accessibility services.
#[serde(skip_serializing_if = "Option::is_none")]
ticker: Option<String>,

// 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<bool>,

// 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<String>,

// Set whether or not this notification is relevant only to the current device.
#[serde(skip_serializing_if = "Option::is_none")]
local_only: Option<bool>,

// Set the relative priority for this notification.
#[serde(skip_serializing_if = "Option::is_none")]
notification_priority: Option<NotificationPriority>,

// If set to true, use the Android framework's default sound for the notification.
#[serde(skip_serializing_if = "Option::is_none")]
default_sound: Option<bool>,

// 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<bool>,

// 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<bool>,

// 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<Vec<String>>,

// Set the Notification.visibility of the notification.
#[serde(skip_serializing_if = "Option::is_none")]
visibility: Option<Visibility>,

// Sets the number of items this notification represents.
#[serde(skip_serializing_if = "Option::is_none")]
notification_count: Option<i32>,

// 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<LightSettingsInternal>,

// Contains the URL of an image that is going to be displayed in a notification.
#[serde(skip_serializing_if = "Option::is_none")]
image: Option<String>,
}

#[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<String>,

// The notification's body text.
pub body: Option<String>,

// The notification's icon.
pub icon: Option<String>,

// The notification's icon color, expressed in #rrggbb format.
pub color: Option<String>,

// The sound to play when the device receives the notification.
pub sound: Option<String>,

// Identifier used to replace existing notifications in the notification drawer.
pub tag: Option<String>,

// The action associated with a user click on the notification.
pub click_action: Option<String>,

// 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<String>,

// 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<Vec<String>>,

// 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<String>,

// 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<Vec<String>>,

// The notification's channel id (new in Android O).
pub channel_id: Option<String>,

// Sets the "ticker" text, which is sent to accessibility services.
pub ticker: Option<String>,

// When set to false or unset, the notification is automatically dismissed when the user clicks it in the panel.
pub sticky: Option<bool>,

// 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<String>,

// Set whether or not this notification is relevant only to the current device.
pub local_only: Option<bool>,

// Set the relative priority for this notification.
pub notification_priority: Option<NotificationPriority>,

// If set to true, use the Android framework's default sound for the notification.
pub default_sound: Option<bool>,

// If set to true, use the Android framework's default vibrate pattern for the notification.
pub default_vibrate_timings: Option<bool>,

// If set to true, use the Android framework's default LED light settings for the notification.
pub default_light_settings: Option<bool>,

// 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<Vec<String>>,

// Set the Notification.visibility of the notification.
pub visibility: Option<Visibility>,

// Sets the number of items this notification represents.
pub notification_count: Option<i32>,

// Settings to control the notification's LED blinking rate and color if LED is available on the device.
pub light_settings: Option<LightSettings>,

// Contains the URL of an image that is going to be displayed in a notification.
pub image: Option<String>,
}

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,
}
}
}
Loading

0 comments on commit 069246e

Please sign in to comment.