integrate reminder sender
This commit is contained in:
		
							
								
								
									
										253
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										253
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -30,9 +30,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "async-trait"
 | 
					name = "async-trait"
 | 
				
			||||||
version = "0.1.51"
 | 
					version = "0.1.52"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e"
 | 
					checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
@@ -41,18 +41,18 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "async-tungstenite"
 | 
					name = "async-tungstenite"
 | 
				
			||||||
version = "0.15.0"
 | 
					version = "0.16.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "742cc7dcb20b2f84a42f4691aa999070ec7e78f8e7e7438bf14be7017b44907e"
 | 
					checksum = "5682ea0913e5c20780fe5785abacb85a411e7437bf52a1bedb93ddb3972cb8dd"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "futures-io",
 | 
					 "futures-io",
 | 
				
			||||||
 "futures-util",
 | 
					 "futures-util",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "tokio-rustls",
 | 
					 "tokio-rustls 0.23.2",
 | 
				
			||||||
 "tungstenite",
 | 
					 "tungstenite",
 | 
				
			||||||
 "webpki-roots",
 | 
					 "webpki-roots 0.22.1",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -216,9 +216,9 @@ checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "crc32fast"
 | 
					name = "crc32fast"
 | 
				
			||||||
version = "1.2.1"
 | 
					version = "1.3.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
 | 
					checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -255,12 +255,13 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "dashmap"
 | 
					name = "dashmap"
 | 
				
			||||||
version = "4.0.2"
 | 
					version = "5.0.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
 | 
					checksum = "b799062aaf67eb976af3bdca031ee6f846d2f0a5710ddbb0d2efee33f3cc4760"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "num_cpus",
 | 
					 "num_cpus",
 | 
				
			||||||
 | 
					 "parking_lot",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -287,9 +288,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "encoding_rs"
 | 
					name = "encoding_rs"
 | 
				
			||||||
version = "0.8.29"
 | 
					version = "0.8.30"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746"
 | 
					checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -397,19 +398,6 @@ version = "0.3.17"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
 | 
					checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "futures-macro"
 | 
					 | 
				
			||||||
version = "0.3.17"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "autocfg 1.0.1",
 | 
					 | 
				
			||||||
 "proc-macro-hack",
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "syn",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "futures-sink"
 | 
					name = "futures-sink"
 | 
				
			||||||
version = "0.3.17"
 | 
					version = "0.3.17"
 | 
				
			||||||
@@ -432,14 +420,11 @@ dependencies = [
 | 
				
			|||||||
 "futures-channel",
 | 
					 "futures-channel",
 | 
				
			||||||
 "futures-core",
 | 
					 "futures-core",
 | 
				
			||||||
 "futures-io",
 | 
					 "futures-io",
 | 
				
			||||||
 "futures-macro",
 | 
					 | 
				
			||||||
 "futures-sink",
 | 
					 "futures-sink",
 | 
				
			||||||
 "futures-task",
 | 
					 "futures-task",
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "pin-utils",
 | 
					 "pin-utils",
 | 
				
			||||||
 "proc-macro-hack",
 | 
					 | 
				
			||||||
 "proc-macro-nested",
 | 
					 | 
				
			||||||
 "slab",
 | 
					 "slab",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -477,9 +462,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "h2"
 | 
					name = "h2"
 | 
				
			||||||
version = "0.3.7"
 | 
					version = "0.3.9"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55"
 | 
					checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "fnv",
 | 
					 "fnv",
 | 
				
			||||||
@@ -544,7 +529,7 @@ checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "fnv",
 | 
					 "fnv",
 | 
				
			||||||
 "itoa",
 | 
					 "itoa 0.4.8",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -566,9 +551,9 @@ checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "httpdate"
 | 
					name = "httpdate"
 | 
				
			||||||
version = "1.0.1"
 | 
					version = "1.0.2"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
 | 
					checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "humantime"
 | 
					name = "humantime"
 | 
				
			||||||
@@ -578,9 +563,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "hyper"
 | 
					name = "hyper"
 | 
				
			||||||
version = "0.14.14"
 | 
					version = "0.14.16"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "2b91bb1f221b6ea1f1e4371216b70f40748774c2fb5971b450c07773fb92d26b"
 | 
					checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "futures-channel",
 | 
					 "futures-channel",
 | 
				
			||||||
@@ -591,7 +576,7 @@ dependencies = [
 | 
				
			|||||||
 "http-body",
 | 
					 "http-body",
 | 
				
			||||||
 "httparse",
 | 
					 "httparse",
 | 
				
			||||||
 "httpdate",
 | 
					 "httpdate",
 | 
				
			||||||
 "itoa",
 | 
					 "itoa 0.4.8",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "socket2",
 | 
					 "socket2",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
@@ -602,17 +587,15 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "hyper-rustls"
 | 
					name = "hyper-rustls"
 | 
				
			||||||
version = "0.22.1"
 | 
					version = "0.23.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
 | 
					checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "futures-util",
 | 
					 "http",
 | 
				
			||||||
 "hyper",
 | 
					 "hyper",
 | 
				
			||||||
 "log",
 | 
					 "rustls 0.20.2",
 | 
				
			||||||
 "rustls",
 | 
					 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "tokio-rustls",
 | 
					 "tokio-rustls 0.23.2",
 | 
				
			||||||
 "webpki",
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -666,9 +649,9 @@ checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "itertools"
 | 
					name = "itertools"
 | 
				
			||||||
version = "0.10.1"
 | 
					version = "0.10.3"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
 | 
					checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "either",
 | 
					 "either",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -679,6 +662,12 @@ version = "0.4.8"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
 | 
					checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "itoa"
 | 
				
			||||||
 | 
					version = "1.0.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "js-sys"
 | 
					name = "js-sys"
 | 
				
			||||||
version = "0.3.55"
 | 
					version = "0.3.55"
 | 
				
			||||||
@@ -705,9 +694,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "libc"
 | 
					name = "libc"
 | 
				
			||||||
version = "0.2.107"
 | 
					version = "0.2.112"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
 | 
					checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "libm"
 | 
					name = "libm"
 | 
				
			||||||
@@ -920,9 +909,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "once_cell"
 | 
					name = "once_cell"
 | 
				
			||||||
version = "1.8.0"
 | 
					version = "1.9.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
 | 
					checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "opaque-debug"
 | 
					name = "opaque-debug"
 | 
				
			||||||
@@ -952,9 +941,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "openssl-sys"
 | 
					name = "openssl-sys"
 | 
				
			||||||
version = "0.9.70"
 | 
					version = "0.9.72"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "c6517987b3f8226b5da3661dad65ff7f300cc59fb5ea8333ca191fc65fde3edf"
 | 
					checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "autocfg 1.0.1",
 | 
					 "autocfg 1.0.1",
 | 
				
			||||||
 "cc",
 | 
					 "cc",
 | 
				
			||||||
@@ -1028,9 +1017,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "pkg-config"
 | 
					name = "pkg-config"
 | 
				
			||||||
version = "0.3.22"
 | 
					version = "0.3.24"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
 | 
					checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ppv-lite86"
 | 
					name = "ppv-lite86"
 | 
				
			||||||
@@ -1038,23 +1027,11 @@ version = "0.2.15"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
 | 
					checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "proc-macro-hack"
 | 
					 | 
				
			||||||
version = "0.5.19"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "proc-macro-nested"
 | 
					 | 
				
			||||||
version = "0.1.7"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "proc-macro2"
 | 
					name = "proc-macro2"
 | 
				
			||||||
version = "1.0.32"
 | 
					version = "1.0.34"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
 | 
					checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "unicode-xid",
 | 
					 "unicode-xid",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -1187,7 +1164,7 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "reminder_rs"
 | 
					name = "reminder_rs"
 | 
				
			||||||
version = "1.6.0-beta2"
 | 
					version = "1.6.0-beta3"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "chrono",
 | 
					 "chrono",
 | 
				
			||||||
@@ -1223,9 +1200,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "reqwest"
 | 
					name = "reqwest"
 | 
				
			||||||
version = "0.11.6"
 | 
					version = "0.11.7"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280"
 | 
					checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
@@ -1246,18 +1223,20 @@ dependencies = [
 | 
				
			|||||||
 "native-tls",
 | 
					 "native-tls",
 | 
				
			||||||
 "percent-encoding",
 | 
					 "percent-encoding",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "rustls",
 | 
					 "rustls 0.20.2",
 | 
				
			||||||
 | 
					 "rustls-pemfile",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
 "serde_urlencoded",
 | 
					 "serde_urlencoded",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "tokio-native-tls",
 | 
					 "tokio-native-tls",
 | 
				
			||||||
 "tokio-rustls",
 | 
					 "tokio-rustls 0.23.2",
 | 
				
			||||||
 | 
					 "tokio-util",
 | 
				
			||||||
 "url",
 | 
					 "url",
 | 
				
			||||||
 "wasm-bindgen",
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 "wasm-bindgen-futures",
 | 
					 "wasm-bindgen-futures",
 | 
				
			||||||
 "web-sys",
 | 
					 "web-sys",
 | 
				
			||||||
 "webpki-roots",
 | 
					 "webpki-roots 0.21.1",
 | 
				
			||||||
 "winreg",
 | 
					 "winreg",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1326,15 +1305,36 @@ dependencies = [
 | 
				
			|||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "ring",
 | 
					 "ring",
 | 
				
			||||||
 "sct",
 | 
					 "sct 0.6.1",
 | 
				
			||||||
 "webpki",
 | 
					 "webpki 0.21.4",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rustls"
 | 
				
			||||||
 | 
					version = "0.20.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "log",
 | 
				
			||||||
 | 
					 "ring",
 | 
				
			||||||
 | 
					 "sct 0.7.0",
 | 
				
			||||||
 | 
					 "webpki 0.22.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rustls-pemfile"
 | 
				
			||||||
 | 
					version = "0.2.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "base64",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ryu"
 | 
					name = "ryu"
 | 
				
			||||||
version = "1.0.5"
 | 
					version = "1.0.9"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
 | 
					checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "schannel"
 | 
					name = "schannel"
 | 
				
			||||||
@@ -1362,6 +1362,16 @@ dependencies = [
 | 
				
			|||||||
 "untrusted",
 | 
					 "untrusted",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "sct"
 | 
				
			||||||
 | 
					version = "0.7.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "ring",
 | 
				
			||||||
 | 
					 "untrusted",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "security-framework"
 | 
					name = "security-framework"
 | 
				
			||||||
version = "2.4.2"
 | 
					version = "2.4.2"
 | 
				
			||||||
@@ -1387,18 +1397,18 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde"
 | 
					name = "serde"
 | 
				
			||||||
version = "1.0.130"
 | 
					version = "1.0.132"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
 | 
					checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "serde_derive",
 | 
					 "serde_derive",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde_derive"
 | 
					name = "serde_derive"
 | 
				
			||||||
version = "1.0.130"
 | 
					version = "1.0.132"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
 | 
					checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
@@ -1407,11 +1417,11 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde_json"
 | 
					name = "serde_json"
 | 
				
			||||||
version = "1.0.69"
 | 
					version = "1.0.73"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
 | 
					checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "itoa",
 | 
					 "itoa 1.0.1",
 | 
				
			||||||
 "ryu",
 | 
					 "ryu",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -1434,7 +1444,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
 | 
					checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "form_urlencoded",
 | 
					 "form_urlencoded",
 | 
				
			||||||
 "itoa",
 | 
					 "itoa 0.4.8",
 | 
				
			||||||
 "ryu",
 | 
					 "ryu",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -1442,7 +1452,7 @@ dependencies = [
 | 
				
			|||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serenity"
 | 
					name = "serenity"
 | 
				
			||||||
version = "0.10.9"
 | 
					version = "0.10.9"
 | 
				
			||||||
source = "git+https://github.com/serenity-rs/serenity?branch=next#8d331b33171739ccecdc902faeefbcc7d32aa0eb"
 | 
					source = "git+https://github.com/serenity-rs/serenity?branch=next#f349db848c16ec0b5f48afd63121573de22d800e"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "async-trait",
 | 
					 "async-trait",
 | 
				
			||||||
 "async-tungstenite",
 | 
					 "async-tungstenite",
 | 
				
			||||||
@@ -1590,7 +1600,7 @@ dependencies = [
 | 
				
			|||||||
 "hashlink",
 | 
					 "hashlink",
 | 
				
			||||||
 "hex",
 | 
					 "hex",
 | 
				
			||||||
 "indexmap",
 | 
					 "indexmap",
 | 
				
			||||||
 "itoa",
 | 
					 "itoa 0.4.8",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
@@ -1600,7 +1610,7 @@ dependencies = [
 | 
				
			|||||||
 "percent-encoding",
 | 
					 "percent-encoding",
 | 
				
			||||||
 "rand 0.8.4",
 | 
					 "rand 0.8.4",
 | 
				
			||||||
 "rsa",
 | 
					 "rsa",
 | 
				
			||||||
 "rustls",
 | 
					 "rustls 0.19.1",
 | 
				
			||||||
 "sha-1",
 | 
					 "sha-1",
 | 
				
			||||||
 "sha2",
 | 
					 "sha2",
 | 
				
			||||||
 "smallvec",
 | 
					 "smallvec",
 | 
				
			||||||
@@ -1610,8 +1620,8 @@ dependencies = [
 | 
				
			|||||||
 "thiserror",
 | 
					 "thiserror",
 | 
				
			||||||
 "tokio-stream",
 | 
					 "tokio-stream",
 | 
				
			||||||
 "url",
 | 
					 "url",
 | 
				
			||||||
 "webpki",
 | 
					 "webpki 0.21.4",
 | 
				
			||||||
 "webpki-roots",
 | 
					 "webpki-roots 0.21.1",
 | 
				
			||||||
 "whoami",
 | 
					 "whoami",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1642,7 +1652,7 @@ checksum = "0d1bd069de53442e7a320f525a6d4deb8bb0621ac7a55f7eccbc2b58b57f43d0"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "tokio-rustls",
 | 
					 "tokio-rustls 0.22.0",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -1663,9 +1673,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "syn"
 | 
					name = "syn"
 | 
				
			||||||
version = "1.0.81"
 | 
					version = "1.0.82"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
 | 
					checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
@@ -1754,11 +1764,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tokio"
 | 
					name = "tokio"
 | 
				
			||||||
version = "1.13.0"
 | 
					version = "1.15.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "588b2d10a336da58d877567cd8fb8a14b463e2104910f8132cd054b4b96e29ee"
 | 
					checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "autocfg 1.0.1",
 | 
					 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
@@ -1774,9 +1783,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tokio-macros"
 | 
					name = "tokio-macros"
 | 
				
			||||||
version = "1.5.1"
 | 
					version = "1.7.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "114383b041aa6212c579467afa0075fbbdd0718de036100bc0ba7961d8cb9095"
 | 
					checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
@@ -1799,9 +1808,20 @@ version = "0.22.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
 | 
					checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "rustls",
 | 
					 "rustls 0.19.1",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "webpki",
 | 
					 "webpki 0.21.4",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "tokio-rustls"
 | 
				
			||||||
 | 
					version = "0.23.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "rustls 0.20.2",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					 "webpki 0.22.0",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -1876,9 +1896,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tungstenite"
 | 
					name = "tungstenite"
 | 
				
			||||||
version = "0.15.0"
 | 
					version = "0.16.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "983d40747bce878d2fb67d910dcb8bd3eca2b2358540c3cc1b98c027407a3ae3"
 | 
					checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "byteorder",
 | 
					 "byteorder",
 | 
				
			||||||
@@ -1887,12 +1907,12 @@ dependencies = [
 | 
				
			|||||||
 "httparse",
 | 
					 "httparse",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "rand 0.8.4",
 | 
					 "rand 0.8.4",
 | 
				
			||||||
 "rustls",
 | 
					 "rustls 0.20.2",
 | 
				
			||||||
 "sha-1",
 | 
					 "sha-1",
 | 
				
			||||||
 "thiserror",
 | 
					 "thiserror",
 | 
				
			||||||
 "url",
 | 
					 "url",
 | 
				
			||||||
 "utf-8",
 | 
					 "utf-8",
 | 
				
			||||||
 "webpki",
 | 
					 "webpki 0.22.0",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -2103,20 +2123,39 @@ dependencies = [
 | 
				
			|||||||
 "untrusted",
 | 
					 "untrusted",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "webpki"
 | 
				
			||||||
 | 
					version = "0.22.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "ring",
 | 
				
			||||||
 | 
					 "untrusted",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "webpki-roots"
 | 
					name = "webpki-roots"
 | 
				
			||||||
version = "0.21.1"
 | 
					version = "0.21.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
 | 
					checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "webpki",
 | 
					 "webpki 0.21.4",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "webpki-roots"
 | 
				
			||||||
 | 
					version = "0.22.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c475786c6f47219345717a043a37ec04cb4bc185e28853adcc4fa0a947eba630"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "webpki 0.22.0",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "whoami"
 | 
					name = "whoami"
 | 
				
			||||||
version = "1.2.0"
 | 
					version = "1.2.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "c33ac5ee236a4efbf2c98967e12c6cc0c51d93a744159a52957ba206ae6ef5f7"
 | 
					checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "wasm-bindgen",
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 "web-sys",
 | 
					 "web-sys",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "reminder_rs"
 | 
					name = "reminder_rs"
 | 
				
			||||||
version = "1.6.0-beta2"
 | 
					version = "1.6.0-beta3"
 | 
				
			||||||
authors = ["jellywx <judesouthworth@pm.me>"]
 | 
					authors = ["jellywx <judesouthworth@pm.me>"]
 | 
				
			||||||
edition = "2018"
 | 
					edition = "2018"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,4 +41,3 @@ __Other Variables__
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
* Convert aliases to macros
 | 
					* Convert aliases to macros
 | 
				
			||||||
* Help command
 | 
					* Help command
 | 
				
			||||||
* Test everything
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -322,7 +322,7 @@ async fn look(ctx: &Context, invoke: &mut CommandInvoke, args: CommandOptions) {
 | 
				
			|||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .map(|reminder| reminder.display(&flags, &timezone))
 | 
					            .map(|reminder| reminder.display(&flags, &timezone))
 | 
				
			||||||
            .fold(0, |t, r| t + r.len())
 | 
					            .fold(0, |t, r| t + r.len())
 | 
				
			||||||
            .div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
 | 
					            .div_ceil(&EMBED_DESCRIPTION_MAX_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let pager = LookPager::new(flags, timezone);
 | 
					        let pager = LookPager::new(flags, timezone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ pub(crate) mod pager;
 | 
				
			|||||||
use std::io::Cursor;
 | 
					use std::io::Cursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use chrono_tz::Tz;
 | 
					use chrono_tz::Tz;
 | 
				
			||||||
 | 
					use num_integer::Integer;
 | 
				
			||||||
use rmp_serde::Serializer;
 | 
					use rmp_serde::Serializer;
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
use serenity::{
 | 
					use serenity::{
 | 
				
			||||||
@@ -78,7 +79,7 @@ impl ComponentDataModel {
 | 
				
			|||||||
                    .iter()
 | 
					                    .iter()
 | 
				
			||||||
                    .map(|reminder| reminder.display(&flags, &pager.timezone))
 | 
					                    .map(|reminder| reminder.display(&flags, &pager.timezone))
 | 
				
			||||||
                    .fold(0, |t, r| t + r.len())
 | 
					                    .fold(0, |t, r| t + r.len())
 | 
				
			||||||
                    .div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
 | 
					                    .div_ceil(&EMBED_DESCRIPTION_MAX_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let channel_name =
 | 
					                let channel_name =
 | 
				
			||||||
                    if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
 | 
					                    if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,11 @@ use regex::Regex;
 | 
				
			|||||||
use serenity::http::AttachmentType;
 | 
					use serenity::http::AttachmentType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lazy_static! {
 | 
					lazy_static! {
 | 
				
			||||||
 | 
					    pub static ref REMIND_INTERVAL: u64 = env::var("REMIND_INTERVAL")
 | 
				
			||||||
 | 
					        .map(|inner| inner.parse::<u64>().ok())
 | 
				
			||||||
 | 
					        .ok()
 | 
				
			||||||
 | 
					        .flatten()
 | 
				
			||||||
 | 
					        .unwrap_or(10);
 | 
				
			||||||
    pub static ref DEFAULT_AVATAR: AttachmentType<'static> = (
 | 
					    pub static ref DEFAULT_AVATAR: AttachmentType<'static> = (
 | 
				
			||||||
        include_bytes!(concat!(
 | 
					        include_bytes!(concat!(
 | 
				
			||||||
            env!("CARGO_MANIFEST_DIR"),
 | 
					            env!("CARGO_MANIFEST_DIR"),
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										62
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -8,9 +8,17 @@ mod consts;
 | 
				
			|||||||
mod framework;
 | 
					mod framework;
 | 
				
			||||||
mod hooks;
 | 
					mod hooks;
 | 
				
			||||||
mod models;
 | 
					mod models;
 | 
				
			||||||
 | 
					mod sender;
 | 
				
			||||||
mod time_parser;
 | 
					mod time_parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::{collections::HashMap, env, sync::Arc};
 | 
					use std::{
 | 
				
			||||||
 | 
					    collections::HashMap,
 | 
				
			||||||
 | 
					    env,
 | 
				
			||||||
 | 
					    sync::{
 | 
				
			||||||
 | 
					        atomic::{AtomicBool, Ordering},
 | 
				
			||||||
 | 
					        Arc,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use chrono_tz::Tz;
 | 
					use chrono_tz::Tz;
 | 
				
			||||||
use dotenv::dotenv;
 | 
					use dotenv::dotenv;
 | 
				
			||||||
@@ -30,12 +38,15 @@ use serenity::{
 | 
				
			|||||||
    utils::shard_id,
 | 
					    utils::shard_id,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use sqlx::mysql::MySqlPool;
 | 
					use sqlx::mysql::MySqlPool;
 | 
				
			||||||
use tokio::sync::RwLock;
 | 
					use tokio::{
 | 
				
			||||||
 | 
					    sync::RwLock,
 | 
				
			||||||
 | 
					    time::{Duration, Instant},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    commands::{info_cmds, moderation_cmds, reminder_cmds, todo_cmds},
 | 
					    commands::{info_cmds, moderation_cmds, reminder_cmds, todo_cmds},
 | 
				
			||||||
    component_models::ComponentDataModel,
 | 
					    component_models::ComponentDataModel,
 | 
				
			||||||
    consts::{CNC_GUILD, SUBSCRIPTION_ROLES, THEME_COLOR},
 | 
					    consts::{CNC_GUILD, SUBSCRIPTION_ROLES, THEME_COLOR, REMIND_INTERVAL},
 | 
				
			||||||
    framework::RegexFramework,
 | 
					    framework::RegexFramework,
 | 
				
			||||||
    models::command_macro::CommandMacro,
 | 
					    models::command_macro::CommandMacro,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -64,10 +75,45 @@ impl TypeMapKey for RecordingMacros {
 | 
				
			|||||||
    type Value = Arc<RwLock<HashMap<(GuildId, UserId), CommandMacro>>>;
 | 
					    type Value = Arc<RwLock<HashMap<(GuildId, UserId), CommandMacro>>>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Handler;
 | 
					struct Handler {
 | 
				
			||||||
 | 
					    is_loop_running: AtomicBool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[async_trait]
 | 
					#[async_trait]
 | 
				
			||||||
impl EventHandler for Handler {
 | 
					impl EventHandler for Handler {
 | 
				
			||||||
 | 
					    async fn cache_ready(&self, ctx_base: Context, _guilds: Vec<GuildId>) {
 | 
				
			||||||
 | 
					        info!("Cache Ready!");
 | 
				
			||||||
 | 
					        info!("Preparing to send reminders");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if !self.is_loop_running.load(Ordering::Relaxed) {
 | 
				
			||||||
 | 
					            let ctx = ctx_base.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tokio::spawn(async move {
 | 
				
			||||||
 | 
					                let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                loop {
 | 
				
			||||||
 | 
					                    let sleep_until = Instant::now() + Duration::from_secs(*REMIND_INTERVAL);
 | 
				
			||||||
 | 
					                    let reminders = sender::Reminder::fetch_reminders(&pool).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if reminders.len() > 0 {
 | 
				
			||||||
 | 
					                        info!("=================================================");
 | 
				
			||||||
 | 
					                        info!("Preparing to send {} reminders:", reminders.len());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        for reminder in reminders {
 | 
				
			||||||
 | 
					                            info!("Sending {:?}", reminder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            reminder.send(pool.clone(), ctx.clone()).await;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    tokio::time::sleep_until(sleep_until).await;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.is_loop_running.swap(true, Ordering::Relaxed);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn channel_delete(&self, ctx: Context, channel: &GuildChannel) {
 | 
					    async fn channel_delete(&self, ctx: Context, channel: &GuildChannel) {
 | 
				
			||||||
        let pool = ctx
 | 
					        let pool = ctx
 | 
				
			||||||
            .data
 | 
					            .data
 | 
				
			||||||
@@ -185,9 +231,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let token = env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment");
 | 
					    let token = env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let http = Http::new_with_token(&token);
 | 
					    let application_id = {
 | 
				
			||||||
 | 
					        let http = Http::new_with_token(&token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let application_id = http.get_current_application_info().await?.id;
 | 
					        http.get_current_application_info().await?.id
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let dm_enabled = env::var("DM_ENABLED").map_or(true, |var| var == "1");
 | 
					    let dm_enabled = env::var("DM_ENABLED").map_or(true, |var| var == "1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -225,7 +273,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
 | 
				
			|||||||
    let mut client = Client::builder(&token)
 | 
					    let mut client = Client::builder(&token)
 | 
				
			||||||
        .intents(GatewayIntents::GUILDS)
 | 
					        .intents(GatewayIntents::GUILDS)
 | 
				
			||||||
        .application_id(application_id.0)
 | 
					        .application_id(application_id.0)
 | 
				
			||||||
        .event_handler(Handler)
 | 
					        .event_handler(Handler { is_loop_running: AtomicBool::from(false) })
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .expect("Error occurred creating client");
 | 
					        .expect("Error occurred creating client");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										557
									
								
								src/sender.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										557
									
								
								src/sender.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,557 @@
 | 
				
			|||||||
 | 
					use chrono::Duration;
 | 
				
			||||||
 | 
					use log::{error, info, warn};
 | 
				
			||||||
 | 
					use serenity::{
 | 
				
			||||||
 | 
					    builder::CreateEmbed,
 | 
				
			||||||
 | 
					    http::{CacheHttp, Http, StatusCode},
 | 
				
			||||||
 | 
					    model::{channel::Embed as SerenityEmbed, id::ChannelId, webhook::Webhook},
 | 
				
			||||||
 | 
					    Error, Result,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use sqlx::{
 | 
				
			||||||
 | 
					    types::chrono::{NaiveDateTime, Utc},
 | 
				
			||||||
 | 
					    MySqlPool,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use chrono_tz::Tz;
 | 
				
			||||||
 | 
					use num_integer::Integer;
 | 
				
			||||||
 | 
					use regex::{Captures, Regex};
 | 
				
			||||||
 | 
					use serenity::model::channel::Channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lazy_static! {
 | 
				
			||||||
 | 
					    pub static ref TIMEFROM_REGEX: Regex =
 | 
				
			||||||
 | 
					        Regex::new(r#"<<timefrom:(?P<time>\d+):(?P<format>.+)?>>"#).unwrap();
 | 
				
			||||||
 | 
					    pub static ref TIMENOW_REGEX: Regex =
 | 
				
			||||||
 | 
					        Regex::new(r#"<<timenow:(?P<timezone>(?:\w|/|_)+):(?P<format>.+)?>>"#).unwrap();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn fmt_displacement(format: &str, seconds: u64) -> String {
 | 
				
			||||||
 | 
					    let mut seconds = seconds;
 | 
				
			||||||
 | 
					    let mut days: u64 = 0;
 | 
				
			||||||
 | 
					    let mut hours: u64 = 0;
 | 
				
			||||||
 | 
					    let mut minutes: u64 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (rep, time_type, div) in [
 | 
				
			||||||
 | 
					        ("%d", &mut days, 86400),
 | 
				
			||||||
 | 
					        ("%h", &mut hours, 3600),
 | 
				
			||||||
 | 
					        ("%m", &mut minutes, 60),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    .iter_mut()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if format.contains(*rep) {
 | 
				
			||||||
 | 
					            let (divided, new_seconds) = seconds.div_rem(&div);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            **time_type = divided;
 | 
				
			||||||
 | 
					            seconds = new_seconds;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    format
 | 
				
			||||||
 | 
					        .replace("%s", &seconds.to_string())
 | 
				
			||||||
 | 
					        .replace("%m", &minutes.to_string())
 | 
				
			||||||
 | 
					        .replace("%h", &hours.to_string())
 | 
				
			||||||
 | 
					        .replace("%d", &days.to_string())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn substitute(string: &str) -> String {
 | 
				
			||||||
 | 
					    let new = TIMEFROM_REGEX.replace(string, |caps: &Captures| {
 | 
				
			||||||
 | 
					        let final_time = caps.name("time").unwrap().as_str();
 | 
				
			||||||
 | 
					        let format = caps.name("format").unwrap().as_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Ok(final_time) = final_time.parse::<i64>() {
 | 
				
			||||||
 | 
					            let dt = NaiveDateTime::from_timestamp(final_time, 0);
 | 
				
			||||||
 | 
					            let now = Utc::now().naive_utc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let difference = {
 | 
				
			||||||
 | 
					                if now < dt {
 | 
				
			||||||
 | 
					                    dt - Utc::now().naive_utc()
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    Utc::now().naive_utc() - dt
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fmt_displacement(format, difference.num_seconds() as u64)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            String::new()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TIMENOW_REGEX
 | 
				
			||||||
 | 
					        .replace(&new, |caps: &Captures| {
 | 
				
			||||||
 | 
					            let timezone = caps.name("timezone").unwrap().as_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            println!("{}", timezone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if let Ok(tz) = timezone.parse::<Tz>() {
 | 
				
			||||||
 | 
					                let format = caps.name("format").unwrap().as_str();
 | 
				
			||||||
 | 
					                let now = Utc::now().with_timezone(&tz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                now.format(format).to_string()
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                String::new()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .to_string()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Embed {
 | 
				
			||||||
 | 
					    inner: EmbedInner,
 | 
				
			||||||
 | 
					    fields: Vec<EmbedField>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct EmbedInner {
 | 
				
			||||||
 | 
					    title: String,
 | 
				
			||||||
 | 
					    description: String,
 | 
				
			||||||
 | 
					    image_url: Option<String>,
 | 
				
			||||||
 | 
					    thumbnail_url: Option<String>,
 | 
				
			||||||
 | 
					    footer: String,
 | 
				
			||||||
 | 
					    footer_url: Option<String>,
 | 
				
			||||||
 | 
					    author: String,
 | 
				
			||||||
 | 
					    author_url: Option<String>,
 | 
				
			||||||
 | 
					    color: u32,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct EmbedField {
 | 
				
			||||||
 | 
					    title: String,
 | 
				
			||||||
 | 
					    value: String,
 | 
				
			||||||
 | 
					    inline: bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Embed {
 | 
				
			||||||
 | 
					    pub async fn from_id(pool: &MySqlPool, id: u32) -> Option<Self> {
 | 
				
			||||||
 | 
					        let mut inner = sqlx::query_as_unchecked!(
 | 
				
			||||||
 | 
					            EmbedInner,
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					SELECT
 | 
				
			||||||
 | 
					    `embed_title` AS title,
 | 
				
			||||||
 | 
					    `embed_description` AS description,
 | 
				
			||||||
 | 
					    `embed_image_url` AS image_url,
 | 
				
			||||||
 | 
					    `embed_thumbnail_url` AS thumbnail_url,
 | 
				
			||||||
 | 
					    `embed_footer` AS footer,
 | 
				
			||||||
 | 
					    `embed_footer_url` AS footer_url,
 | 
				
			||||||
 | 
					    `embed_author` AS author,
 | 
				
			||||||
 | 
					    `embed_author_url` AS author_url,
 | 
				
			||||||
 | 
					    `embed_color` AS color
 | 
				
			||||||
 | 
					FROM
 | 
				
			||||||
 | 
					    reminders
 | 
				
			||||||
 | 
					WHERE
 | 
				
			||||||
 | 
					    `id` = ?
 | 
				
			||||||
 | 
					            ",
 | 
				
			||||||
 | 
					            id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .fetch_one(&pool.clone())
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inner.title = substitute(&inner.title);
 | 
				
			||||||
 | 
					        inner.description = substitute(&inner.description);
 | 
				
			||||||
 | 
					        inner.footer = substitute(&inner.footer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut fields = sqlx::query_as_unchecked!(
 | 
				
			||||||
 | 
					            EmbedField,
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					SELECT
 | 
				
			||||||
 | 
					    title,
 | 
				
			||||||
 | 
					    value,
 | 
				
			||||||
 | 
					    inline
 | 
				
			||||||
 | 
					FROM
 | 
				
			||||||
 | 
					    embed_fields
 | 
				
			||||||
 | 
					WHERE
 | 
				
			||||||
 | 
					    reminder_id = ?
 | 
				
			||||||
 | 
					            ",
 | 
				
			||||||
 | 
					            id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .fetch_all(pool)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fields.iter_mut().for_each(|mut field| {
 | 
				
			||||||
 | 
					            field.title = substitute(&field.title);
 | 
				
			||||||
 | 
					            field.value = substitute(&field.value);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let e = Embed { inner, fields };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if e.has_content() {
 | 
				
			||||||
 | 
					            Some(e)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            None
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn has_content(&self) -> bool {
 | 
				
			||||||
 | 
					        if self.inner.title.is_empty()
 | 
				
			||||||
 | 
					            && self.inner.description.is_empty()
 | 
				
			||||||
 | 
					            && self.inner.image_url.is_none()
 | 
				
			||||||
 | 
					            && self.inner.thumbnail_url.is_none()
 | 
				
			||||||
 | 
					            && self.inner.footer.is_empty()
 | 
				
			||||||
 | 
					            && self.inner.footer_url.is_none()
 | 
				
			||||||
 | 
					            && self.inner.author.is_empty()
 | 
				
			||||||
 | 
					            && self.inner.author_url.is_none()
 | 
				
			||||||
 | 
					            && self.fields.is_empty()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            false
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Into<CreateEmbed> for Embed {
 | 
				
			||||||
 | 
					    fn into(self) -> CreateEmbed {
 | 
				
			||||||
 | 
					        let mut c = CreateEmbed::default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        c.title(&self.inner.title)
 | 
				
			||||||
 | 
					            .description(&self.inner.description)
 | 
				
			||||||
 | 
					            .color(self.inner.color)
 | 
				
			||||||
 | 
					            .author(|a| {
 | 
				
			||||||
 | 
					                a.name(&self.inner.author);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if let Some(author_icon) = &self.inner.author_url {
 | 
				
			||||||
 | 
					                    a.icon_url(author_icon);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                a
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .footer(|f| {
 | 
				
			||||||
 | 
					                f.text(&self.inner.footer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if let Some(footer_icon) = &self.inner.footer_url {
 | 
				
			||||||
 | 
					                    f.icon_url(footer_icon);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                f
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for field in &self.fields {
 | 
				
			||||||
 | 
					            c.field(&field.title, &field.value, field.inline);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(image_url) = &self.inner.image_url {
 | 
				
			||||||
 | 
					            c.image(image_url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(thumbnail_url) = &self.inner.thumbnail_url {
 | 
				
			||||||
 | 
					            c.thumbnail(thumbnail_url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        c
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct Reminder {
 | 
				
			||||||
 | 
					    id: u32,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    channel_id: u64,
 | 
				
			||||||
 | 
					    webhook_id: Option<u64>,
 | 
				
			||||||
 | 
					    webhook_token: Option<String>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    channel_paused: bool,
 | 
				
			||||||
 | 
					    channel_paused_until: Option<NaiveDateTime>,
 | 
				
			||||||
 | 
					    enabled: bool,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tts: bool,
 | 
				
			||||||
 | 
					    pin: bool,
 | 
				
			||||||
 | 
					    content: String,
 | 
				
			||||||
 | 
					    attachment: Option<Vec<u8>>,
 | 
				
			||||||
 | 
					    attachment_name: Option<String>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    utc_time: NaiveDateTime,
 | 
				
			||||||
 | 
					    timezone: String,
 | 
				
			||||||
 | 
					    restartable: bool,
 | 
				
			||||||
 | 
					    expires: Option<NaiveDateTime>,
 | 
				
			||||||
 | 
					    interval: Option<u32>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    avatar: Option<String>,
 | 
				
			||||||
 | 
					    username: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Reminder {
 | 
				
			||||||
 | 
					    pub async fn fetch_reminders(pool: &MySqlPool) -> Vec<Self> {
 | 
				
			||||||
 | 
					        sqlx::query_as_unchecked!(
 | 
				
			||||||
 | 
					            Reminder,
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					SELECT
 | 
				
			||||||
 | 
					    reminders.`id` AS id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    channels.`channel` AS channel_id,
 | 
				
			||||||
 | 
					    channels.`webhook_id` AS webhook_id,
 | 
				
			||||||
 | 
					    channels.`webhook_token` AS webhook_token,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    channels.`paused` AS channel_paused,
 | 
				
			||||||
 | 
					    channels.`paused_until` AS channel_paused_until,
 | 
				
			||||||
 | 
					    reminders.`enabled` AS enabled,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reminders.`tts` AS tts,
 | 
				
			||||||
 | 
					    reminders.`pin` AS pin,
 | 
				
			||||||
 | 
					    reminders.`content` AS content,
 | 
				
			||||||
 | 
					    reminders.`attachment` AS attachment,
 | 
				
			||||||
 | 
					    reminders.`attachment_name` AS attachment_name,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reminders.`utc_time` AS 'utc_time',
 | 
				
			||||||
 | 
					    reminders.`timezone` AS timezone,
 | 
				
			||||||
 | 
					    reminders.`restartable` AS restartable,
 | 
				
			||||||
 | 
					    reminders.`expires` AS expires,
 | 
				
			||||||
 | 
					    reminders.`interval` AS 'interval',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reminders.`avatar` AS avatar,
 | 
				
			||||||
 | 
					    reminders.`username` AS username
 | 
				
			||||||
 | 
					FROM
 | 
				
			||||||
 | 
					    reminders
 | 
				
			||||||
 | 
					INNER JOIN
 | 
				
			||||||
 | 
					    channels
 | 
				
			||||||
 | 
					ON
 | 
				
			||||||
 | 
					    reminders.channel_id = channels.id
 | 
				
			||||||
 | 
					WHERE
 | 
				
			||||||
 | 
					    reminders.`utc_time` < NOW()
 | 
				
			||||||
 | 
					            ",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .fetch_all(pool)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap()
 | 
				
			||||||
 | 
					        .into_iter()
 | 
				
			||||||
 | 
					        .map(|mut rem| {
 | 
				
			||||||
 | 
					            rem.content = substitute(&rem.content);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            rem
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .collect::<Vec<Self>>()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn reset_webhook(&self, pool: &MySqlPool) {
 | 
				
			||||||
 | 
					        let _ = sqlx::query!(
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?
 | 
				
			||||||
 | 
					            ",
 | 
				
			||||||
 | 
					            self.channel_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .execute(pool)
 | 
				
			||||||
 | 
					        .await;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn refresh(&self, pool: &MySqlPool) {
 | 
				
			||||||
 | 
					        if let Some(interval) = self.interval {
 | 
				
			||||||
 | 
					            let now = Utc::now().naive_local();
 | 
				
			||||||
 | 
					            let mut updated_reminder_time = self.utc_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while updated_reminder_time < now {
 | 
				
			||||||
 | 
					                updated_reminder_time += Duration::seconds(interval as i64);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if self.expires.map_or(false, |expires| {
 | 
				
			||||||
 | 
					                NaiveDateTime::from_timestamp(updated_reminder_time.timestamp(), 0) > expires
 | 
				
			||||||
 | 
					            }) {
 | 
				
			||||||
 | 
					                self.force_delete(pool).await;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                sqlx::query!(
 | 
				
			||||||
 | 
					                    "
 | 
				
			||||||
 | 
					UPDATE reminders SET `utc_time` = ? WHERE `id` = ?
 | 
				
			||||||
 | 
					                    ",
 | 
				
			||||||
 | 
					                    updated_reminder_time,
 | 
				
			||||||
 | 
					                    self.id
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .execute(pool)
 | 
				
			||||||
 | 
					                .await
 | 
				
			||||||
 | 
					                .expect(&format!("Could not update time on Reminder {}", self.id));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.force_delete(pool).await;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn force_delete(&self, pool: &MySqlPool) {
 | 
				
			||||||
 | 
					        sqlx::query!(
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					DELETE FROM reminders WHERE `id` = ?
 | 
				
			||||||
 | 
					            ",
 | 
				
			||||||
 | 
					            self.id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .execute(pool)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .expect(&format!("Could not delete Reminder {}", self.id));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn pin_message<M: Into<u64>>(&self, message_id: M, http: impl AsRef<Http>) {
 | 
				
			||||||
 | 
					        let _ = http.as_ref().pin_message(self.channel_id, message_id.into(), None).await;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn send(&self, pool: MySqlPool, cache_http: impl CacheHttp) {
 | 
				
			||||||
 | 
					        async fn send_to_channel(
 | 
				
			||||||
 | 
					            cache_http: impl CacheHttp,
 | 
				
			||||||
 | 
					            reminder: &Reminder,
 | 
				
			||||||
 | 
					            embed: Option<CreateEmbed>,
 | 
				
			||||||
 | 
					        ) -> Result<()> {
 | 
				
			||||||
 | 
					            let channel = ChannelId(reminder.channel_id).to_channel(&cache_http).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            match channel {
 | 
				
			||||||
 | 
					                Ok(Channel::Guild(channel)) => {
 | 
				
			||||||
 | 
					                    match channel
 | 
				
			||||||
 | 
					                        .send_message(&cache_http, |m| {
 | 
				
			||||||
 | 
					                            m.content(&reminder.content).tts(reminder.tts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            if let (Some(attachment), Some(name)) =
 | 
				
			||||||
 | 
					                                (&reminder.attachment, &reminder.attachment_name)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                m.add_file((attachment as &[u8], name.as_str()));
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            if let Some(embed) = embed {
 | 
				
			||||||
 | 
					                                m.set_embed(embed);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            m
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                        .await
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Ok(m) => {
 | 
				
			||||||
 | 
					                            if reminder.pin {
 | 
				
			||||||
 | 
					                                reminder.pin_message(m.id, cache_http.http()).await;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            Ok(())
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        Err(e) => Err(e),
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Ok(Channel::Private(channel)) => {
 | 
				
			||||||
 | 
					                    match channel
 | 
				
			||||||
 | 
					                        .send_message(&cache_http.http(), |m| {
 | 
				
			||||||
 | 
					                            m.content(&reminder.content).tts(reminder.tts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            if let (Some(attachment), Some(name)) =
 | 
				
			||||||
 | 
					                                (&reminder.attachment, &reminder.attachment_name)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                m.add_file((attachment as &[u8], name.as_str()));
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            if let Some(embed) = embed {
 | 
				
			||||||
 | 
					                                m.set_embed(embed);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            m
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                        .await
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Ok(m) => {
 | 
				
			||||||
 | 
					                            if reminder.pin {
 | 
				
			||||||
 | 
					                                reminder.pin_message(m.id, cache_http.http()).await;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            Ok(())
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        Err(e) => Err(e),
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Err(e) => {
 | 
				
			||||||
 | 
					                    Err(e)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                _ => {
 | 
				
			||||||
 | 
					                    Err(Error::Other("Channel not of valid type"))
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async fn send_to_webhook(
 | 
				
			||||||
 | 
					            cache_http: impl CacheHttp,
 | 
				
			||||||
 | 
					            reminder: &Reminder,
 | 
				
			||||||
 | 
					            webhook: Webhook,
 | 
				
			||||||
 | 
					            embed: Option<CreateEmbed>,
 | 
				
			||||||
 | 
					        ) -> Result<()> {
 | 
				
			||||||
 | 
					            match webhook
 | 
				
			||||||
 | 
					                .execute(&cache_http.http(), reminder.pin || reminder.restartable, |w| {
 | 
				
			||||||
 | 
					                    w.content(&reminder.content).tts(reminder.tts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if let Some(username) = &reminder.username {
 | 
				
			||||||
 | 
					                        w.username(username);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if let Some(avatar) = &reminder.avatar {
 | 
				
			||||||
 | 
					                        w.avatar_url(avatar);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if let (Some(attachment), Some(name)) =
 | 
				
			||||||
 | 
					                        (&reminder.attachment, &reminder.attachment_name)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        w.add_file((attachment as &[u8], name.as_str()));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if let Some(embed) = embed {
 | 
				
			||||||
 | 
					                        w.embeds(vec![SerenityEmbed::fake(|c| {
 | 
				
			||||||
 | 
					                            *c = embed;
 | 
				
			||||||
 | 
					                            c
 | 
				
			||||||
 | 
					                        })]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    w
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .await
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Ok(m) => {
 | 
				
			||||||
 | 
					                    if reminder.pin {
 | 
				
			||||||
 | 
					                        if let Some(message) = m {
 | 
				
			||||||
 | 
					                            reminder.pin_message(message.id, cache_http.http()).await;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Ok(())
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Err(e) => Err(e),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.enabled
 | 
				
			||||||
 | 
					            && !(self.channel_paused
 | 
				
			||||||
 | 
					                && self
 | 
				
			||||||
 | 
					                    .channel_paused_until
 | 
				
			||||||
 | 
					                    .map_or(true, |inner| inner >= Utc::now().naive_local()))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let _ = sqlx::query!(
 | 
				
			||||||
 | 
					                "
 | 
				
			||||||
 | 
					UPDATE `channels` SET paused = 0, paused_until = NULL WHERE `channel` = ?
 | 
				
			||||||
 | 
					                ",
 | 
				
			||||||
 | 
					                self.channel_id
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .execute(&pool.clone())
 | 
				
			||||||
 | 
					            .await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let embed = Embed::from_id(&pool.clone(), self.id).await.map(|e| e.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let result = if let (Some(webhook_id), Some(webhook_token)) =
 | 
				
			||||||
 | 
					                (self.webhook_id, &self.webhook_token)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                let webhook_res = cache_http.http().get_webhook_with_token(webhook_id, webhook_token).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if let Ok(webhook) = webhook_res {
 | 
				
			||||||
 | 
					                    send_to_webhook(cache_http, &self, webhook, embed).await
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    warn!("Webhook vanished: {:?}", webhook_res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    self.reset_webhook(&pool.clone()).await;
 | 
				
			||||||
 | 
					                    send_to_channel(cache_http, &self, embed).await
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                send_to_channel(cache_http, &self, embed).await
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if let Err(e) = result {
 | 
				
			||||||
 | 
					                error!("Error sending {:?}: {:?}", self, e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if let Error::Http(error) = e {
 | 
				
			||||||
 | 
					                    if error.status_code() == Some(StatusCode::from_u16(404).unwrap()) {
 | 
				
			||||||
 | 
					                        error!("Seeing channel is deleted. Removing reminder");
 | 
				
			||||||
 | 
					                        self.force_delete(&pool).await;
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        self.refresh(&pool).await;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    self.refresh(&pool).await;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                self.refresh(&pool).await;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            info!("Reminder {} is paused", self.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.refresh(&pool).await;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user