Browse Source

initial commit

main
xenua 1 year ago
commit
0de46b3ce3
Signed by untrusted user: xenua
GPG Key ID: 8F93B68BD37255B8
  1. 3
      .gitignore
  2. 1881
      Cargo.lock
  3. 17
      Cargo.toml
  4. 2
      src/default_config.kdl
  5. 110
      src/main.rs

3
.gitignore vendored

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
/target
fedi-data.toml
config.kdl

1881
Cargo.lock generated

File diff suppressed because it is too large Load Diff

17
Cargo.toml

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
[package]
name = "fedi-frq-friend"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
futures-util = "0.3.28"
knuffel = "3.0.0"
mastodon-async = { version = "1.2.1", features = ["toml", "mt"] }
tokio = { version = "1.27.0", features = ["full"] }
[[bin]]
name = "f3"
path = "src/main.rs"

2
src/default_config.kdl

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
status-text "this is the automated follow request message from fedi-frq-friend. i haven't set the message in the config yet!"
with-cw "automated follow request pm" // optional

110
src/main.rs

@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
use futures_util::TryStreamExt;
use mastodon_async::entities::notification::NotificationType;
use mastodon_async::helpers::cli::authenticate;
use mastodon_async::helpers::toml;
use mastodon_async::prelude::*;
use mastodon_async::Result as MResult;
use std::fs::File;
use std::io::{self, Write};
const DEFAULT_CONFIG: &'static str = include_str!("default_config.kdl");
#[derive(knuffel::Decode, Debug, Clone)]
struct Config {
#[knuffel(child, unwrap(argument))]
status_text: String,
#[knuffel(child, unwrap(argument))]
with_cw: Option<String>,
}
async fn get_mastodon() -> MResult<Mastodon> {
if let Ok(data) = toml::from_file("fedi-data.toml") {
Ok(Mastodon::from(data))
} else {
log_in().await
}
}
async fn log_in() -> MResult<Mastodon> {
println!("fedi-data.toml is missing, doing initial setup:");
print!("Enter your instance url (e.g. botsin.space): ");
io::stdout().flush()?;
let mut instance = String::new();
io::stdin().read_line(&mut instance)?;
if !(instance.starts_with("http://") || instance.starts_with("https://")) {
instance = format!("https://{instance}");
}
let registration = Registration::new(instance.trim())
.client_name("frq-friend")
.scopes(Scopes::all())
.build()
.await?;
let mastodon = authenticate(registration).await?;
toml::to_file(&mastodon.data, "fedi-data.toml")?;
Ok(mastodon)
}
async fn do_the_thing() -> MResult<()> {
let config_string = std::fs::read_to_string("config.kdl").unwrap_or_else(|_| {
File::create("config.kdl")
.and_then(|mut v| v.write_all(DEFAULT_CONFIG.as_bytes()))
.expect("Unable to write default to config.kdl; is the working dir writable?");
println!("created example config.kdl. you probably want to change the text in there");
DEFAULT_CONFIG.to_string()
});
let config: Config =
knuffel::parse("config.kdl", &config_string).expect("Error parsing config.kdl");
let mastodon = get_mastodon().await?;
let stream = mastodon.stream_notifications().await?;
println!("listening for events\n--------------------");
stream
.try_for_each(|(event, client)| {
let cfg = config.clone();
async move {
match event {
Event::Notification {
0:
Notification {
notification_type: NotificationType::FollowRequest,
account,
..
},
} => {
println!(
"got a follow request from {} (@{})",
account.display_name, account.acct
);
let mut builder = StatusBuilder::new();
builder
.status(format!("@{}\n{}", account.acct, cfg.status_text))
.visibility(Visibility::Direct);
if let Some(cw) = cfg.with_cw {
builder.sensitive(true).spoiler_text(cw);
}
let status = builder.build()?;
client.new_status(status).await?;
}
_ => (),
}
Ok(())
}
})
.await?;
Ok(())
}
#[tokio::main]
async fn main() -> MResult<()> {
do_the_thing().await
}
Loading…
Cancel
Save