Skip to main content

quick_start/
quick_start.rs

1use mxlink::helpers::encryption::EncryptionKey;
2use mxlink::{
3    InitConfig, LoginConfig, LoginCredentials, LoginEncryption, MatrixLink, PersistenceConfig,
4};
5use mxlink::{InvitationDecision, MessageResponseType};
6
7// You can run this example either by modifying the configuration below,
8// or against the Synapse server provided by baibot (https://github.com/etkecc/baibot/) - see its docs/development.md guide.
9
10const HOMESERVER_URL: &str = "http://synapse.127.0.0.1.nip.io:42020";
11
12const LOGIN_USERNAME: &str = "baibot";
13const LOGIN_PASSWORD: &str = "baibot";
14const LOGIN_ENCRYPTION_RECOVERY_PASSPHRASE: &str = "long-and-secure-passphrase-here";
15const LOGIN_ENCRYPTION_RESET_ALLOWED: bool = false;
16
17const DEVICE_DISPLAY_NAME: &str = LOGIN_USERNAME;
18
19const PERSISTENCE_SESSION_FILE_PATH: &str = "/tmp/mxlink-session.json";
20const PERSISTENCE_SESSION_ENCRYPTION_KEY: &str =
21    "ef4d037845e5591c6627122112b7f30b2154e7354f928ff75e4dda206ba84338";
22const PERSISTENCE_DB_DIR_PATH: &str = "/tmp/mxlink-db";
23
24#[tokio::main]
25async fn main() {
26    let matrix_link = create_matrix_link().await;
27
28    // matrix_link can be cloned freely
29    register_event_handlers(matrix_link.clone()).await;
30
31    matrix_link
32        .start()
33        .await
34        .expect("Failed to start MatrixLink");
35
36    println!("Done");
37}
38
39async fn create_matrix_link() -> MatrixLink {
40    let login_creds =
41        LoginCredentials::UserPassword(LOGIN_USERNAME.to_owned(), LOGIN_PASSWORD.to_owned());
42
43    let login_encryption = LoginEncryption::new(
44        Some(LOGIN_ENCRYPTION_RECOVERY_PASSPHRASE.to_owned()),
45        LOGIN_ENCRYPTION_RESET_ALLOWED,
46    );
47
48    let login_config = LoginConfig::new(
49        HOMESERVER_URL.to_owned(),
50        login_creds,
51        Some(login_encryption),
52        DEVICE_DISPLAY_NAME.to_owned(),
53    );
54
55    let session_file_path = std::path::PathBuf::from(PERSISTENCE_SESSION_FILE_PATH);
56    let session_encryption_key = EncryptionKey::from_hex_str(PERSISTENCE_SESSION_ENCRYPTION_KEY)
57        .expect("Invalid encryption key hex string");
58    let db_dir_path = std::path::PathBuf::from(PERSISTENCE_DB_DIR_PATH);
59
60    let persistence_config =
61        PersistenceConfig::new(session_file_path, Some(session_encryption_key), db_dir_path);
62
63    let init_config = InitConfig::new(login_config, persistence_config);
64
65    mxlink::init(&init_config)
66        .await
67        .expect("Failed to initialize MatrixLink")
68}
69
70async fn register_event_handlers(matrix_link: MatrixLink) {
71    let rooms = matrix_link.rooms();
72
73    // We auto-accept all invitations
74    rooms.on_invitation(|_event, _room| async move { Ok(InvitationDecision::Join) });
75
76    // We send an introduction to all rooms we join
77    let messaging = matrix_link.messaging();
78    rooms.on_joined(|_event, room| async move {
79        let _ = messaging
80            .send_text_markdown(&room, "Hello!".to_owned(), MessageResponseType::InRoom)
81            .await
82            .expect("Failed to send message");
83
84        Ok(())
85    });
86
87    // We listen for reactions to messages and send a reply to the original message that received the reaction
88    let messaging = matrix_link.messaging();
89    let reacting = matrix_link.reacting();
90    reacting.on_actionable_reaction(|event, room, reaction_event_content| async move {
91        let response_text = if reaction_event_content.relates_to.key == "👍️" {
92            format!("{} reacted to this message with thumbs up!", event.sender())
93        } else {
94            format!(
95                "{} reacted to this message with an unknown-to-me reaction ({}).",
96                event.sender(),
97                reaction_event_content.relates_to.key,
98            )
99        };
100
101        let response_type =
102            MessageResponseType::Reply(reaction_event_content.relates_to.event_id.clone());
103
104        let _ = messaging
105            .send_notice_markdown(&room, response_text, response_type)
106            .await
107            .expect("Failed to send message");
108
109        Ok(())
110    });
111}