whatsapp_rust/handlers/
notification.rs1use super::traits::StanzaHandler;
2use crate::client::Client;
3use crate::types::events::Event;
4use async_trait::async_trait;
5use log::{info, warn};
6use std::sync::Arc;
7use wacore_binary::{jid::SERVER_JID, node::Node};
8
9#[derive(Default)]
16pub struct NotificationHandler;
17
18impl NotificationHandler {
19 pub fn new() -> Self {
20 Self
21 }
22}
23
24#[async_trait]
25impl StanzaHandler for NotificationHandler {
26 fn tag(&self) -> &'static str {
27 "notification"
28 }
29
30 async fn handle(&self, client: Arc<Client>, node: &Node, _cancelled: &mut bool) -> bool {
31 handle_notification_impl(&client, node).await;
32 true
33 }
34}
35
36async fn handle_notification_impl(client: &Arc<Client>, node: &Node) {
37 let notification_type = node.attrs.get("type").cloned().unwrap_or_default();
38
39 match notification_type.as_str() {
40 "encrypt" => {
41 if let Some(from) = node.attrs.get("from")
42 && from == SERVER_JID
43 {
44 let client_clone = client.clone();
45 tokio::spawn(async move {
46 if let Err(e) = client_clone.upload_pre_keys().await {
47 warn!("Failed to upload pre-keys after notification: {:?}", e);
48 }
49 });
50 }
51 }
52 "server_sync" => {
53 info!(target: "Client", "Received `server_sync` notification, scheduling app state sync(s).");
54 for collection_node in node.get_children_by_tag("collection") {
55 let name = collection_node
56 .attrs
57 .get("name")
58 .cloned()
59 .unwrap_or_default();
60 let version = collection_node
61 .attrs
62 .get("version")
63 .and_then(|v| v.parse::<u64>().ok())
64 .unwrap_or(0);
65 info!(
66 target: "Client/AppState",
67 "scheduling sync for collection '{name}' from version {version}."
68 );
69 }
70 }
71 "account_sync" => {
72 if let Some(push_name_attr) = node.attrs.get("pushname") {
73 let new_push_name = push_name_attr.clone();
74 client
75 .clone()
76 .update_push_name_and_notify(new_push_name)
77 .await;
78 } else {
79 warn!(target: "Client", "TODO: Implement full handler for <notification type='account_sync'>, for now dispatching generic event.");
80 client
81 .core
82 .event_bus
83 .dispatch(&Event::Notification(node.clone()));
84 }
85 }
86 _ => {
87 warn!(target: "Client", "TODO: Implement handler for <notification type='{notification_type}'>");
88 client
89 .core
90 .event_bus
91 .dispatch(&Event::Notification(node.clone()));
92 }
93 }
94}