sms_receiver/
sms_receiver.rs

1use crate::kdeconnect_client::{Connection, Daemon, MessageType};
2use crate::Message;
3use dbus::channel::Token;
4use std::sync::mpsc;
5use std::sync::mpsc::{Receiver, Sender, TryRecvError};
6use std::time::Duration;
7
8pub struct SMSReceiver {
9    rx: Receiver<Message>,
10    kde_connection: Connection,
11    _tokens: Vec<Token>,
12}
13
14impl SMSReceiver {
15    pub fn connect() -> Result<Self, Box<dyn std::error::Error>> {
16        let kde_connection = Connection::new()?;
17        let kde_daemon = Daemon::new(&kde_connection);
18        let devices = kde_daemon.get_devices(true, true)?;
19
20        let (tx, rx): (Sender<Message>, Receiver<Message>) = mpsc::channel();
21        let mut tokens = Vec::new();
22        for device in devices {
23            if device.has_plugin("kdeconnect_sms")? {
24                let sms_plugin = device.get_sms_plugin();
25                let device_name = device.get_name()?;
26
27                let tx_clone = tx.clone();
28                let device_name_clone = device_name.clone();
29                tokens.push(sms_plugin.on_conversation_created(move |sms| {
30                    if let MessageType::Inbox = sms.msg_type {
31                        if !sms.sender.is_empty() && !sms.body.is_empty() {
32                            tx_clone
33                                .send(Message {
34                                    sender: sms.sender,
35                                    body: sms.body,
36                                    date: sms.date,
37                                    thread_id: sms.thread_id,
38                                    unique_id: sms.unique_id,
39                                    device_name: device_name_clone.clone(),
40                                    sim_id: sms.sim_id,
41                                })
42                                .unwrap();
43                        }
44                    }
45                })?);
46
47                let tx_clone = tx.clone();
48                let device_name_clone = device_name.clone();
49                tokens.push(sms_plugin.on_conversation_updated(move |sms| {
50                    if let MessageType::Inbox = sms.msg_type {
51                        if !sms.sender.is_empty() && !sms.body.is_empty() {
52                            tx_clone
53                                .send(Message {
54                                    sender: sms.sender,
55                                    body: sms.body,
56                                    date: sms.date,
57                                    thread_id: sms.thread_id,
58                                    unique_id: sms.unique_id,
59                                    device_name: device_name_clone.clone(),
60                                    sim_id: sms.sim_id,
61                                })
62                                .unwrap();
63                        }
64                    }
65                })?);
66            }
67        }
68
69        Ok(Self {
70            rx,
71            kde_connection,
72            _tokens: tokens,
73        })
74    }
75
76    pub fn check_for_message(&self) -> Result<Option<Message>, Box<dyn std::error::Error>> {
77        self.kde_connection.process(Duration::from_millis(100))?;
78
79        match self.rx.try_recv() {
80            Ok(msg) => Ok(Some(msg)),
81            Err(TryRecvError::Empty) => Ok(None),
82            Err(TryRecvError::Disconnected) => Err(Box::new(TryRecvError::Disconnected).into()),
83        }
84    }
85}