webhooks
This commit is contained in:
parent
37475460e2
commit
02966c0605
9 changed files with 340 additions and 13 deletions
255
Cargo.lock
generated
255
Cargo.lock
generated
|
@ -294,6 +294,7 @@ dependencies = [
|
|||
"mdq",
|
||||
"mongod",
|
||||
"mongodb",
|
||||
"reqwest",
|
||||
"rocket",
|
||||
"rocket_cors",
|
||||
"serde",
|
||||
|
@ -387,6 +388,16 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
|
@ -665,6 +676,21 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
|
@ -965,6 +991,19 @@ dependencies = [
|
|||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
|
@ -1333,6 +1372,23 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -1383,6 +1439,50 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
@ -1462,6 +1562,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
|
@ -1623,6 +1729,46 @@ version = "0.8.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http 0.2.12",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resolv-conf"
|
||||
version = "0.7.0"
|
||||
|
@ -1846,6 +1992,15 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
|
@ -1868,6 +2023,29 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
|
@ -1940,6 +2118,18 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "1.14.0"
|
||||
|
@ -2150,6 +2340,33 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration-sys"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "take_mut"
|
||||
version = "0.2.2"
|
||||
|
@ -2280,6 +2497,16 @@ dependencies = [
|
|||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.24.1"
|
||||
|
@ -2606,6 +2833,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
@ -2663,6 +2896,18 @@ dependencies = [
|
|||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.93"
|
||||
|
@ -2692,6 +2937,16 @@ version = "0.2.93"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.25.4"
|
||||
|
|
|
@ -20,3 +20,4 @@ uuid = { version = "1.8.0", features = ["v4"] }
|
|||
mongod = { git = "https://git.hydrar.de/jmarya/mongod" }
|
||||
env_logger = "0.11.5"
|
||||
walkdir = "2.5.0"
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
12
config.toml
12
config.toml
|
@ -1 +1,13 @@
|
|||
# Only these tokens are authorized to make requests
|
||||
allowed_tokens = ["password"]
|
||||
|
||||
# Webhook Notifications
|
||||
[webhook]
|
||||
# Item Variants inventory goes below the minimum
|
||||
item_below_minimum = "https://example.com"
|
||||
|
||||
# Transaction gets added
|
||||
transaction_added = "https://example.com"
|
||||
|
||||
# Transaction gets consumed
|
||||
transaction_consumed = "https://example.com"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
# Webhooks
|
||||
Certain events can trigger webhooks. This allows you to independently build your automation pipeline.
|
||||
#todo
|
||||
Webhooks are configured in the `config.toml` file under `[webhook]`.
|
||||
|
||||
## Webhook Events
|
||||
These events can trigger a webhook:
|
||||
- Add a transaction
|
||||
- Consume a transaction
|
||||
- Item Variant amount goes below specified minimum
|
||||
|
|
|
@ -4,12 +4,15 @@ use serde::Deserialize;
|
|||
pub struct Config {
|
||||
/// Allowed tokens for access
|
||||
pub allowed_tokens: Vec<String>,
|
||||
/// Webhook Config
|
||||
pub webhook: Option<Webhook>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
allowed_tokens: Vec::new(),
|
||||
webhook: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,3 +24,17 @@ pub fn get_config() -> Config {
|
|||
|
||||
Config::default()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Webhook {
|
||||
pub item_below_minimum: Option<String>,
|
||||
pub transaction_added: Option<String>,
|
||||
pub transaction_consumed: Option<String>,
|
||||
}
|
||||
|
||||
impl Webhook {
|
||||
pub async fn send(url: &str, data: &serde_json::Value) {
|
||||
let client = reqwest::Client::new();
|
||||
client.post(url).json(data).send().await.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
use mongod::{Model, ToAPI};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{get, post, State};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::check_auth;
|
||||
use crate::config::Config;
|
||||
use crate::config::{Config, Webhook};
|
||||
use crate::item::Item;
|
||||
use crate::routes::Token;
|
||||
use crate::variant::Variant;
|
||||
use crate::{
|
||||
|
@ -26,7 +28,7 @@ pub struct DemandForm {
|
|||
pub async fn demand_route(f: Json<DemandForm>, t: Token, c: &State<Config>) -> FallibleApiResponse {
|
||||
check_auth!(t, c);
|
||||
|
||||
Variant::demand(
|
||||
let transaction = Variant::demand(
|
||||
&f.uuid,
|
||||
f.price
|
||||
.clone()
|
||||
|
@ -37,6 +39,33 @@ pub async fn demand_route(f: Json<DemandForm>, t: Token, c: &State<Config>) -> F
|
|||
.await
|
||||
.ok_or_else(|| api_error("Demand failed"))?;
|
||||
|
||||
if let Some(hook) = &c.webhook {
|
||||
if let Some(url) = &hook.transaction_consumed {
|
||||
Webhook::send(url, &transaction.api().await).await;
|
||||
}
|
||||
|
||||
if let Some(url) = &hook.item_below_minimum {
|
||||
let variant = Item::get(&transaction.item)
|
||||
.await
|
||||
.unwrap()
|
||||
.variant(&transaction.variant)
|
||||
.unwrap();
|
||||
let min_res = variant.is_below_min().await;
|
||||
if min_res.0 {
|
||||
Webhook::send(
|
||||
url,
|
||||
&json!({
|
||||
"item": transaction.item,
|
||||
"variant": transaction.variant,
|
||||
"minimum": variant.min,
|
||||
"current_amount": variant.min.unwrap() - min_res.1
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(json!({"ok": 1}))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use mongod::ToAPI;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{get, post, State};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::check_auth;
|
||||
use crate::config::Config;
|
||||
use crate::config::{Config, Webhook};
|
||||
use crate::routes::Token;
|
||||
use crate::{
|
||||
db::ItemDB,
|
||||
|
@ -38,7 +39,7 @@ pub async fn supply_route(
|
|||
.variant(&form.variant)
|
||||
.ok_or_else(variant_does_not_exist_error)?;
|
||||
|
||||
let transaction_id = variant
|
||||
let transaction = variant
|
||||
.supply(
|
||||
form.price
|
||||
.clone()
|
||||
|
@ -49,7 +50,13 @@ pub async fn supply_route(
|
|||
)
|
||||
.await;
|
||||
|
||||
Ok(json!({"uuid": transaction_id}))
|
||||
if let Some(hook) = &c.webhook {
|
||||
if let Some(url) = &hook.transaction_added {
|
||||
Webhook::send(url, &transaction.api().await).await;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(json!({"uuid": transaction._id}))
|
||||
}
|
||||
|
||||
/// Returns a list of Transaction UUIDs for the Item Variant
|
||||
|
|
|
@ -77,7 +77,7 @@ impl Transaction {
|
|||
}
|
||||
|
||||
/// Consumes the Item with `price` and `destination`
|
||||
pub async fn consume(self, price: Price, destination: &str) {
|
||||
pub async fn consume(self, price: Price, destination: &str) -> Self {
|
||||
self.change()
|
||||
.consumed(Some(Consumed {
|
||||
destination: destination.to_string(),
|
||||
|
@ -86,7 +86,7 @@ impl Transaction {
|
|||
}))
|
||||
.update()
|
||||
.await
|
||||
.unwrap();
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub async fn is_expired(&self) -> bool {
|
||||
|
|
|
@ -125,11 +125,11 @@ impl Variant {
|
|||
ret
|
||||
}
|
||||
|
||||
pub async fn demand(uuid: &str, price: Price, destination: &str) -> Option<()> {
|
||||
pub async fn demand(uuid: &str, price: Price, destination: &str) -> Option<Transaction> {
|
||||
// check if transaction exists
|
||||
let mut t = Transaction::get(uuid).await?;
|
||||
t.consume(price, destination).await;
|
||||
Some(())
|
||||
t = t.consume(price, destination).await;
|
||||
Some(t)
|
||||
}
|
||||
|
||||
/// Records a supply transaction in the database.
|
||||
|
@ -147,12 +147,12 @@ impl Variant {
|
|||
price: Price,
|
||||
origin: Option<&str>,
|
||||
location: Option<&str>,
|
||||
) -> String {
|
||||
) -> Transaction {
|
||||
let t = Transaction::new(&self.item, &self.variant, price, origin, location).await;
|
||||
|
||||
t.insert().await.unwrap();
|
||||
|
||||
t._id
|
||||
t
|
||||
}
|
||||
|
||||
pub async fn get_all_transactions(&self) -> Vec<Transaction> {
|
||||
|
|
Loading…
Reference in a new issue