mirror of
https://git.alemi.dev/guestbook.rs.git
synced 2024-11-14 12:29:19 +01:00
chore: moved telegram notifier as optional feature
This commit is contained in:
parent
62a7cdbbef
commit
dbcf022019
4 changed files with 60 additions and 63 deletions
|
@ -13,7 +13,13 @@ html-escape = "0.2.13"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
serde = { version = "1.0.189", features = ["derive"] }
|
serde = { version = "1.0.189", features = ["derive"] }
|
||||||
serde_json = "1.0.107"
|
serde_json = "1.0.107"
|
||||||
teloxide = { version = "0.12.2", features = ["macros"] }
|
|
||||||
tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] }
|
||||||
tracing = "0.1.39"
|
tracing = "0.1.39"
|
||||||
tracing-subscriber = "0.3.17"
|
tracing-subscriber = "0.3.17"
|
||||||
|
# telegram provider
|
||||||
|
teloxide = { version = "0.12.2", features = ["macros"], optional = true }
|
||||||
|
thiserror = "1.0.51"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
telegram = ["dep:teloxide"]
|
||||||
|
|
80
src/main.rs
80
src/main.rs
|
@ -1,20 +1,20 @@
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use axum::{routing::{get, put, post}, http::StatusCode, Json, Router, Form};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use teloxide::prelude::*;
|
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
use crate::{storage::JsonFileStorageStrategy, routes::Context, notifications::console::ConsoleTracingNotifier};
|
||||||
static ref BOT : Bot = Bot::from_env();
|
|
||||||
static ref CHAT_ID : RwLock<ChatId> = RwLock::new(ChatId(0)); // TODO ewwwwwww
|
mod notifications;
|
||||||
}
|
|
||||||
|
mod routes;
|
||||||
|
mod model;
|
||||||
|
mod storage;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Parser)]
|
#[derive(Debug, Clone, Parser)]
|
||||||
/// api for sending anonymous telegram messages to a specific user
|
/// api for sending anonymous telegram messages to a specific user
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
/// chat id of target user
|
// chat id of target user
|
||||||
target: i64,
|
//target: i64,
|
||||||
|
|
||||||
#[arg(long, short, default_value = "127.0.0.1:37812")]
|
#[arg(long, short, default_value = "127.0.0.1:37812")]
|
||||||
/// host to bind onto
|
/// host to bind onto
|
||||||
|
@ -27,63 +27,19 @@ async fn main() {
|
||||||
|
|
||||||
let args = CliArgs::parse();
|
let args = CliArgs::parse();
|
||||||
|
|
||||||
*CHAT_ID.write().await = ChatId(args.target);
|
|
||||||
|
|
||||||
let app = Router::new()
|
|
||||||
.route("/send", get(suggestion_help))
|
|
||||||
.route("/send", post(suggestion_form))
|
|
||||||
.route("/send", put(suggestion_json));
|
|
||||||
|
|
||||||
let addr : SocketAddr = args.addr.parse().expect("invalid host provided");
|
let addr : SocketAddr = args.addr.parse().expect("invalid host provided");
|
||||||
|
|
||||||
|
let storage = Box::new(JsonFileStorageStrategy::new("./storage.json"));
|
||||||
|
|
||||||
|
let state = Context::new(storage)
|
||||||
|
.register(Box::new(ConsoleTracingNotifier {}));
|
||||||
|
|
||||||
|
let router = routes::create_router_with_app_routes(state);
|
||||||
|
|
||||||
tracing::info!("listening on {}", addr);
|
tracing::info!("listening on {}", addr);
|
||||||
|
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service())
|
.serve(router.into_make_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn suggestion_help() -> (StatusCode, Json<Suggestion>) {
|
|
||||||
let body = "use this endpoint to send me direct messages. this is the accepted structure. on PUT send as json, on POST send as form-urlencoded".to_string();
|
|
||||||
(StatusCode::OK, Json(Suggestion { author: None, contact: None, body }))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn suggestion_json(Json(payload): Json<Suggestion>) -> (StatusCode, Json<Acknowledgement>) {
|
|
||||||
suggestion_inner(payload).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn suggestion_form(Form(payload): Form<Suggestion>) -> (StatusCode, Json<Acknowledgement>) {
|
|
||||||
suggestion_inner(payload).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn suggestion_inner(payload: Suggestion) -> (StatusCode, Json<Acknowledgement>) {
|
|
||||||
let message = format!(
|
|
||||||
"[<code>{}</code>] <i>{}</i> | {}",
|
|
||||||
html_escape::encode_text(payload.author.as_deref().unwrap_or("anon")),
|
|
||||||
html_escape::encode_text(payload.contact.as_deref().unwrap_or("N/A")),
|
|
||||||
html_escape::encode_text(&payload.body)
|
|
||||||
);
|
|
||||||
|
|
||||||
match BOT
|
|
||||||
.send_message(*CHAT_ID.read().await, message)
|
|
||||||
.parse_mode(teloxide::types::ParseMode::Html)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(x) => (StatusCode::OK, Json(Acknowledgement::Sent(x.text().unwrap_or("").into()))),
|
|
||||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, Json(Acknowledgement::Refused(e.to_string()))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct Suggestion {
|
|
||||||
author: Option<String>,
|
|
||||||
contact: Option<String>,
|
|
||||||
body: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
enum Acknowledgement {
|
|
||||||
Sent(String),
|
|
||||||
Refused(String),
|
|
||||||
}
|
|
||||||
|
|
11
src/notifications/mod.rs
Normal file
11
src/notifications/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
#[cfg(feature = "telegram")]
|
||||||
|
pub mod telegram;
|
||||||
|
|
||||||
|
pub mod console;
|
||||||
|
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
pub trait NotificationProcessor<T> : Send + Sync {
|
||||||
|
async fn process(&self, notification: &T);
|
||||||
|
}
|
24
src/notifications/telegram.rs
Normal file
24
src/notifications/telegram.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
use teloxide::prelude::*;
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref BOT : Bot = Bot::from_env();
|
||||||
|
static ref CHAT_ID : RwLock<ChatId> = RwLock::new(ChatId(0)); // TODO ewwwwwww
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn suggestion_inner(payload: Suggestion) -> (StatusCode, Json<Acknowledgement>) {
|
||||||
|
let message = format!(
|
||||||
|
"[<code>{}</code>] <i>{}</i> | {}",
|
||||||
|
html_escape::encode_text(payload.author.as_deref().unwrap_or("anon")),
|
||||||
|
html_escape::encode_text(payload.contact.as_deref().unwrap_or("N/A")),
|
||||||
|
html_escape::encode_text(&payload.body)
|
||||||
|
);
|
||||||
|
|
||||||
|
match BOT
|
||||||
|
.send_message(*CHAT_ID.read().await, message)
|
||||||
|
.parse_mode(teloxide::types::ParseMode::Html)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(x) => (StatusCode::OK, Json(Acknowledgement::Sent(x.text().unwrap_or("").into()))),
|
||||||
|
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, Json(Acknowledgement::Refused(e.to_string()))),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue