diff --git a/services/tunnelbroker/rust-notifications/src/fcm.rs b/services/tunnelbroker/rust-notifications/src/fcm.rs --- a/services/tunnelbroker/rust-notifications/src/fcm.rs +++ b/services/tunnelbroker/rust-notifications/src/fcm.rs @@ -1,24 +1,50 @@ +use crate::ffi::fcm_status; use anyhow::{anyhow, Result}; -use fcm::{Client, MessageBuilder, NotificationBuilder}; +use fcm::{ + response::ErrorReason::{InvalidRegistration, NotRegistered}, + Client, MessageBuilder, NotificationBuilder, +}; pub async fn send_by_fcm_client( fcm_api_key: &str, device_registration_id: &str, message_title: &str, message_body: &str, -) -> Result { +) -> Result { let client = Client::new(); let mut notification_builder = NotificationBuilder::new(); notification_builder.title(message_title); notification_builder.body(message_body); - let notification = notification_builder.finalize(); + let mut message_builder = MessageBuilder::new(fcm_api_key, device_registration_id); message_builder.notification(notification); + let result = client.send(message_builder.finalize()).await?; - match result.message_id { - Some(message_id) => Ok(message_id), - None => Err(anyhow!("FCM client returned an empty message id")), + match result.results { + Some(results) => { + if results.len() == 0 { + return Err(anyhow!("FCM client returned zero size results")); + } + for result in results { + if let Some(result_error) = result.error { + match result_error { + // We are returning `Ok` with the error types here to distinguish the exact + // error type in a C++ side + InvalidRegistration => return Ok(fcm_status::InvalidRegistration), + NotRegistered => return Ok(fcm_status::NotRegistered), + _ => { + return Err(anyhow!( + "Notification was not accepted by FCM, reason: {:?}", + result_error + )) + } + } + } + } + } + None => return Err(anyhow!("FCM client has no results set")), } + Ok(fcm_status::Ok) } diff --git a/services/tunnelbroker/rust-notifications/src/lib.rs b/services/tunnelbroker/rust-notifications/src/lib.rs --- a/services/tunnelbroker/rust-notifications/src/lib.rs +++ b/services/tunnelbroker/rust-notifications/src/lib.rs @@ -1,3 +1,4 @@ +use crate::ffi::fcm_status; use anyhow::Result; use lazy_static::lazy_static; use tokio::runtime::Runtime; @@ -6,6 +7,12 @@ #[cxx::bridge] mod ffi { + #[cxx_name = "fcmReturnStatus"] + enum fcm_status { + Ok, + InvalidRegistration, + NotRegistered, + } extern "Rust" { #[cxx_name = "sendNotifToAPNS"] fn send_notif_to_apns( @@ -22,7 +29,7 @@ device_registration_id: &str, message_title: &str, message_body: &str, - ) -> Result; + ) -> Result; } } @@ -52,7 +59,7 @@ device_registration_id: &str, message_title: &str, message_body: &str, -) -> Result { +) -> Result { RUNTIME.block_on(fcm::send_by_fcm_client( fcm_api_key, device_registration_id,