firebae_cm/message/
message.rs

1use crate::MessageBody;
2
3/// A representation of a complete message that can be sent. It requires your project_id and an authentication JWT token (see <https://cloud.google.com/docs/authentication/>).
4/// For automatic handling of the JWT authentication, see the `oauth` feature and the `Message::with_oauth` function.
5#[derive(serde::Serialize, Debug)]
6pub struct Message {
7    #[serde(skip_serializing)]
8    pub(crate) project_id: String,
9    #[serde(skip_serializing)]
10    pub(crate) jwt: String,
11    pub(crate) message: MessageBody,
12}
13
14impl Message {
15    /// Create a new Message.
16    pub fn new(project_id: impl Into<String>, jwt: impl Into<String>, body: MessageBody) -> Self {
17        Self {
18            project_id: project_id.into(),
19            jwt: jwt.into(),
20            message: body,
21        }
22    }
23}
24
25#[cfg(all(feature = "oauth", not(all(loom, test))))]
26mod oauth {
27    use gcp_auth::AuthenticationManager;
28    pub use gcp_auth::Error;
29    use tokio::sync::OnceCell;
30
31    use super::{Message, MessageBody};
32
33    static AUTH_MANAGER: OnceCell<AuthenticationManager> = OnceCell::const_new();
34
35    async fn authentication_manager() -> &'static AuthenticationManager {
36        AUTH_MANAGER
37            .get_or_init(|| async {
38                AuthenticationManager::new()
39                    .await
40                    .expect("unable to initialize authentication manager")
41            })
42            .await
43    }
44
45    impl Message {
46        #[cfg_attr(docsrs, doc(cfg(feature = "oauth")))]
47        /// Create a new Message and automatically handle (oauth) authentication. Requires the `oauth` feature.
48        /// To use this, make sure to set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable with the path to the `credentials.json` file.
49        /// Check the GCP documentation to obtain such file: <https://cloud.google.com/docs/authentication/provide-credentials-adc>.
50        pub async fn with_oauth(
51            project_id: impl Into<String>,
52            body: MessageBody,
53        ) -> Result<Self, Error> {
54            let scopes = &["https://www.googleapis.com/auth/cloud-platform"];
55            let full_token = authentication_manager().await.get_token(scopes).await?;
56            let token = full_token.as_str().trim_end_matches('.');
57
58            Ok(Self::new(project_id, token, body))
59        }
60    }
61}