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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//! # Utils
//!
//! ## Session
//!
//! The easiest way to use the [Session](crate::utils::Session) struct is to use it like this:
//!
//! ```compile_fail
//! use matrix_sdk::Session as SDKSession;
//!
//! if let Some(session) = Session::load(config.session_path.parse().unwrap()) {
//! info!("Starting relogin");
//!
//! let session = SDKSession {
//! access_token: session.access_token,
//! device_id: session.device_id.into(),
//! user_id: matrix_sdk::identifiers::UserId::try_from(session.user_id.as_str()).unwrap(),
//! };
//!
//! if let Err(e) = client.restore_login(session).await {
//! error!("{}", e);
//! };
//! info!("Finished relogin");
//! } else {
//! info!("Starting login");
//! let login_response = client
//! .login(
//! &config.mxid,
//! &config.password,
//! None,
//! Some(&"timetracking-bot".to_string()),
//! )
//! .await;
//! match login_response {
//! Ok(login_response) => {
//! info!("Session: {:#?}", login_response);
//! let session = Session {
//! homeserver: client.homeserver().to_string(),
//! user_id: login_response.user_id.to_string(),
//! access_token: login_response.access_token,
//! device_id: login_response.device_id.into(),
//! };
//! session.save(config.session_path.parse().unwrap())?;
//! }
//! Err(e) => error!("Error while login: {}", e),
//! }
//! info!("Finished login");
//! }
//! ```
//!
//! <br>
//!
//! This first checks if there is a session already existing and uses it to relogin using the known
//! session data.
//!
//! If not it creates and saves the [Session](crate::utils::Session) struct. Allowing for a relogin on the next start.
//!
//! ## Autojoin
//!
//! The [`#[autojoin]`](crate::utils::autojoin) macro is used to generate the logic in the
//! [EventEmitter](matrix_sdk::EventEmitter) to handle invites for the bot. It is executed after your code.
//!
//! The usage is:
//!
//! ```compile_fail
//! use matrix_sdk::async_trait;
//! use matrix_sdk::{
//! events::{
//! room::message::MessageEventContent, StrippedStateEvent,
//! },
//! EventEmitter, SyncRoom, Client
//! };
//! use tracing::*;
//!
//! #[derive(Debug, Clone)]
//! pub struct Bot {
//! client: Client,
//! }
//!
//! #[mrsbfh::utils::autojoin]
//! #[async_trait]
//! impl EventEmitter for Bot {
//! async fn on_stripped_state_member(
//! &self,
//! room: SyncRoom,
//! room_member: &StrippedStateEvent<MemberEventContent>,
//! _: Option<MemberEventContent>,
//! ) {
//! println!("autojoin example")
//! }
//! }
//! ```
//!
//! <br>
//!
//! **This does have some requirements:**
//! * The struct MUST have a field `client` which is the [MatrixSDK Client](matrix_sdk::Client)
//! * The `#[async_trait]` macro MUST be below the `#[autojoin]` macro
//! * The `on_stripped_state_member` method MUST exist and the arguments MUST be named the way they are named
//! in the example.
//!
use crateSessionError;
use ;
use PathBuf;
use *;