Skip to content

Commit

Permalink
fix: push payloads (#326)
Browse files Browse the repository at this point in the history
  • Loading branch information
chris13524 committed May 15, 2024
1 parent c31b519 commit 1abce43
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 117 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

181 changes: 65 additions & 116 deletions src/providers/fcm_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ use {
crate::{blob::DecryptedPayloadBlob, error::Error, providers::PushProvider},
async_trait::async_trait,
fcm_v1::{
gauth::serv_account::ServiceAccountKey, AndroidConfig, AndroidMessagePriority,
AndroidNotification, Client, ClientBuildError, ErrorReason, Message, Notification,
Response, Target, WebpushConfig,
gauth::serv_account::ServiceAccountKey, AndroidConfig, AndroidMessagePriority, ApnsConfig,
Client, ClientBuildError, ErrorReason, Message, Notification, Response, Target,
},
serde::Serialize,
serde_json::json,
std::sync::Arc,
tracing::{debug, instrument},
};

Expand Down Expand Up @@ -36,134 +38,81 @@ impl PushProvider for FcmV1Provider {
token: String,
body: PushMessage,
) -> crate::error::Result<()> {
fn make_message(
token: String,
notification: Option<Notification>,
data: serde_json::Value,
) -> Message {
Message {
data: Some(data),
notification,
target: Target::Token(token),
android: Some(AndroidConfig {
priority: Some(AndroidMessagePriority::High),
..Default::default()
}),
webpush: None,
apns: Some(ApnsConfig {
payload: Some(json!({
"aps": {
"content-available": 1,
}
})),
..Default::default()
}),
fcm_options: None,
}
}

let result = match body {
PushMessage::RawPushMessage(message) => {
// Sending `always_raw` encrypted message
debug!("Sending raw encrypted message");
let message = Message {
data: Some(
serde_json::to_value(message).map_err(Error::InternalSerializationError)?,
),
notification: None,
target: Target::Token(token),
android: Some(AndroidConfig {
priority: Some(AndroidMessagePriority::High),
collapse_key: None,
ttl: None,
restricted_package_name: None,
data: None,
notification: None,
fcm_options: None,
direct_boot_ok: None,
}),
// TODO
webpush: Some(WebpushConfig {
headers: None,
data: None,
notification: None,
fcm_options: None,
}),
// TODO do we need to set this for iOS React Native? We are missing content_available equivalent
apns: None,
fcm_options: None,
};
#[derive(Serialize)]
pub struct FcmV1RawPushMessage {
pub topic: Arc<str>,
pub tag: String,
pub message: Arc<str>,
}
let data = serde_json::to_value(FcmV1RawPushMessage {
// All keys must be strings
topic: message.topic,
tag: message.tag.to_string(),
message: message.message,
})
.map_err(Error::InternalSerializationError)?;
let message = make_message(token, None, data);
self.client.send(message).await
}
PushMessage::LegacyPushMessage(LegacyPushMessage { id: _, payload }) => {
#[derive(Serialize)]
pub struct FcmV1MessagePayload {
pub topic: Arc<str>,
pub flags: String,
pub blob: Arc<str>,
}
let data = serde_json::to_value(FcmV1MessagePayload {
// All keys must be strings
topic: payload.topic.clone(),
flags: payload.flags.to_string(),
blob: payload.blob.clone(),
})
.map_err(Error::InternalSerializationError)?;

if payload.is_encrypted() {
debug!("Sending legacy `is_encrypted` message");
let message = Message {
data: Some(
serde_json::to_value(payload)
.map_err(Error::InternalSerializationError)?,
),
notification: None,
target: Target::Token(token),
android: Some(AndroidConfig {
priority: Some(AndroidMessagePriority::High),
collapse_key: None,
ttl: None,
restricted_package_name: None,
data: None,
notification: None,
fcm_options: None,
direct_boot_ok: None,
}),
// TODO
webpush: Some(WebpushConfig {
headers: None,
data: None,
notification: None,
fcm_options: None,
}),
// TODO do we need to set this for iOS React Native? We are missing content_available equivalent
apns: None,
fcm_options: None,
};
let message = make_message(token, None, data);
self.client.send(message).await
} else {
debug!("Sending plain message");
let blob = DecryptedPayloadBlob::from_base64_encoded(&payload.blob)?;

let message = Message {
data: Some(
serde_json::to_value(payload.to_owned())
.map_err(Error::InternalSerializationError)?,
),
notification: Some(Notification {
title: Some(blob.title.clone()),
body: Some(blob.body.clone()),
image: None,
}),
target: Target::Token(token),
android: Some(AndroidConfig {
priority: Some(AndroidMessagePriority::High),
collapse_key: None,
ttl: None,
restricted_package_name: None,
data: None,
notification: Some(AndroidNotification {
notification_priority: None,
// TODO do we need to override this of already set in `notification` above?
title: Some(blob.title),
body: Some(blob.body),
icon: None,
color: None,
sound: None,
tag: None,
click_action: None,
body_loc_key: None,
body_loc_args: None,
title_loc_key: None,
title_loc_args: None,
channel_id: None,
ticker: None,
sticky: None,
event_time: None,
local_only: None,
default_sound: None,
default_vibrate_timings: None,
default_light_settings: None,
vibrate_timings: None,
visibility: None,
notification_count: None,
light_settings: None,
image: None,
}),
fcm_options: None,
direct_boot_ok: None,
}),
// TODO
webpush: Some(WebpushConfig {
headers: None,
data: None,
notification: None,
fcm_options: None,
}),
// TODO do we need to set this for iOS React Native? We are missing content_available equivalent
apns: None,
fcm_options: None,
let notification = Notification {
title: Some(blob.title),
body: Some(blob.body),
..Default::default()
};
let message = make_message(token, Some(notification), data);
self.client.send(message).await
}
}
Expand Down

0 comments on commit 1abce43

Please sign in to comment.