1
Fork 0
generated from lucas/rust-template
Code Issues 1 Pull requests 9 Activity
Var Dump:
dumpVar: only available in dev mode
Mailing List
ntfy-collector/src/worker/lua.rs
Lucas Schwiderski d2cb39f9a2
Rework API tasks
GitHub expects a 'Last-Modified' header, and honoring an
'X-Poll-Interval' header for their notifications endpoint.
Other services might also have certain limitations that require
customizing every API query individually.

Since that's not possible if API tasks are configured once and run off
of an interval, this reworks them so that the config needs to trigger
every query individually. A `delay` parameter allows re-creating the
same intervals that were possible before.

This also moves the configuration for Ntfy to the Lua file.
2024-09-18 11:31:10 +02:00

87 lines
2.9 KiB
Rust

use std::sync::mpsc::Receiver;
use color_eyre::Result;
use mlua::{Function, IntoLua as _, Lua, LuaSerdeExt};
use tokio::sync::mpsc::UnboundedSender;
use crate::types::{ApiTask, Event, Message};
#[tracing::instrument(skip_all)]
pub fn worker(
config: String,
event_rx: Receiver<Event>,
api_tx: UnboundedSender<ApiTask>,
ntfy_tx: UnboundedSender<Message>,
) -> Result<()> {
let lua = Lua::new();
let globals = lua.globals();
let config = lua.load(config).set_name("config");
lua.scope(|scope| {
let ntfy_fn = scope.create_function_mut(|_, data: mlua::Value| {
let data = lua.from_value(data)?;
tracing::trace!("Sending Ntfy message: {:?}", data);
match ntfy_tx.send(Message::Ntfy(data)) {
Ok(_) => Ok((true, mlua::Value::Nil)),
Err(_) => {
let msg = lua.create_string("Failed to send message")?;
Ok((false, mlua::Value::String(msg)))
}
}
})?;
let set_api_task_fn = scope.create_function_mut(|_, data: mlua::Value| {
let task = lua.from_value(data)?;
tracing::trace!("Sending task request: {:?}", task);
match api_tx.send(task) {
Ok(_) => Ok((true, mlua::Value::Nil)),
Err(_) => {
let msg = lua.create_string("Failed to trigger task")?;
Ok((false, mlua::Value::String(msg)))
}
}
})?;
globals.set("ntfy", ntfy_fn)?;
globals.set("api_task", set_api_task_fn)?;
config.exec()?;
let event_fn: Function = match globals.get("on_event") {
Ok(f) => f,
Err(err) => match err {
mlua::Error::FromLuaConversionError { from, to: _, message: _ } => {
let err = mlua::Error::runtime(format!("Global function 'on_event' not defined properly. Got value of type '{}'", from));
return Err(err);
}
err => return Err(err),
},
};
// Main blocking loop. As long as we can receive events, this scope will stay active.
while let Ok(event) = event_rx.recv() {
tracing::trace!("Received event: {:?}", event);
match event {
Event::Webhook(data) => {
let data = lua.to_value(&data)?;
event_fn.call::<_, ()>(("webhook", data))?
}
Event::Api(data) => {
let data = data.into_lua(&lua)?;
event_fn.call::<_, ()>(("api", data))?
}
Event::Error(data) => {
let data = lua.to_value(&data)?;
event_fn.call::<_, ()>(("error", data))?
}
}
}
Ok(())
})?;
Ok(())
}