116 lines
3.4 KiB
Rust
116 lines
3.4 KiB
Rust
use sigh::PrivateKey;
|
|
use std::{sync::Arc, time::Duration};
|
|
use std::{panic, process};
|
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
|
use cave::activitypub;
|
|
|
|
mod error;
|
|
mod config;
|
|
mod db;
|
|
|
|
async fn follow_back(
|
|
client: &reqwest::Client, hostname: &str,
|
|
priv_key: &PrivateKey,
|
|
follow: db::Follow,
|
|
) {
|
|
let follow_id = format!(
|
|
"https://{}/activity/follow/{}/{}",
|
|
hostname,
|
|
urlencoding::encode(&follow.id),
|
|
urlencoding::encode(&follow.actor),
|
|
);
|
|
let action = activitypub::Action {
|
|
jsonld_context: Some(serde_json::Value::String("https://www.w3.org/ns/activitystreams".to_string())),
|
|
action_type: "Follow".to_string(),
|
|
id: follow_id,
|
|
to: None,
|
|
actor: follow.actor.clone(),
|
|
object: Some(&follow.id),
|
|
};
|
|
let key_id = format!("{}#key", follow.actor);
|
|
let result = activitypub::send::send(
|
|
client, &follow.inbox,
|
|
&key_id, &priv_key,
|
|
&action,
|
|
).await;
|
|
match result {
|
|
Ok(body) => {
|
|
tracing::info!("Ok {}: {:?}", follow.id, body);
|
|
}
|
|
Err(e) => {
|
|
tracing::error!("POST: {:?}", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
exit_on_panic();
|
|
|
|
tracing_subscriber::registry()
|
|
.with(
|
|
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
|
"buzzback=trace,tower_http=trace,axum=trace".into()
|
|
}),
|
|
)
|
|
.with(tracing_subscriber::fmt::layer())
|
|
.init();
|
|
|
|
let config = config::Config::load(
|
|
&std::env::args().nth(1)
|
|
.expect("Call with config.yaml")
|
|
);
|
|
let priv_key = config.priv_key();
|
|
|
|
let client = Arc::new(
|
|
reqwest::Client::builder()
|
|
.timeout(Duration::from_secs(5))
|
|
.user_agent(concat!(
|
|
env!("CARGO_PKG_NAME"),
|
|
"/",
|
|
env!("CARGO_PKG_VERSION"),
|
|
))
|
|
.pool_max_idle_per_host(0)
|
|
.pool_idle_timeout(Some(Duration::from_secs(1)))
|
|
.build()
|
|
.unwrap()
|
|
);
|
|
|
|
// Follow relays from the static list in the config.yaml
|
|
for relay in config.relays {
|
|
let (id, inbox) =
|
|
if relay.ends_with("/inbox") {
|
|
(relay.replace("/inbox", "/actor"), relay.clone())
|
|
} else if relay.ends_with("/actor") {
|
|
(relay.clone(), relay.replace("/actor", "/inbox"))
|
|
} else {
|
|
panic!("Not sure how to deal with relay {}", relay);
|
|
};
|
|
tracing::trace!("Following {}", &id);
|
|
let follow = db::Follow {
|
|
id,
|
|
actor: config.default_actor.clone(),
|
|
inbox,
|
|
};
|
|
follow_back(&client, &config.hostname, &priv_key, follow).await;
|
|
}
|
|
|
|
let database = db::Database::connect(&config.db).await;
|
|
let instance_followers = database.get_instance_followers().await.unwrap();
|
|
|
|
// Follow back every instance that followed us
|
|
for follow in instance_followers {
|
|
tracing::trace!("Following {}", follow.id);
|
|
follow_back(&client, &config.hostname, &priv_key, follow).await;
|
|
}
|
|
}
|
|
|
|
fn exit_on_panic() {
|
|
let orig_hook = panic::take_hook();
|
|
panic::set_hook(Box::new(move |panic_info| {
|
|
// invoke the default handler and exit the process
|
|
orig_hook(panic_info);
|
|
process::exit(1);
|
|
}));
|
|
}
|