receive posts from zulip and reply

This commit is contained in:
joe 2025-12-20 14:19:18 -08:00
parent 13a8f5dc8a
commit 046d3157c2
4 changed files with 52 additions and 15 deletions

10
Cargo.lock generated
View file

@ -221,6 +221,7 @@ dependencies = [
"tracing",
"tracing-subscriber",
"unicode-segmentation",
"winnow",
]
[[package]]
@ -3306,6 +3307,15 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen"
version = "0.46.0"

View file

@ -21,6 +21,7 @@ tokio-util = "0.7.17"
tracing = "0.1.43"
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
unicode-segmentation = "1.12.0"
winnow = "0.7.14"
[dev-dependencies]
rand = "0.9.2"

View file

@ -30,7 +30,8 @@ pub struct BlogdorTheAggregator {
cancel: CancellationToken,
endpoint: String,
channel_id: u32,
email: String,
blogdor_to_zulip_email: String,
zulip_to_blogdor_email: String,
zulip_token: String, // sent *to zulip* in POSTs *from us*
blogdor_token: String, // sent *from zulip* in POSTs *to us*
}
@ -75,7 +76,10 @@ impl BlogdorTheAggregator {
.parse()
.expect("ZULIP_CHANNEL must be an integer");
let password = std::env::var("ZULIP_TOKEN").expect("ZULIP_TOKEN must be set");
let email = std::env::var("BLOGDOR_EMAIL").expect("BLOGDOR_EMAIL must be set");
let b2z_email =
std::env::var("BLOGDOR_TO_ZULIP_EMAIL").expect("BLOGDOR_TO_ZULIP_EMAIL must be set");
let z2b_email =
std::env::var("ZULIP_TO_BLOGDOR_EMAIL").expect("ZULIP_TO_BLOGDOR_EMAIL must be set");
let token = std::env::var("BLOGDOR_TOKEN").expect("BLOGDOR_TOKEN must be set");
Self {
@ -84,7 +88,8 @@ impl BlogdorTheAggregator {
cancel,
endpoint,
channel_id,
email,
blogdor_to_zulip_email: b2z_email,
zulip_to_blogdor_email: z2b_email,
zulip_token: password,
blogdor_token: token,
}
@ -95,7 +100,11 @@ impl BlogdorTheAggregator {
}
pub async fn spawn_http(&self) {
let state = ServerState::new(self.db.clone(), &self.email, &self.blogdor_token);
let state = ServerState::new(
self.db.clone(),
&self.zulip_to_blogdor_email,
&self.blogdor_token,
);
server::spawn_server(state, self.cancel.clone()).await;
}
@ -161,7 +170,7 @@ impl BlogdorTheAggregator {
match self
.client
.post(&self.endpoint)
.basic_auth(&self.email, Some(&self.zulip_token))
.basic_auth(&self.blogdor_to_zulip_email, Some(&self.zulip_token))
.body(msg)
.header("Content-Type", "application/x-www-form-urlencoded")
.send()

View file

@ -1,4 +1,4 @@
use std::{net::SocketAddr, sync::Arc};
use std::{collections::HashMap, net::SocketAddr, sync::Arc};
use axum::{
Router,
@ -11,6 +11,7 @@ use serde::Deserialize;
use serde_json::{Map, Value};
use sqlx::SqlitePool;
use tokio_util::sync::CancellationToken;
use winnow::Parser;
type Payload = Map<String, Value>;
@ -49,28 +50,28 @@ pub(crate) async fn spawn_server(
fn make_router(state: ServerState) -> Router {
Router::new()
.route("/api/v1/add-feed", post(handle_add_feed))
.route("/blogdor/manage-feeds", post(handle_manage_feed))
.with_state(state.into())
}
async fn handle_add_feed(
async fn handle_manage_feed(
State(state): State<Arc<ServerState>>,
Json(request): Json<AddFeedRequest>,
Json(request): Json<ManageFeedMessage>,
) -> impl IntoResponse {
let AddFeedRequest {
let ManageFeedMessage {
bot_email,
token,
message,
_rest: _,
} = request;
tracing::debug!("email: {bot_email}, token: {token}");
if state.email == bot_email && state.token == token {
tracing::debug!("gonna do a thing with {message:?}");
// things
(StatusCode::IM_A_TEAPOT, "nee-ope")
Json(HashMap::from([("content", "nee-ope")])).into_response()
} else {
tracing::debug!("psych");
(StatusCode::IM_A_TEAPOT, "nee-ope")
tracing::debug!("bad emal/token");
StatusCode::IM_A_TEAPOT.into_response()
}
}
@ -101,7 +102,7 @@ async fn graceful_shutdown(cancel: CancellationToken) {
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
struct AddFeedRequest {
struct ManageFeedMessage {
bot_email: String,
token: String,
message: ZulipMessage,
@ -118,3 +119,19 @@ struct ZulipMessage {
#[serde(flatten)]
_rest: Payload,
}
fn parse_command(input: &mut &str) -> String {
// let Ok(s) = ("***@", winnow::token::take_until(1.., "**"))
// .map(|(_, s, _)| s)
// .parse_next(input)
// else {
// return "could not find Blogdor's name".to_string();
// };
// if s != "Blogdor Outgoing Bot" {
// return "could not confirm Blogdor's name".to_string();
// }
// s.into()
todo!()
}