Added webhook configuration and documentation updates (#158)

* Added webhook configuration and documentation updates

* Updated docs

* Notifications

* Updated ValheimPlus instructions
This commit is contained in:
Michael
2021-02-25 21:19:10 -07:00
committed by GitHub
parent 2356ff7b68
commit bf6865ed2c
17 changed files with 1332 additions and 40 deletions

View File

@@ -12,9 +12,8 @@ insert_final_newline = true
[*.rs]
max_line_length = 100
#
# [{*.graphqlconfig,*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
# # indent_size = 2
#
# [{*.yaml,*.yml}]
# # indent_size = 2
[{*.graphqlconfig,*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
indent_size = 2
[{*.yaml,*.yml}]
indent_size = 2

787
Cargo.lock generated
View File

@@ -23,6 +23,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bitflags"
version = "1.2.1"
@@ -35,18 +41,49 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
[[package]]
name = "bumpalo"
version = "3.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "cargo-husky"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
[[package]]
name = "cc"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "clap"
version = "3.0.0-beta.2"
@@ -80,6 +117,16 @@ dependencies = [
"syn",
]
[[package]]
name = "core-foundation"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.2"
@@ -111,6 +158,15 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "encoding_rs"
version = "0.8.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
dependencies = [
"cfg-if",
]
[[package]]
name = "filetime"
version = "0.2.14"
@@ -135,6 +191,88 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "fnv"
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.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
"matches",
"percent-encoding",
]
[[package]]
name = "futures-channel"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
[[package]]
name = "futures-io"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
[[package]]
name = "futures-sink"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"
[[package]]
name = "futures-task"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86"
dependencies = [
"once_cell",
]
[[package]]
name = "futures-util"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
dependencies = [
"futures-core",
"futures-io",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "getrandom"
version = "0.2.2"
@@ -146,6 +284,26 @@ dependencies = [
"wasi",
]
[[package]]
name = "h2"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b67e66362108efccd8ac053abafc8b7a8d86a37e6e48fc4f6f7485eb5e9e6a5"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
"tracing-futures",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
@@ -170,6 +328,87 @@ dependencies = [
"libc",
]
[[package]]
name = "http"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "httparse"
version = "1.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691"
[[package]]
name = "httpdate"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
[[package]]
name = "hyper"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8e946c2b1349055e0b72ae281b238baf1a3ea7307c7e9f9d64673bdd9c26ac7"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project",
"socket2",
"tokio",
"tower-service",
"tracing",
"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 = "idna"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "1.6.1"
@@ -180,12 +419,33 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "inflections"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a"
[[package]]
name = "ipnet"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135"
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "js-sys"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -213,6 +473,24 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "miniz_oxide"
version = "0.4.3"
@@ -223,6 +501,47 @@ dependencies = [
"autocfg",
]
[[package]]
name = "mio"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc250d6848c90d719ea2ce34546fb5df7af1d3fd189d10bf7bad80bfcebecd95"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"winapi",
]
[[package]]
name = "miow"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
dependencies = [
"socket2",
"winapi",
]
[[package]]
name = "native-tls"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "ntapi"
version = "0.3.6"
@@ -232,16 +551,48 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "odin"
version = "1.2.0"
dependencies = [
"cargo-husky",
"chrono",
"clap",
"daemonize",
"flate2",
"inflections",
"log",
"rand",
"reqwest",
"serde",
"serde_json",
"sysinfo",
@@ -255,12 +606,89 @@ version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
[[package]]
name = "openssl"
version = "0.10.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"lazy_static",
"libc",
"openssl-sys",
]
[[package]]
name = "openssl-probe"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
[[package]]
name = "openssl-sys"
version = "0.9.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "os_str_bytes"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pin-project"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96fa8ebb90271c4477f144354485b8068bd8f6b78b428b01ba892ca26caf0b63"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "ppv-lite86"
version = "0.2.10"
@@ -358,12 +786,89 @@ dependencies = [
"bitflags",
]
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "reqwest"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0460542b551950620a3648c6aa23318ac6b3cd779114bd873209e6e8b5eb1c34"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"hyper-tls",
"ipnet",
"js-sys",
"lazy_static",
"log",
"mime",
"native-tls",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "schannel"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
dependencies = [
"lazy_static",
"winapi",
]
[[package]]
name = "security-framework"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "serde"
version = "1.0.123"
@@ -395,6 +900,35 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "socket2"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
dependencies = [
"cfg-if",
"libc",
"winapi",
]
[[package]]
name = "strsim"
version = "0.10.0"
@@ -438,6 +972,20 @@ dependencies = [
"xattr",
]
[[package]]
name = "tempfile"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
name = "termcolor"
version = "1.1.2"
@@ -476,6 +1024,130 @@ dependencies = [
"syn",
]
[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "tinyvec"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"pin-project-lite",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tower-service"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]]
name = "tracing"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f77d3842f76ca899ff2dbcf231c5c65813dea431301d6eb686279c15c4464f12"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
dependencies = [
"lazy_static",
]
[[package]]
name = "tracing-futures"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
dependencies = [
"pin-project",
"tracing",
]
[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
dependencies = [
"matches",
]
[[package]]
name = "unicode-normalization"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.7.1"
@@ -494,6 +1166,24 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "url"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
dependencies = [
"form_urlencoded",
"idna",
"matches",
"percent-encoding",
]
[[package]]
name = "vcpkg"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
[[package]]
name = "vec_map"
version = "0.8.2"
@@ -506,12 +1196,100 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "want"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
dependencies = [
"log",
"try-lock",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be"
dependencies = [
"cfg-if",
"serde",
"serde_json",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3de431a2910c86679c34283a33f66f4e4abd7e0aec27b6669060148872aadf94"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
[[package]]
name = "web-sys"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "which"
version = "4.0.2"
@@ -553,6 +1331,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "winreg"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
dependencies = [
"winapi",
]
[[package]]
name = "xattr"
version = "0.2.2"

View File

@@ -16,6 +16,10 @@ serde_json = "1.0"
daemonize = "0.4"
tar = "0.4"
flate2 = "1.0"
inflections = "1.1.1"
reqwest = { version = "0.11.1", features = ["blocking", "json"] }
chrono = "0.4"
[dev-dependencies]
rand = "0.8.3"

View File

@@ -43,6 +43,7 @@
| AUTO_BACKUP_DAYS_TO_LIVE | `3` | FALSE | This is the number of days you would like to keep backups for. While backups are compressed and generally small it is best to change this number as needed. |
| AUTO_BACKUP_ON_UPDATE | `0` | FALSE | Create a backup on right before updating and starting your server. |
| AUTO_BACKUP_ON_SHUTDOWN | `0` | FALSE | Create a backup on shutdown. |
| WEBHOOK_URL | `` | FALSE | Supply this to get information regarding your server's status in a webhook or Discord notification! [Click here to learn how to get a webhook url for Discord](https://help.dashe.io/en/articles/2521940-how-to-create-a-discord-webhook-url) |
### Docker Compose
@@ -97,47 +98,35 @@ services:
- AUTO_BACKUP_DAYS_TO_LIVE=3
- AUTO_BACKUP_ON_UPDATE=1
- AUTO_BACKUP_ON_SHUTDOWN=1
- WEBHOOK_URL="https://discord.com/api/webhooks/IM_A_SNOWFLAKE/AND_I_AM_A_SECRET"
volumes:
- ./valheim/saves:/home/steam/.config/unity3d/IronGate/Valheim
- ./valheim/server:/home/steam/valheim
- ./valheim/backups:/home/steam/backups
```
### Advanced Environment Variables
> Editing or adding these can cause issues! They are intended to give you more access to the system.
#### Odin Specific
> These are set automatically by [Odin];
> you DO NOT need to set these and only mess with them if you Know what you are doing.
| Variable | Default | Required | Description |
|--------------------------|------------------------|----------|-------------|
| DEBUG_MOD | `0` | FALSE | Set to `1` if you want a noisy output and to see what Odin is doing.
| ODIN_CONFIG_FILE | `config.json` | FALSE | This file stores start parameters to restart the instance, change if you run multiple container instances on the same host |
| ODIN_WORKING_DIR | `$PWD` | FALSE | Sets the directory you wish to run `odin` commands in and can be used to set where valheim is managed from. |
#### BepInEx/Modded Variables
> These are set automatically by [Odin] for a basic BepInEx installation;
> you DO NOT need to set these and only mess with them if you Know what you are doing.
| Variable | Default | Required | Description |
|--------------------------|----------------------------------------------------------|----------|-------------|
| LD_PRELOAD | `libdoorstop_x64.so` | TRUE | Sets which library to preload on Valheim start. |
| LD_LIBRARY_PATH | `./linux64:/home/steam/valheim/doorstop_libs` | TRUE | Sets which library paths it should look in for preload libs. |
| DOORSTOP_ENABLE | `TRUE` | TRUE | Enables Doorstop or not. |
| DOORSTOP_LIB | `libdoorstop_x64.so` | TRUE | Which doorstop lib to load |
| DOORSTOP_LIBS | `/home/steam/valheim/doorstop_libs` | TRUE | Where to look for doorstop libs. |
| DOORSTOP_INVOKE_DLL_PATH | `/home/steam/valheim/BepInEx/core/BepInEx.Preloader.dll` | TRUE | BepInEx preload dll to load. |
| DYLD_LIBRARY_PATH | `"/home/steam/valheim/doorstop_libs"` | TRUE | Sets the library paths. NOTE: This variable is weird and MUST have quotes around it! |
| DYLD_INSERT_LIBRARIES | `/home/steam/valheim/doorstop_libs/libdoorstop_x64.so` | TRUE | Sets which library to load. |
### [Odin]
This repo has a CLI tool called [Odin] in it! It is used for managing the server inside the container. If you are looking for instructions for it click here: [Odin]
[Click here to see advanced environment variables for Odin](./docs/odin.md)
### [BepInEx Support](./docs/bepinex.md)
This repo automatically launches with the proper environment variables for BepInEx.
However, you have to install it manually in the container due to the fact that the modding community around Valheim is still in its infancy.
[Click Here to view documentation on BepInEx Support](./docs/bepinex.md)
### [Webhook Support](./docs/webhooks.md)
This repo can automatically send notifications to discord via the WEBHOOK_URL variable.
Only use the documentation link below if you want advanced settings!
[Click Here to view documentation on Webhook Support](./docs/webhooks.md)
## Sponsors
<a href="https://github.com/AtroposOrbis">

64
docs/bepinex.md Normal file
View File

@@ -0,0 +1,64 @@
# BepInEx Support
## Installing BepInEx
> Due to the fact that there are so many variants of installing and running BepInEx; we will be covering only the basics.
> If you have additional questions please visit their discord. [BepInEx Discord](https://discord.gg/aZszQ9YB)
> If you have issues with setting up a specific plugin, please contact the mod developer!
1. Access the container as the steam user.
```shell
docker-compose exec --user steam valheim bash
```
2. Create a new folder
```shell
mkdir -p ~/tmp
```
3. Download BepInEx
```shell
wget -O /home/steam/tmp/bepinex.zip https://github.com/valheimPlus/ValheimPlus/releases/download/0.9/UnixServer.zip
```
4. Extract the BepInEx zip file
> Overwrite files with `A`
```shell
unzip /home/steam/tmp/bepinex.zip -d /home/steam/valheim
```
5. Cleanup files
```shell
cd /home/steam/valheim && rm -rf /home/steam/tmp
```
6. Restart your server.
> You should see a huge disclaimer in your console about running with bepinex.
## BepInEx/Modded Variables
> These are set automatically by [Odin] for a basic BepInEx installation;
> you DO NOT need to set these and only mess with them if you Know what you are doing.
| Variable | Default | Required | Description |
|-------------------------------|----------------------------------------------------------|----------|-------------|
| LD_PRELOAD | `libdoorstop_x64.so` | TRUE | Sets which library to preload on Valheim start. |
| LD_LIBRARY_PATH | `./linux64:/home/steam/valheim/doorstop_libs` | TRUE | Sets which library paths it should look in for preload libs. |
| DOORSTOP_ENABLE | `TRUE` | TRUE | Enables Doorstop or not. |
| DOORSTOP_LIB | `libdoorstop_x64.so` | TRUE | Which doorstop lib to load |
| DOORSTOP_LIBS | `/home/steam/valheim/doorstop_libs` | TRUE | Where to look for doorstop libs. |
| DOORSTOP_INVOKE_DLL_PATH | `/home/steam/valheim/BepInEx/core/BepInEx.Preloader.dll` | TRUE | BepInEx preload dll to load. |
| DOORSTOP_CORLIB_OVERRIDE_PATH | `/home/steam/valheim/unstripped_corlib` | TRUE | Sets where the decompiled libraries containing base mono files are located at |
| DYLD_LIBRARY_PATH | `"/home/steam/valheim/doorstop_libs"` | TRUE | Sets the library paths. NOTE: This variable is weird and MUST have quotes around it! |
| DYLD_INSERT_LIBRARIES | `/home/steam/valheim/doorstop_libs/libdoorstop_x64.so` | TRUE | Sets which library to load. |
[Odin]: ./odin.md

View File

@@ -2,6 +2,17 @@
Odin is a CLI tool utilized for installing, starting, and stopping [Valheim] servers
#### Odin Specific Environment Variables
> These are set automatically by Odin;
> you DO NOT need to set these and only mess with them if you Know what you are doing.
| Variable | Default | Required | Description |
|--------------------------|------------------------|----------|-------------|
| DEBUG_MODE | `0` | FALSE | Set to `1` if you want a noisy output and to see what Odin is doing.
| ODIN_CONFIG_FILE | `config.json` | FALSE | This file stores start parameters to restart the instance, change if you run multiple container instances on the same host |
| ODIN_WORKING_DIR | `$PWD` | FALSE | Sets the directory you wish to run `odin` commands in and can be used to set where valheim is managed from. |
## Gotchas
- Odin relies on Rust. [Please install Rust](https://www.rust-lang.org/tools/install)

62
docs/webhooks.md Normal file
View File

@@ -0,0 +1,62 @@
# Webhook Configuration
## Environment Variables
| Variable | Default | Required | Description |
|-------------------------------------|------------------------------------|----------|-------------|
| WEBHOOK_URL | `` | FALSE | Supply this to get information regarding your server's status in a webhook or Discord notification! [Click here to learn how to get a webhook url for Discord](https://help.dashe.io/en/articles/2521940-how-to-create-a-discord-webhook-url) |
| WEBHOOK_BROADCAST_MESSAGE | CHANGE_ME | TRUE | You set this. See `odin notify --help` |
| WEBHOOK_UPDATING_MESSAGE | `Server Status: Updating` | FALSE | Set the Updating message of your server |
| WEBHOOK_UPDATE_SUCCESSFUL_MESSAGE | `Server Status: Update Successful` | FALSE | Set the Update Successful message of your server |
| WEBHOOK_UPDATE_FAILED_MESSAGE | `Server Status: Update Failed` | FALSE | Set the Update Failed message of your server |
| WEBHOOK_STARTING_MESSAGE | `Server Status: Starting` | FALSE | Set the Starting message of your server |
| WEBHOOK_START_SUCCESSFUL_MESSAGE | `Server Status: Start Successful` | FALSE | Set the Start Successful message of your server |
| WEBHOOK_START_FAILED_MESSAGE | `Server Status: Start Failed` | FALSE | Set the Start Failed message of your server |
| WEBHOOK_STOPPING_MESSAGE | `Server Status: Stopping` | FALSE | Set the Stopping message of your server |
| WEBHOOK_STOP_SUCCESSFUL_MESSAGE | `Server Status: Stop Successful` | FALSE | Set the Stop Successful message of your server |
| WEBHOOK_STOP_FAILED_MESSAGE | `Server Status: Stop Failed` | FALSE | Set the Stop Failed message of your server |
## POST Body Example
```Json
{
"event_type": {
"name": "Broadcast",
"status": "triggered"
},
"event_message": "Server Status: Broadcast",
"timestamp": "02/22/2021 17:18:04 -08:00"
}
```
| Key | Description |
|-----------------|-------------|
| `event_type.name` | Name of the event |
| `event_type.status` | Status of the event |
| `event_message` | A description of the event. |
| `timestamp` | ISO8601 timestamp |
## Considerations
- The expected HTTP codes returned from the webhook should be either 204 or 201 to be considered successful.
- 204 is the default return http code for a webhook as it signifies the request has been processed.
- 201 was included in case you want to stream into an endpoint for creating a resource.
- Example 1, logging actions on the server.
- Example 2, using json-server to debug webhooks.
## Developing/Debugging Webhooks
1. Start json-server
```shell
docker run --rm -p 3000:3000 vimagick/json-server -H 0.0.0.0 -p 3000 -w db.json
```
2. Run notify against the webhook
```shell
cargo run -- notify "Derp Testing another notification" --webhook "http://127.0.0.1:3000/posts"
```

View File

@@ -82,3 +82,17 @@ subcommands:
about: Sets the output file to use
required: true
index: 2
- notify:
about: Sends a notification to the provided webhook.
version: "1.1"
author: mbround18
args:
- MESSAGE:
about: Message to send to the webhook.
required: true
index: 1
- webhook_url:
long: webhook
value_name: WEBHOOK_URL
about: Sets the webhook to send a notification to, (Can be set with ENV variable WEBHOOK_URL)
takes_value: true

View File

@@ -1,5 +1,6 @@
pub mod backup;
pub mod configure;
pub mod install;
pub mod notify;
pub mod start;
pub mod stop;

15
src/commands/notify.rs Normal file
View File

@@ -0,0 +1,15 @@
use crate::notifications::enums::notification_event::NotificationEvent;
use crate::utils::get_variable;
use clap::ArgMatches;
use log::{error, info};
pub fn invoke(args: &ArgMatches) {
let message = get_variable(&args, "MESSAGE", String::from("Test Notification"));
let webhook_url = get_variable(&args, "webhook_url", "".to_string());
if !webhook_url.is_empty() {
info!("Sending Broadcast: {}", message);
NotificationEvent::Broadcast.send_custom_notification(webhook_url.as_str(), message.as_str())
} else {
error!("Failed to send notification! Webhook url not provided!")
}
}

15
src/errors/mod.rs Normal file
View File

@@ -0,0 +1,15 @@
use std::fmt::Display;
use std::{error, fmt};
#[derive(Debug)]
pub struct VariantNotFound {
pub(crate) v: String,
}
impl error::Error for VariantNotFound {}
impl Display for VariantNotFound {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "VariantNotFound: {}", &self.v)
}
}

View File

@@ -4,15 +4,19 @@ use log::{debug, info, LevelFilter, SetLoggerError};
use crate::executable::handle_exit_status;
use crate::logger::OdinLogger;
use crate::utils::fetch_env;
mod commands;
mod errors;
mod executable;
mod files;
mod logger;
mod messages;
mod notifications;
mod steamcmd;
mod utils;
use crate::notifications::enums::event_status::EventStatus;
use crate::notifications::enums::notification_event::NotificationEvent;
const VERSION: &str = env!("CARGO_PKG_VERSION");
static LOGGER: OdinLogger = OdinLogger;
static GAME_ID: i64 = 896660;
@@ -35,7 +39,6 @@ fn main() {
let matches = app.get_matches();
let debug_mode = matches.is_present("debug") || fetch_env("DEBUG_MODE", "0", false).eq("1");
setup_logger(debug_mode).unwrap();
if !debug_mode {
info!("Run with DEBUG_MODE as 1 if you think there is an issue with Odin");
}
@@ -44,7 +47,7 @@ fn main() {
debug!("Launching configure command...");
commands::configure::invoke(configure_matches);
};
if matches.subcommand_matches("install").is_some() {
if let Some(ref _match) = matches.subcommand_matches("install") {
debug!("Launching install command...");
let result = commands::install::invoke(GAME_ID);
handle_exit_status(result, "Successfully installed Valheim!".to_string())
@@ -52,13 +55,20 @@ fn main() {
if let Some(ref start_matches) = matches.subcommand_matches("start") {
debug!("Launching start command...");
commands::start::invoke(start_matches);
NotificationEvent::Start(EventStatus::Successful).send_notification();
};
if let Some(ref stop_matches) = matches.subcommand_matches("stop") {
debug!("Launching stop command...");
NotificationEvent::Stop(EventStatus::Running).send_notification();
commands::stop::invoke(stop_matches);
NotificationEvent::Stop(EventStatus::Successful).send_notification();
};
if let Some(ref backup_matches) = matches.subcommand_matches("backup") {
debug!("Launching backup command...");
commands::backup::invoke(backup_matches);
};
if let Some(ref notify_matches) = matches.subcommand_matches("notify") {
debug!("Launching notify command...");
commands::notify::invoke(notify_matches);
};
}

View File

@@ -0,0 +1,72 @@
use crate::notifications::EventStatus;
use crate::notifications::NotificationMessage;
use crate::utils::fetch_env;
use inflections::case::to_title_case;
use log::debug;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Debug)]
enum Color {
Success = 0x4B_B5_43,
Failure = 0xFA_11_3D,
Generic = 0x00_7F_66,
}
const DISCORD_WEBHOOK_BASE: &str = "https://discord.com/api/webhooks";
impl From<EventStatus> for Color {
fn from(event: EventStatus) -> Self {
use EventStatus::{Failed, Successful};
match event {
Successful => Self::Success,
Failed => Self::Failure,
_ => Self::Generic,
}
}
}
pub fn is_discord_webhook(webhook_url: &str) -> bool {
webhook_url.starts_with(DISCORD_WEBHOOK_BASE)
}
#[derive(Deserialize, Serialize)]
pub struct DiscordWebHookEmbed {
title: String,
description: String,
color: i32,
}
#[derive(Deserialize, Serialize)]
pub struct DiscordWebHookBody {
content: String,
embeds: Vec<DiscordWebHookEmbed>,
}
impl DiscordWebHookBody {
pub fn new(event: &NotificationMessage) -> Self {
let server_name = fetch_env("NAME", "Your Valheim Server", false);
let status = &event.event_type.status;
let event_status = EventStatus::from_str(status).unwrap_or(EventStatus::Failed);
let color: i32 = Color::from(event_status) as i32;
let payload = DiscordWebHookBody {
content: to_title_case(format!("Notification From: {}", server_name).as_str()),
embeds: vec![DiscordWebHookEmbed {
title: String::from(&event.event_type.name),
description: String::from(&event.event_message),
color,
}],
};
debug!(
"Discord Payload: {}",
serde_json::to_string(&payload).unwrap()
);
payload
}
}
impl From<&NotificationMessage> for DiscordWebHookBody {
fn from(event: &NotificationMessage) -> Self {
Self::new(event)
}
}

View File

@@ -0,0 +1,36 @@
use crate::errors::VariantNotFound;
use serde::{Deserialize, Serialize};
#[derive(PartialEq, Debug, Deserialize, Serialize)]
pub enum EventStatus {
Running,
Successful,
Failed,
}
impl std::str::FromStr for EventStatus {
type Err = VariantNotFound;
fn from_str(s: &str) -> ::std::result::Result<EventStatus, Self::Err> {
use EventStatus::{Failed, Running, Successful};
match s {
"Running" => ::std::result::Result::Ok(Running),
"Successful" => ::std::result::Result::Ok(Successful),
"Failed" => ::std::result::Result::Ok(Failed),
_ => ::std::result::Result::Err(VariantNotFound {
v: String::from("Failed to find Event Status"),
}),
}
}
}
#[cfg(test)]
mod event_status_tests {
use super::*;
use crate::notifications::enums::event_status::EventStatus::Running;
use std::str::FromStr;
#[test]
fn parse_enum_from_string() {
assert_eq!(Running, EventStatus::from_str("Running").unwrap());
}
}

View File

@@ -0,0 +1,2 @@
pub mod event_status;
pub mod notification_event;

View File

@@ -0,0 +1,71 @@
use crate::errors::VariantNotFound;
use crate::notifications::enums::event_status::EventStatus;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(PartialEq, Debug, Deserialize, Serialize)]
pub enum NotificationEvent {
Broadcast,
Update(EventStatus),
Start(EventStatus),
Stop(EventStatus),
}
#[derive(PartialEq, Debug, Deserialize, Serialize)]
pub struct EventType {
pub(crate) name: String,
pub(crate) status: String,
}
impl NotificationEvent {
pub(crate) fn to_event_type(&self) -> EventType {
let event = self.to_string();
let parsed_event: Vec<&str> = event.split(' ').collect();
let name = parsed_event.get(0).unwrap_or(&"EVENT NAME").to_string();
let status = parsed_event.get(1).unwrap_or(&"Triggered").to_string();
EventType { name, status }
}
}
impl fmt::Display for NotificationEvent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let debug = format!("{:?}", self);
let formatted = debug.replace("(", " ").replace(")", "");
f.write_str(&formatted)
}
}
impl std::str::FromStr for NotificationEvent {
type Err = VariantNotFound;
fn from_str(s: &str) -> core::result::Result<NotificationEvent, Self::Err> {
use NotificationEvent::{Broadcast, Start, Stop, Update};
let parts: Vec<&str> = s.split(' ').collect();
let event = parts[0];
if event.eq(Broadcast.to_string().as_str()) {
::std::result::Result::Ok(Broadcast)
} else {
let status = parts[1];
let event_status = EventStatus::from_str(&status).unwrap();
match event {
"Update" => ::std::result::Result::Ok(Update(event_status)),
"Start" => ::std::result::Result::Ok(Start(event_status)),
"Stop" => ::std::result::Result::Ok(Stop(event_status)),
_ => ::std::result::Result::Err(VariantNotFound {
v: String::from("Failed to find Notification Event"),
}),
}
}
}
}
#[cfg(test)]
mod notification_event_tests {
use super::*;
use std::str::FromStr;
use NotificationEvent::Broadcast;
#[test]
fn parse_enum_from_string() {
assert_eq!(NotificationEvent::from_str("Broadcast").unwrap(), Broadcast);
}
}

140
src/notifications/mod.rs Normal file
View File

@@ -0,0 +1,140 @@
use std::env;
use std::env::VarError;
use chrono::prelude::*;
use inflections::case::{to_constant_case, to_title_case};
use log::{debug, error, info};
use reqwest::blocking::RequestBuilder;
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use crate::notifications::discord::{is_discord_webhook, DiscordWebHookBody};
use crate::notifications::enums::event_status::EventStatus;
use crate::notifications::enums::notification_event::{EventType, NotificationEvent};
mod discord;
pub mod enums;
pub const WEBHOOK_URL: &str = "WEBHOOK_URL";
#[derive(Deserialize, Serialize)]
pub struct NotificationMessage {
event_type: EventType,
event_message: String,
timestamp: String,
}
fn fetch_webhook_url() -> Result<String, VarError> {
env::var(WEBHOOK_URL)
}
fn is_webhook_enabled() -> bool {
fetch_webhook_url().is_ok()
}
fn parse_webhook_env_var(event_type: EventType) -> String {
if event_type.name.to_lowercase().eq("broadcast") {
to_constant_case(format!("WEBHOOK_{}_MESSAGE", event_type.name).as_str())
} else {
to_constant_case(format!("WEBHOOK_{}_{}_MESSAGE", event_type.name, event_type.status).as_str())
}
}
impl NotificationEvent {
fn create_notification_message(&self) -> NotificationMessage {
NotificationMessage {
event_type: self.to_event_type(),
event_message: format!(
"Server Status: {}",
to_title_case(self.to_string().as_str())
),
timestamp: Local::now().to_rfc3339(),
}
}
fn handle_request(&self, request: RequestBuilder) {
let response = request.send();
if let Ok(parsed_response) = response {
let response_status = parsed_response.status();
let response_message = parsed_response.text().unwrap();
match response_status.as_u16() {
204 | 201 => info!("[{}]: Webhook message sent successfully!", self),
_ => error!("Request failed! {}, {}", response_status, response_message),
}
} else {
error!(
"[{}]: Error with webhook! Status {}",
self,
response
.err()
.unwrap()
.status()
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
.as_str()
);
}
}
fn build_request(&self, webhook_url: &str) -> RequestBuilder {
let client = reqwest::blocking::Client::new();
debug!("Webhook URL: {}", webhook_url);
client.post(webhook_url)
}
pub fn send_custom_notification(&self, webhook_url: &str, message: &str) {
let mut notification = self.create_notification_message();
notification.event_message = message.to_string();
debug!("Webhook enabled, sending notification {}", self.to_string());
let mut req = self.build_request(webhook_url);
req = if is_discord_webhook(webhook_url) {
info!("Sending discord notification <3");
req.json(&DiscordWebHookBody::from(&notification))
} else {
debug!(
"Webhook Payload: {}",
serde_json::to_string(&notification).unwrap()
);
req.json(&notification)
};
self.handle_request(req);
}
pub fn send_notification(&self) {
if is_webhook_enabled() {
debug!("Webhook found! Starting notification process...");
let event = self.create_notification_message();
let env_var_name = parse_webhook_env_var(event.event_type);
let notification_message = env::var(env_var_name).unwrap_or(event.event_message);
self.send_custom_notification(
fetch_webhook_url().unwrap().replace("\"", "").as_str(),
notification_message.as_str(),
);
} else {
debug!("Skipping notification, no webhook supplied!");
}
}
}
#[cfg(test)]
mod enum_tests {
use inflections::case::to_title_case;
use super::*;
use crate::notifications::enums::event_status::EventStatus;
use crate::notifications::NotificationEvent::Broadcast;
#[test]
fn parse_enum_as_string() {
assert_eq!(to_title_case(Broadcast.to_string().as_str()), "Broadcast");
}
#[test]
fn parse_enum_create_notification() {
let event = NotificationEvent::Stop(EventStatus::Running);
let notification = event.create_notification_message();
assert_eq!(
format!(
"{} {}",
notification.event_type.name, notification.event_type.status
),
event.to_string()
);
assert!(notification.event_message.contains(&event.to_string()));
}
}