|
|
@ -1,8 +1,4 @@ |
|
|
|
use std::{
|
|
|
|
path::Path,
|
|
|
|
fs,
|
|
|
|
time::Duration
|
|
|
|
};
|
|
|
|
use std::{fs, path::Path, time::Duration};
|
|
|
|
|
|
|
|
use url::Url;
|
|
|
|
|
|
|
@ -10,32 +6,43 @@ use matrix_sdk::{ |
|
|
|
self,
|
|
|
|
events::{
|
|
|
|
room::{
|
|
|
|
member::MemberEventContent,
|
|
|
|
message::{MessageEventContent, TextMessageEventContent},
|
|
|
|
member::MemberEventContent
|
|
|
|
},
|
|
|
|
StrippedStateEventStub,
|
|
|
|
MessageEventStub
|
|
|
|
MessageEventStub, StrippedStateEventStub,
|
|
|
|
},
|
|
|
|
Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings, RoomState,
|
|
|
|
identifiers::UserId
|
|
|
|
identifiers::UserId,
|
|
|
|
Client, ClientConfig, EventEmitter, RoomState, SyncRoom, SyncSettings,
|
|
|
|
};
|
|
|
|
|
|
|
|
use phf::phf_map;
|
|
|
|
|
|
|
|
use async_trait::async_trait;
|
|
|
|
use db::DataStore;
|
|
|
|
|
|
|
|
mod relation;
|
|
|
|
mod config;
|
|
|
|
mod db;
|
|
|
|
mod relation;
|
|
|
|
|
|
|
|
const REACTION_MAP: phf::Map<&'static str, &'static str> = phf_map! {
|
|
|
|
"cat" => "🐈",
|
|
|
|
"spook" => "👀",
|
|
|
|
"glasses" => "👓"
|
|
|
|
};
|
|
|
|
|
|
|
|
struct EventCallback {
|
|
|
|
client: Client,
|
|
|
|
user_id: UserId,
|
|
|
|
statsd_client: statsd::Client
|
|
|
|
statsd_client: statsd::Client,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EventCallback {
|
|
|
|
pub fn new(client: Client, user_id: UserId, statsd_client: statsd::Client) -> Self {
|
|
|
|
Self { client, user_id, statsd_client }
|
|
|
|
Self {
|
|
|
|
client,
|
|
|
|
user_id,
|
|
|
|
statsd_client,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
@ -48,18 +55,25 @@ impl EventEmitter for EventCallback { |
|
|
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
|
|
|
event_id,
|
|
|
|
..
|
|
|
|
} = event {
|
|
|
|
if msg_body.to_lowercase().contains("cat") {
|
|
|
|
// Cat in message. React with emoji
|
|
|
|
|
|
|
|
match relation::react(&self.client,
|
|
|
|
event_id.clone(),
|
|
|
|
room.read().await.room_id.clone(),
|
|
|
|
"🐈".to_string()).await { // Cat emoji
|
|
|
|
Ok(_) => self.statsd_client.incr("reacted.cats"),
|
|
|
|
Err(x) => {
|
|
|
|
println!("Error while reacting: {}", x);
|
|
|
|
self.statsd_client.incr("reacted.error");
|
|
|
|
} = event
|
|
|
|
{
|
|
|
|
for (k, v) in REACTION_MAP.entries() {
|
|
|
|
if msg_body.to_lowercase().contains(k) {
|
|
|
|
// key in message. React with value
|
|
|
|
|
|
|
|
match relation::react(
|
|
|
|
&self.client,
|
|
|
|
event_id.clone(),
|
|
|
|
room.read().await.room_id.clone(),
|
|
|
|
v.to_string(),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
Ok(_) => self.statsd_client.incr(&format!("reacted.{}s", k)),
|
|
|
|
Err(x) => {
|
|
|
|
println!("Error while reacting: {}", x);
|
|
|
|
self.statsd_client.incr("reacted.error");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -68,10 +82,12 @@ impl EventEmitter for EventCallback { |
|
|
|
}
|
|
|
|
|
|
|
|
//Handles incoming invitations
|
|
|
|
async fn on_stripped_state_member(&self,
|
|
|
|
sync_room: SyncRoom,
|
|
|
|
room_member: &StrippedStateEventStub<MemberEventContent>,
|
|
|
|
_: Option<MemberEventContent>) {
|
|
|
|
async fn on_stripped_state_member(
|
|
|
|
&self,
|
|
|
|
sync_room: SyncRoom,
|
|
|
|
room_member: &StrippedStateEventStub<MemberEventContent>,
|
|
|
|
_: Option<MemberEventContent>,
|
|
|
|
) {
|
|
|
|
if room_member.state_key == self.user_id {
|
|
|
|
if let RoomState::Invited(x) = sync_room {
|
|
|
|
let room = x.read().await;
|
|
|
@ -80,7 +96,7 @@ impl EventEmitter for EventCallback { |
|
|
|
Ok(_) => {
|
|
|
|
println!("Joined {}", room.display_name());
|
|
|
|
self.statsd_client.incr("joined.success");
|
|
|
|
},
|
|
|
|
}
|
|
|
|
Err(_) => {
|
|
|
|
println!("There was an error while joining {}", room.display_name());
|
|
|
|
self.statsd_client.incr("joined.error");
|
|
|
@ -97,17 +113,19 @@ async fn login( |
|
|
|
password: String,
|
|
|
|
config: ClientConfig,
|
|
|
|
statsd_client: statsd::Client,
|
|
|
|
datastore: DataStore
|
|
|
|
datastore: DataStore,
|
|
|
|
) -> Result<(), matrix_sdk::Error> {
|
|
|
|
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
|
|
|
|
let mut client = Client::new_with_config(homeserver_url, config).unwrap();
|
|
|
|
|
|
|
|
let login_response = client.login(
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
datastore.get_device_id(),
|
|
|
|
Some("Cat Disruptor".to_string())
|
|
|
|
).await?;
|
|
|
|
let login_response = client
|
|
|
|
.login(
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
datastore.get_device_id(),
|
|
|
|
Some("Cat Disruptor".to_string()),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
println!("Logged in as {}", login_response.user_id);
|
|
|
|
println!("Device id: {}", login_response.device_id);
|
|
|
@ -121,12 +139,14 @@ async fn login( |
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() -> Result<(), matrix_sdk::Error> {
|
|
|
|
tracing_subscriber::fmt().with_env_filter(tracing_subscriber::EnvFilter::from_default_env()).init();
|
|
|
|
tracing_subscriber::fmt()
|
|
|
|
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
|
|
|
.init();
|
|
|
|
let config = config::get_config();
|
|
|
|
|
|
|
|
if config.homeserver_url == "changeme" &&
|
|
|
|
config.username == "changeme" &&
|
|
|
|
config.password == "changeme"
|
|
|
|
if config.homeserver_url == "changeme"
|
|
|
|
&& config.username == "changeme"
|
|
|
|
&& config.password == "changeme"
|
|
|
|
{
|
|
|
|
panic!("Please update the values in the config file!");
|
|
|
|
}
|
|
|
@ -137,7 +157,7 @@ async fn main() -> Result<(), matrix_sdk::Error> { |
|
|
|
if !store_path.exists() {
|
|
|
|
fs::create_dir(config.store_path.clone()).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let matrix_config = ClientConfig::new()
|
|
|
|
.store_path(store_path.clone())
|
|
|
|
.timeout(Duration::from_secs(60)); // Auto-reconnect if we lose connection
|
|
|
@ -146,7 +166,14 @@ async fn main() -> Result<(), matrix_sdk::Error> { |
|
|
|
// In the future we will probably store other things in the database.
|
|
|
|
// Sqlite would be overkill otherwise.
|
|
|
|
let datastore = DataStore::open(store_path.join("cat_disruptor.sqlite"));
|
|
|
|
|
|
|
|
login(config.homeserver_url, config.username, config.password,
|
|
|
|
matrix_config, statsd_client, datastore).await
|
|
|
|
|
|
|
|
login(
|
|
|
|
config.homeserver_url,
|
|
|
|
config.username,
|
|
|
|
config.password,
|
|
|
|
matrix_config,
|
|
|
|
statsd_client,
|
|
|
|
datastore,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|