1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Crypto-bank telegram bot balances command.

use std::time::Duration;

use telegram_client::Message;

use cxmr_broker::{get_all_balances, SharedBroker};

use crate::{ChatClient, Error};

/// Telegram balances configuration.
#[derive(Clone, Deserialize, Serialize)]
pub struct BalancesConfig {
    pub start_minutes: u64,
    pub interval_minutes: u64,
}

impl BalancesConfig {
    pub fn start(&self) -> Duration {
        Duration::from_secs(self.start_minutes * 60)
    }

    pub fn interval(&self) -> Duration {
        Duration::from_secs(self.interval_minutes * 60)
    }
}

/// Starts balances notifications.
pub async fn balances_notify(
    chat: ChatClient,
    broker: SharedBroker,
    cfg: BalancesConfig,
) -> Result<(), Error> {
    let mut interval = tokio::time::interval(cfg.interval());
    loop {
        let _tick = interval.tick().await;
        let message = balances_msg(&broker).await?;
        if let Err(e) = chat.notify_owner(message).await {
            error!("Error sending balance notification: {:?}", e);
        }
    }
}

/// Balances command.
pub async fn balances(
    chat: &ChatClient,
    msg: &Message,
    broker: &SharedBroker,
) -> Result<Message, Error> {
    let message = balances_msg(broker).await?;
    chat.send(&msg.chat, message).await
}

/// Starts balances notifications.
pub async fn balances_msg(broker: &SharedBroker) -> Result<String, Error> {
    let broker = broker.read().await;
    Ok(get_all_balances(&broker)
        .into_iter()
        .map(|bnc| format!("**{}** balance: {:.4}", bnc.name, bnc.total))
        .collect::<Vec<String>>()
        .join("\n"))
}