It ain't bridging yet

This commit is contained in:
vanten-s 2024-08-28 10:04:34 +02:00
commit a904c473b1
Signed by: vanten-s
GPG key ID: DE3060396884D3F2
6 changed files with 1855 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

1683
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

20
Cargo.toml Normal file
View file

@ -0,0 +1,20 @@
[package]
name = "mailing-list-matrix-bridge"
version = "0.1.0"
edition = "2021"
[dependencies]
color-eyre = "0.6.3"
eyre = "0.6.12"
futures = "0.3.30"
mlpa = "0.4.0"
ruma-client = { version = "0.13.0", features = ["hyper-native-tls", "client-api"] }
ruma-client-api = "0.18.0"
ruma-common = { version = "0.13.0", features = ["rand"] }
ruma-events = "0.28.1"
serde = { version = "1.0.209", features = ["derive"] }
tokio = { version = "1.39.3", features = ["rt-multi-thread"] }
toml = "0.8.19"
[lib]
crate-type = ["dylib"]

17
shell.nix Normal file
View file

@ -0,0 +1,17 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell rec {
buildInputs = with pkgs; [
rustup
openssl
];
RUSTC_VERSION = "stable";
shellHook = ''
rustup default $RUSTC_VERSION
rustup component add rust-analyzer
export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin
export PATH=$PATH:''${RUSTUP_HOME:-~/.rustup}/toolchains/nightly-x86_64-unknown-linux-gnu/bin/
export OPENSSL_DIR="${pkgs.openssl.dev}"
export OPENSSL_LIB_DIR="${pkgs.openssl.out}/lib"
'';
}

17
src/config.rs Normal file
View file

@ -0,0 +1,17 @@
use std::path::Path;
use color_eyre::eyre::Result;
use serde::Deserialize;
#[derive(Deserialize, Debug, Clone)]
pub(crate) struct Config {
pub access_token: String,
pub channel: String,
pub homeserver: String,
}
pub(crate) fn get_config(file: Option<&str>) -> Result<Config> {
let file = &Path::new(file.unwrap_or("/etc/mailing-list/matrix.toml"));
let file_contents = String::from_utf8(std::fs::read(file)?)?;
return Ok(toml::from_str(&file_contents)?);
}

117
src/lib.rs Normal file
View file

@ -0,0 +1,117 @@
use config::Config;
use eyre::Result;
use std::{ffi::c_char, sync::Mutex};
use mlpa::Plugin;
use ruma_client::{http_client::HyperNativeTls, Client};
use ruma_client_api::{alias::get_alias, message::send_message_event};
use ruma_common::{OwnedRoomAliasId, OwnedRoomId, TransactionId};
use ruma_events::room::message::{MessageType, RoomMessageEventContent, TextMessageEventContent};
mod config;
#[no_mangle]
pub extern "C" fn get_plugin() -> Plugin {
use mlpa::Optional::*;
Plugin {
on_start: Some(on_start),
message_handler: Some(message_handler),
}
}
static CLIENT: Mutex<Option<Client<HyperNativeTls>>> = Mutex::new(None);
static ROOM_ID: Mutex<Option<OwnedRoomId>> = Mutex::new(None);
static CONFIG: Mutex<Option<Config>> = Mutex::new(None);
extern "C" fn on_start() {
println!("Creating körtid");
let handle = tokio::runtime::Runtime::new().expect("Couldn't skapa the körtid");
println!("Går in i körtid");
handle.block_on(start()).unwrap();
}
extern "C" fn message_handler(_message: *const c_char) {}
async fn create_room_id() -> Result<()> {
let config = CONFIG.lock().unwrap();
let config = config.as_ref().unwrap();
let client = CLIENT.lock().unwrap();
let client = client.as_ref().unwrap();
let alias: OwnedRoomAliasId = config.channel.parse().unwrap();
let response = client
.send_request(get_alias::v3::Request::new(alias))
.await?;
println!("Room ID: {}", response.room_id);
*ROOM_ID.lock().unwrap() = Some(response.room_id);
Ok(())
}
async fn create_config() -> Result<()> {
let config = config::get_config(None)?;
*CONFIG.lock().unwrap() = Some(config);
Ok(())
}
async fn create_client() -> Result<()> {
let config = get_config();
let client = ruma_client::Client::builder()
.homeserver_url(config.homeserver.clone())
.access_token(Some(config.access_token.clone()))
.build::<HyperNativeTls>()
.await
.expect("Couldn't bygga the klient");
*CLIENT.lock().unwrap() = Some(client);
Ok(())
}
fn get_config() -> Config {
let config = CONFIG.lock().unwrap();
config.as_ref().unwrap().clone()
}
fn get_client() -> Client<HyperNativeTls> {
let client = CLIENT.lock().unwrap();
client.as_ref().unwrap().clone()
}
fn get_room_id() -> OwnedRoomId {
let room_id = ROOM_ID.lock().unwrap();
room_id.as_ref().unwrap().clone()
}
async fn send_message(message: &str) -> Result<()> {
let client = get_client();
let room_id = get_room_id();
let transaction_id = TransactionId::new();
let text_content = TextMessageEventContent::plain(message);
let content = RoomMessageEventContent::new(MessageType::Text(text_content));
let message = send_message_event::v3::Request::new(
room_id,
transaction_id.to_owned(),
&content,
)?;
client.send_request(message).await?;
Ok(())
}
async fn start() -> Result<()> {
create_config().await?;
create_client().await?;
create_room_id().await?;
send_message("Started Mailing-List Matrix bridge").await?;
println!("Started Matrix Plugin");
Ok(())
}