aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-13 01:24:10 +0200
committersalmonik <salmonik@tuta.io>2026-08-13 01:24:10 +0200
commit710f616c05983f4b92944e05ad9dd485e1cdb121 (patch)
tree892b209032575246abc5e2a66eed856c95b28c3c
downloadtimeoutinator-710f616c05983f4b92944e05ad9dd485e1cdb121.tar.gz
timeoutinator-710f616c05983f4b92944e05ad9dd485e1cdb121.zip
init
-rw-r--r--.env.example4
-rw-r--r--.gitignore2
-rw-r--r--Cargo.lock1991
-rw-r--r--Cargo.toml18
-rw-r--r--README.md64
-rw-r--r--src/main.rs275
6 files changed, 2354 insertions, 0 deletions
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..38fa058
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,4 @@
1DISCORD_TOKEN=your-bot-token-here
2TARGET_CHANNEL_ID=123456789012345678
3TIMEOUT_MINUTES=60
4PURGE_HOURS=24
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fedaa2b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
1/target
2.env
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..1752dcd
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,1991 @@
1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing.
3version = 4
4
5[[package]]
6name = "adler2"
7version = "2.0.1"
8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
10
11[[package]]
12name = "android_system_properties"
13version = "0.1.6"
14source = "registry+https://github.com/rust-lang/crates.io-index"
15checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc"
16dependencies = [
17 "libc",
18]
19
20[[package]]
21name = "arrayvec"
22version = "0.7.8"
23source = "registry+https://github.com/rust-lang/crates.io-index"
24checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
25dependencies = [
26 "serde",
27]
28
29[[package]]
30name = "async-trait"
31version = "0.1.92"
32source = "registry+https://github.com/rust-lang/crates.io-index"
33checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
34dependencies = [
35 "proc-macro2",
36 "quote",
37 "syn 3.0.3",
38]
39
40[[package]]
41name = "atomic-waker"
42version = "1.1.2"
43source = "registry+https://github.com/rust-lang/crates.io-index"
44checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
45
46[[package]]
47name = "autocfg"
48version = "1.5.1"
49source = "registry+https://github.com/rust-lang/crates.io-index"
50checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
51
52[[package]]
53name = "base64"
54version = "0.22.1"
55source = "registry+https://github.com/rust-lang/crates.io-index"
56checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
57
58[[package]]
59name = "bitflags"
60version = "2.13.1"
61source = "registry+https://github.com/rust-lang/crates.io-index"
62checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
63
64[[package]]
65name = "block-buffer"
66version = "0.10.4"
67source = "registry+https://github.com/rust-lang/crates.io-index"
68checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
69dependencies = [
70 "generic-array",
71]
72
73[[package]]
74name = "bumpalo"
75version = "3.20.3"
76source = "registry+https://github.com/rust-lang/crates.io-index"
77checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
78
79[[package]]
80name = "byteorder"
81version = "1.5.0"
82source = "registry+https://github.com/rust-lang/crates.io-index"
83checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
84
85[[package]]
86name = "bytes"
87version = "1.12.1"
88source = "registry+https://github.com/rust-lang/crates.io-index"
89checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
90
91[[package]]
92name = "cc"
93version = "1.4.2"
94source = "registry+https://github.com/rust-lang/crates.io-index"
95checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e"
96dependencies = [
97 "find-msvc-tools",
98 "shlex",
99]
100
101[[package]]
102name = "cfg-if"
103version = "1.0.4"
104source = "registry+https://github.com/rust-lang/crates.io-index"
105checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
106
107[[package]]
108name = "cfg_aliases"
109version = "0.2.2"
110source = "registry+https://github.com/rust-lang/crates.io-index"
111checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527"
112
113[[package]]
114name = "chacha20"
115version = "0.10.1"
116source = "registry+https://github.com/rust-lang/crates.io-index"
117checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
118dependencies = [
119 "cfg-if",
120 "cpufeatures 0.3.0",
121 "rand_core 0.10.1",
122]
123
124[[package]]
125name = "chrono"
126version = "0.4.45"
127source = "registry+https://github.com/rust-lang/crates.io-index"
128checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
129dependencies = [
130 "iana-time-zone",
131 "js-sys",
132 "num-traits",
133 "wasm-bindgen",
134 "windows-link",
135]
136
137[[package]]
138name = "core-foundation-sys"
139version = "0.8.7"
140source = "registry+https://github.com/rust-lang/crates.io-index"
141checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
142
143[[package]]
144name = "cpufeatures"
145version = "0.2.17"
146source = "registry+https://github.com/rust-lang/crates.io-index"
147checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
148dependencies = [
149 "libc",
150]
151
152[[package]]
153name = "cpufeatures"
154version = "0.3.0"
155source = "registry+https://github.com/rust-lang/crates.io-index"
156checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
157dependencies = [
158 "libc",
159]
160
161[[package]]
162name = "crc32fast"
163version = "1.5.0"
164source = "registry+https://github.com/rust-lang/crates.io-index"
165checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
166dependencies = [
167 "cfg-if",
168]
169
170[[package]]
171name = "crypto-common"
172version = "0.1.7"
173source = "registry+https://github.com/rust-lang/crates.io-index"
174checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
175dependencies = [
176 "generic-array",
177 "typenum",
178]
179
180[[package]]
181name = "data-encoding"
182version = "2.11.1"
183source = "registry+https://github.com/rust-lang/crates.io-index"
184checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06"
185
186[[package]]
187name = "deranged"
188version = "0.5.8"
189source = "registry+https://github.com/rust-lang/crates.io-index"
190checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
191dependencies = [
192 "serde_core",
193]
194
195[[package]]
196name = "digest"
197version = "0.10.7"
198source = "registry+https://github.com/rust-lang/crates.io-index"
199checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
200dependencies = [
201 "block-buffer",
202 "crypto-common",
203]
204
205[[package]]
206name = "displaydoc"
207version = "0.2.7"
208source = "registry+https://github.com/rust-lang/crates.io-index"
209checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8"
210dependencies = [
211 "proc-macro2",
212 "quote",
213 "syn 3.0.3",
214]
215
216[[package]]
217name = "dotenvy"
218version = "0.15.7"
219source = "registry+https://github.com/rust-lang/crates.io-index"
220checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
221
222[[package]]
223name = "find-msvc-tools"
224version = "0.1.10"
225source = "registry+https://github.com/rust-lang/crates.io-index"
226checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de"
227
228[[package]]
229name = "flate2"
230version = "1.1.9"
231source = "registry+https://github.com/rust-lang/crates.io-index"
232checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
233dependencies = [
234 "crc32fast",
235 "miniz_oxide",
236]
237
238[[package]]
239name = "form_urlencoded"
240version = "1.2.2"
241source = "registry+https://github.com/rust-lang/crates.io-index"
242checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
243dependencies = [
244 "percent-encoding",
245]
246
247[[package]]
248name = "futures"
249version = "0.3.34"
250source = "registry+https://github.com/rust-lang/crates.io-index"
251checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3"
252dependencies = [
253 "futures-channel",
254 "futures-core",
255 "futures-io",
256 "futures-sink",
257 "futures-task",
258 "futures-util",
259]
260
261[[package]]
262name = "futures-channel"
263version = "0.3.34"
264source = "registry+https://github.com/rust-lang/crates.io-index"
265checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
266dependencies = [
267 "futures-core",
268 "futures-sink",
269]
270
271[[package]]
272name = "futures-core"
273version = "0.3.34"
274source = "registry+https://github.com/rust-lang/crates.io-index"
275checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
276
277[[package]]
278name = "futures-io"
279version = "0.3.34"
280source = "registry+https://github.com/rust-lang/crates.io-index"
281checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed"
282
283[[package]]
284name = "futures-macro"
285version = "0.3.34"
286source = "registry+https://github.com/rust-lang/crates.io-index"
287checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
288dependencies = [
289 "proc-macro2",
290 "quote",
291 "syn 3.0.3",
292]
293
294[[package]]
295name = "futures-sink"
296version = "0.3.34"
297source = "registry+https://github.com/rust-lang/crates.io-index"
298checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d"
299
300[[package]]
301name = "futures-task"
302version = "0.3.34"
303source = "registry+https://github.com/rust-lang/crates.io-index"
304checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
305
306[[package]]
307name = "futures-util"
308version = "0.3.34"
309source = "registry+https://github.com/rust-lang/crates.io-index"
310checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
311dependencies = [
312 "futures-channel",
313 "futures-core",
314 "futures-io",
315 "futures-macro",
316 "futures-sink",
317 "futures-task",
318 "memchr",
319 "pin-project-lite",
320 "slab",
321]
322
323[[package]]
324name = "generic-array"
325version = "0.14.7"
326source = "registry+https://github.com/rust-lang/crates.io-index"
327checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
328dependencies = [
329 "typenum",
330 "version_check",
331]
332
333[[package]]
334name = "getrandom"
335version = "0.2.17"
336source = "registry+https://github.com/rust-lang/crates.io-index"
337checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
338dependencies = [
339 "cfg-if",
340 "js-sys",
341 "libc",
342 "wasi",
343 "wasm-bindgen",
344]
345
346[[package]]
347name = "getrandom"
348version = "0.4.3"
349source = "registry+https://github.com/rust-lang/crates.io-index"
350checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
351dependencies = [
352 "cfg-if",
353 "js-sys",
354 "libc",
355 "r-efi",
356 "rand_core 0.10.1",
357 "wasm-bindgen",
358]
359
360[[package]]
361name = "http"
362version = "1.5.0"
363source = "registry+https://github.com/rust-lang/crates.io-index"
364checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
365dependencies = [
366 "bytes",
367 "itoa",
368]
369
370[[package]]
371name = "http-body"
372version = "1.1.0"
373source = "registry+https://github.com/rust-lang/crates.io-index"
374checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c"
375dependencies = [
376 "bytes",
377 "http",
378]
379
380[[package]]
381name = "http-body-util"
382version = "0.1.4"
383source = "registry+https://github.com/rust-lang/crates.io-index"
384checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2"
385dependencies = [
386 "bytes",
387 "futures-core",
388 "http",
389 "http-body",
390 "pin-project-lite",
391]
392
393[[package]]
394name = "httparse"
395version = "1.10.1"
396source = "registry+https://github.com/rust-lang/crates.io-index"
397checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
398
399[[package]]
400name = "hyper"
401version = "1.11.0"
402source = "registry+https://github.com/rust-lang/crates.io-index"
403checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72"
404dependencies = [
405 "atomic-waker",
406 "bytes",
407 "futures-channel",
408 "futures-core",
409 "http",
410 "http-body",
411 "httparse",
412 "itoa",
413 "pin-project-lite",
414 "smallvec",
415 "tokio",
416 "want",
417]
418
419[[package]]
420name = "hyper-rustls"
421version = "0.27.9"
422source = "registry+https://github.com/rust-lang/crates.io-index"
423checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
424dependencies = [
425 "http",
426 "hyper",
427 "hyper-util",
428 "rustls 0.23.43",
429 "tokio",
430 "tokio-rustls 0.26.4",
431 "tower-service",
432 "webpki-roots 1.0.9",
433]
434
435[[package]]
436name = "hyper-util"
437version = "0.1.20"
438source = "registry+https://github.com/rust-lang/crates.io-index"
439checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
440dependencies = [
441 "base64",
442 "bytes",
443 "futures-channel",
444 "futures-util",
445 "http",
446 "http-body",
447 "hyper",
448 "ipnet",
449 "libc",
450 "percent-encoding",
451 "pin-project-lite",
452 "socket2",
453 "tokio",
454 "tower-service",
455 "tracing",
456]
457
458[[package]]
459name = "iana-time-zone"
460version = "0.1.65"
461source = "registry+https://github.com/rust-lang/crates.io-index"
462checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
463dependencies = [
464 "android_system_properties",
465 "core-foundation-sys",
466 "iana-time-zone-haiku",
467 "js-sys",
468 "log",
469 "wasm-bindgen",
470 "windows-core",
471]
472
473[[package]]
474name = "iana-time-zone-haiku"
475version = "0.1.2"
476source = "registry+https://github.com/rust-lang/crates.io-index"
477checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
478dependencies = [
479 "cc",
480]
481
482[[package]]
483name = "icu_collections"
484version = "2.2.0"
485source = "registry+https://github.com/rust-lang/crates.io-index"
486checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
487dependencies = [
488 "displaydoc",
489 "potential_utf",
490 "utf8_iter",
491 "yoke",
492 "zerofrom",
493 "zerovec",
494]
495
496[[package]]
497name = "icu_locale_core"
498version = "2.2.0"
499source = "registry+https://github.com/rust-lang/crates.io-index"
500checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
501dependencies = [
502 "displaydoc",
503 "litemap",
504 "tinystr",
505 "writeable",
506 "zerovec",
507]
508
509[[package]]
510name = "icu_normalizer"
511version = "2.2.0"
512source = "registry+https://github.com/rust-lang/crates.io-index"
513checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
514dependencies = [
515 "icu_collections",
516 "icu_normalizer_data",
517 "icu_properties",
518 "icu_provider",
519 "smallvec",
520 "zerovec",
521]
522
523[[package]]
524name = "icu_normalizer_data"
525version = "2.2.0"
526source = "registry+https://github.com/rust-lang/crates.io-index"
527checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
528
529[[package]]
530name = "icu_properties"
531version = "2.2.0"
532source = "registry+https://github.com/rust-lang/crates.io-index"
533checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
534dependencies = [
535 "icu_collections",
536 "icu_locale_core",
537 "icu_properties_data",
538 "icu_provider",
539 "zerotrie",
540 "zerovec",
541]
542
543[[package]]
544name = "icu_properties_data"
545version = "2.2.0"
546source = "registry+https://github.com/rust-lang/crates.io-index"
547checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
548
549[[package]]
550name = "icu_provider"
551version = "2.2.0"
552source = "registry+https://github.com/rust-lang/crates.io-index"
553checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
554dependencies = [
555 "displaydoc",
556 "icu_locale_core",
557 "writeable",
558 "yoke",
559 "zerofrom",
560 "zerotrie",
561 "zerovec",
562]
563
564[[package]]
565name = "idna"
566version = "1.1.0"
567source = "registry+https://github.com/rust-lang/crates.io-index"
568checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
569dependencies = [
570 "idna_adapter",
571 "smallvec",
572 "utf8_iter",
573]
574
575[[package]]
576name = "idna_adapter"
577version = "1.2.2"
578source = "registry+https://github.com/rust-lang/crates.io-index"
579checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
580dependencies = [
581 "icu_normalizer",
582 "icu_properties",
583]
584
585[[package]]
586name = "ipnet"
587version = "2.12.1"
588source = "registry+https://github.com/rust-lang/crates.io-index"
589checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78"
590
591[[package]]
592name = "itoa"
593version = "1.0.18"
594source = "registry+https://github.com/rust-lang/crates.io-index"
595checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
596
597[[package]]
598name = "js-sys"
599version = "0.3.104"
600source = "registry+https://github.com/rust-lang/crates.io-index"
601checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a"
602dependencies = [
603 "cfg-if",
604 "futures-util",
605 "wasm-bindgen",
606]
607
608[[package]]
609name = "lazy_static"
610version = "1.5.0"
611source = "registry+https://github.com/rust-lang/crates.io-index"
612checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
613
614[[package]]
615name = "libc"
616version = "0.2.189"
617source = "registry+https://github.com/rust-lang/crates.io-index"
618checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
619
620[[package]]
621name = "litemap"
622version = "0.8.2"
623source = "registry+https://github.com/rust-lang/crates.io-index"
624checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
625
626[[package]]
627name = "log"
628version = "0.4.33"
629source = "registry+https://github.com/rust-lang/crates.io-index"
630checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
631
632[[package]]
633name = "lru-slab"
634version = "0.1.2"
635source = "registry+https://github.com/rust-lang/crates.io-index"
636checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
637
638[[package]]
639name = "memchr"
640version = "2.8.3"
641source = "registry+https://github.com/rust-lang/crates.io-index"
642checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
643
644[[package]]
645name = "mime"
646version = "0.3.17"
647source = "registry+https://github.com/rust-lang/crates.io-index"
648checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
649
650[[package]]
651name = "mime_guess"
652version = "2.0.5"
653source = "registry+https://github.com/rust-lang/crates.io-index"
654checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
655dependencies = [
656 "mime",
657 "unicase",
658]
659
660[[package]]
661name = "miniz_oxide"
662version = "0.8.9"
663source = "registry+https://github.com/rust-lang/crates.io-index"
664checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
665dependencies = [
666 "adler2",
667 "simd-adler32",
668]
669
670[[package]]
671name = "mio"
672version = "1.2.2"
673source = "registry+https://github.com/rust-lang/crates.io-index"
674checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
675dependencies = [
676 "libc",
677 "wasi",
678 "windows-sys 0.61.2",
679]
680
681[[package]]
682name = "nu-ansi-term"
683version = "0.50.3"
684source = "registry+https://github.com/rust-lang/crates.io-index"
685checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
686dependencies = [
687 "windows-sys 0.61.2",
688]
689
690[[package]]
691name = "num-conv"
692version = "0.2.2"
693source = "registry+https://github.com/rust-lang/crates.io-index"
694checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
695
696[[package]]
697name = "num-traits"
698version = "0.2.19"
699source = "registry+https://github.com/rust-lang/crates.io-index"
700checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
701dependencies = [
702 "autocfg",
703]
704
705[[package]]
706name = "once_cell"
707version = "1.21.4"
708source = "registry+https://github.com/rust-lang/crates.io-index"
709checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
710
711[[package]]
712name = "percent-encoding"
713version = "2.3.2"
714source = "registry+https://github.com/rust-lang/crates.io-index"
715checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
716
717[[package]]
718name = "pin-project-lite"
719version = "0.2.17"
720source = "registry+https://github.com/rust-lang/crates.io-index"
721checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
722
723[[package]]
724name = "potential_utf"
725version = "0.1.5"
726source = "registry+https://github.com/rust-lang/crates.io-index"
727checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
728dependencies = [
729 "zerovec",
730]
731
732[[package]]
733name = "powerfmt"
734version = "0.2.0"
735source = "registry+https://github.com/rust-lang/crates.io-index"
736checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
737
738[[package]]
739name = "ppv-lite86"
740version = "0.2.21"
741source = "registry+https://github.com/rust-lang/crates.io-index"
742checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
743dependencies = [
744 "zerocopy",
745]
746
747[[package]]
748name = "proc-macro2"
749version = "1.0.107"
750source = "registry+https://github.com/rust-lang/crates.io-index"
751checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
752dependencies = [
753 "unicode-ident",
754]
755
756[[package]]
757name = "quinn"
758version = "0.11.11"
759source = "registry+https://github.com/rust-lang/crates.io-index"
760checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8"
761dependencies = [
762 "bytes",
763 "cfg_aliases",
764 "pin-project-lite",
765 "quinn-proto",
766 "quinn-udp",
767 "rustc-hash",
768 "rustls 0.23.43",
769 "socket2",
770 "thiserror 2.0.20",
771 "tokio",
772 "tracing",
773 "web-time",
774]
775
776[[package]]
777name = "quinn-proto"
778version = "0.11.16"
779source = "registry+https://github.com/rust-lang/crates.io-index"
780checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560"
781dependencies = [
782 "bytes",
783 "getrandom 0.4.3",
784 "lru-slab",
785 "rand 0.10.2",
786 "rand_pcg",
787 "ring",
788 "rustc-hash",
789 "rustls 0.23.43",
790 "rustls-pki-types",
791 "slab",
792 "thiserror 2.0.20",
793 "tinyvec",
794 "tracing",
795 "web-time",
796]
797
798[[package]]
799name = "quinn-udp"
800version = "0.5.15"
801source = "registry+https://github.com/rust-lang/crates.io-index"
802checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694"
803dependencies = [
804 "cfg_aliases",
805 "libc",
806 "once_cell",
807 "socket2",
808 "tracing",
809 "windows-sys 0.61.2",
810]
811
812[[package]]
813name = "quote"
814version = "1.0.47"
815source = "registry+https://github.com/rust-lang/crates.io-index"
816checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
817dependencies = [
818 "proc-macro2",
819]
820
821[[package]]
822name = "r-efi"
823version = "6.0.0"
824source = "registry+https://github.com/rust-lang/crates.io-index"
825checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
826
827[[package]]
828name = "rand"
829version = "0.8.7"
830source = "registry+https://github.com/rust-lang/crates.io-index"
831checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a"
832dependencies = [
833 "libc",
834 "rand_chacha",
835 "rand_core 0.6.4",
836]
837
838[[package]]
839name = "rand"
840version = "0.10.2"
841source = "registry+https://github.com/rust-lang/crates.io-index"
842checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
843dependencies = [
844 "chacha20",
845 "getrandom 0.4.3",
846 "rand_core 0.10.1",
847]
848
849[[package]]
850name = "rand_chacha"
851version = "0.3.1"
852source = "registry+https://github.com/rust-lang/crates.io-index"
853checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
854dependencies = [
855 "ppv-lite86",
856 "rand_core 0.6.4",
857]
858
859[[package]]
860name = "rand_core"
861version = "0.6.4"
862source = "registry+https://github.com/rust-lang/crates.io-index"
863checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
864dependencies = [
865 "getrandom 0.2.17",
866]
867
868[[package]]
869name = "rand_core"
870version = "0.10.1"
871source = "registry+https://github.com/rust-lang/crates.io-index"
872checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
873
874[[package]]
875name = "rand_pcg"
876version = "0.10.2"
877source = "registry+https://github.com/rust-lang/crates.io-index"
878checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a"
879dependencies = [
880 "rand_core 0.10.1",
881]
882
883[[package]]
884name = "reqwest"
885version = "0.12.28"
886source = "registry+https://github.com/rust-lang/crates.io-index"
887checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
888dependencies = [
889 "base64",
890 "bytes",
891 "futures-core",
892 "futures-util",
893 "http",
894 "http-body",
895 "http-body-util",
896 "hyper",
897 "hyper-rustls",
898 "hyper-util",
899 "js-sys",
900 "log",
901 "mime_guess",
902 "percent-encoding",
903 "pin-project-lite",
904 "quinn",
905 "rustls 0.23.43",
906 "rustls-pki-types",
907 "serde",
908 "serde_json",
909 "serde_urlencoded",
910 "sync_wrapper",
911 "tokio",
912 "tokio-rustls 0.26.4",
913 "tokio-util",
914 "tower",
915 "tower-http",
916 "tower-service",
917 "url",
918 "wasm-bindgen",
919 "wasm-bindgen-futures",
920 "wasm-streams",
921 "web-sys",
922 "webpki-roots 1.0.9",
923]
924
925[[package]]
926name = "ring"
927version = "0.17.14"
928source = "registry+https://github.com/rust-lang/crates.io-index"
929checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
930dependencies = [
931 "cc",
932 "cfg-if",
933 "getrandom 0.2.17",
934 "libc",
935 "untrusted",
936 "windows-sys 0.52.0",
937]
938
939[[package]]
940name = "rustc-hash"
941version = "2.1.3"
942source = "registry+https://github.com/rust-lang/crates.io-index"
943checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
944
945[[package]]
946name = "rustls"
947version = "0.22.4"
948source = "registry+https://github.com/rust-lang/crates.io-index"
949checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
950dependencies = [
951 "log",
952 "ring",
953 "rustls-pki-types",
954 "rustls-webpki 0.102.8",
955 "subtle",
956 "zeroize",
957]
958
959[[package]]
960name = "rustls"
961version = "0.23.43"
962source = "registry+https://github.com/rust-lang/crates.io-index"
963checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
964dependencies = [
965 "once_cell",
966 "ring",
967 "rustls-pki-types",
968 "rustls-webpki 0.103.14",
969 "subtle",
970 "zeroize",
971]
972
973[[package]]
974name = "rustls-pki-types"
975version = "1.15.1"
976source = "registry+https://github.com/rust-lang/crates.io-index"
977checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
978dependencies = [
979 "web-time",
980 "zeroize",
981]
982
983[[package]]
984name = "rustls-webpki"
985version = "0.102.8"
986source = "registry+https://github.com/rust-lang/crates.io-index"
987checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
988dependencies = [
989 "ring",
990 "rustls-pki-types",
991 "untrusted",
992]
993
994[[package]]
995name = "rustls-webpki"
996version = "0.103.14"
997source = "registry+https://github.com/rust-lang/crates.io-index"
998checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a"
999dependencies = [
1000 "ring",
1001 "rustls-pki-types",
1002 "untrusted",
1003]
1004
1005[[package]]
1006name = "rustversion"
1007version = "1.0.23"
1008source = "registry+https://github.com/rust-lang/crates.io-index"
1009checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
1010
1011[[package]]
1012name = "ryu"
1013version = "1.0.23"
1014source = "registry+https://github.com/rust-lang/crates.io-index"
1015checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
1016
1017[[package]]
1018name = "secrecy"
1019version = "0.8.0"
1020source = "registry+https://github.com/rust-lang/crates.io-index"
1021checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
1022dependencies = [
1023 "serde",
1024 "zeroize",
1025]
1026
1027[[package]]
1028name = "serde"
1029version = "1.0.229"
1030source = "registry+https://github.com/rust-lang/crates.io-index"
1031checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
1032dependencies = [
1033 "serde_core",
1034 "serde_derive",
1035]
1036
1037[[package]]
1038name = "serde_core"
1039version = "1.0.229"
1040source = "registry+https://github.com/rust-lang/crates.io-index"
1041checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
1042dependencies = [
1043 "serde_derive",
1044]
1045
1046[[package]]
1047name = "serde_cow"
1048version = "0.1.2"
1049source = "registry+https://github.com/rust-lang/crates.io-index"
1050checksum = "1e7bbbec7196bfde255ab54b65e34087c0849629280028238e67ee25d6a4b7da"
1051dependencies = [
1052 "serde",
1053]
1054
1055[[package]]
1056name = "serde_derive"
1057version = "1.0.229"
1058source = "registry+https://github.com/rust-lang/crates.io-index"
1059checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
1060dependencies = [
1061 "proc-macro2",
1062 "quote",
1063 "syn 3.0.3",
1064]
1065
1066[[package]]
1067name = "serde_json"
1068version = "1.0.151"
1069source = "registry+https://github.com/rust-lang/crates.io-index"
1070checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
1071dependencies = [
1072 "itoa",
1073 "memchr",
1074 "serde",
1075 "serde_core",
1076 "zmij",
1077]
1078
1079[[package]]
1080name = "serde_urlencoded"
1081version = "0.7.1"
1082source = "registry+https://github.com/rust-lang/crates.io-index"
1083checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
1084dependencies = [
1085 "form_urlencoded",
1086 "itoa",
1087 "ryu",
1088 "serde",
1089]
1090
1091[[package]]
1092name = "serenity"
1093version = "0.12.5"
1094source = "registry+https://github.com/rust-lang/crates.io-index"
1095checksum = "9bde37f42765dfdc34e2a039e0c84afbf79a3101c1941763b0beb816c2f17541"
1096dependencies = [
1097 "arrayvec",
1098 "async-trait",
1099 "base64",
1100 "bitflags",
1101 "bytes",
1102 "flate2",
1103 "futures",
1104 "mime_guess",
1105 "percent-encoding",
1106 "reqwest",
1107 "secrecy",
1108 "serde",
1109 "serde_cow",
1110 "serde_json",
1111 "time",
1112 "tokio",
1113 "tokio-tungstenite",
1114 "tracing",
1115 "typemap_rev",
1116 "url",
1117]
1118
1119[[package]]
1120name = "sha1"
1121version = "0.10.7"
1122source = "registry+https://github.com/rust-lang/crates.io-index"
1123checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8"
1124dependencies = [
1125 "cfg-if",
1126 "cpufeatures 0.2.17",
1127 "digest",
1128]
1129
1130[[package]]
1131name = "sharded-slab"
1132version = "0.1.7"
1133source = "registry+https://github.com/rust-lang/crates.io-index"
1134checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
1135dependencies = [
1136 "lazy_static",
1137]
1138
1139[[package]]
1140name = "shlex"
1141version = "2.0.1"
1142source = "registry+https://github.com/rust-lang/crates.io-index"
1143checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
1144
1145[[package]]
1146name = "simd-adler32"
1147version = "0.3.10"
1148source = "registry+https://github.com/rust-lang/crates.io-index"
1149checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
1150
1151[[package]]
1152name = "slab"
1153version = "0.4.12"
1154source = "registry+https://github.com/rust-lang/crates.io-index"
1155checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
1156
1157[[package]]
1158name = "smallvec"
1159version = "1.15.2"
1160source = "registry+https://github.com/rust-lang/crates.io-index"
1161checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
1162
1163[[package]]
1164name = "socket2"
1165version = "0.6.5"
1166source = "registry+https://github.com/rust-lang/crates.io-index"
1167checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
1168dependencies = [
1169 "libc",
1170 "windows-sys 0.61.2",
1171]
1172
1173[[package]]
1174name = "stable_deref_trait"
1175version = "1.2.1"
1176source = "registry+https://github.com/rust-lang/crates.io-index"
1177checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
1178
1179[[package]]
1180name = "subtle"
1181version = "2.6.1"
1182source = "registry+https://github.com/rust-lang/crates.io-index"
1183checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
1184
1185[[package]]
1186name = "syn"
1187version = "2.0.119"
1188source = "registry+https://github.com/rust-lang/crates.io-index"
1189checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
1190dependencies = [
1191 "proc-macro2",
1192 "quote",
1193 "unicode-ident",
1194]
1195
1196[[package]]
1197name = "syn"
1198version = "3.0.3"
1199source = "registry+https://github.com/rust-lang/crates.io-index"
1200checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
1201dependencies = [
1202 "proc-macro2",
1203 "quote",
1204 "unicode-ident",
1205]
1206
1207[[package]]
1208name = "sync_wrapper"
1209version = "1.0.2"
1210source = "registry+https://github.com/rust-lang/crates.io-index"
1211checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
1212dependencies = [
1213 "futures-core",
1214]
1215
1216[[package]]
1217name = "synstructure"
1218version = "0.13.2"
1219source = "registry+https://github.com/rust-lang/crates.io-index"
1220checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
1221dependencies = [
1222 "proc-macro2",
1223 "quote",
1224 "syn 2.0.119",
1225]
1226
1227[[package]]
1228name = "thiserror"
1229version = "1.0.69"
1230source = "registry+https://github.com/rust-lang/crates.io-index"
1231checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
1232dependencies = [
1233 "thiserror-impl 1.0.69",
1234]
1235
1236[[package]]
1237name = "thiserror"
1238version = "2.0.20"
1239source = "registry+https://github.com/rust-lang/crates.io-index"
1240checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
1241dependencies = [
1242 "thiserror-impl 2.0.20",
1243]
1244
1245[[package]]
1246name = "thiserror-impl"
1247version = "1.0.69"
1248source = "registry+https://github.com/rust-lang/crates.io-index"
1249checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
1250dependencies = [
1251 "proc-macro2",
1252 "quote",
1253 "syn 2.0.119",
1254]
1255
1256[[package]]
1257name = "thiserror-impl"
1258version = "2.0.20"
1259source = "registry+https://github.com/rust-lang/crates.io-index"
1260checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
1261dependencies = [
1262 "proc-macro2",
1263 "quote",
1264 "syn 3.0.3",
1265]
1266
1267[[package]]
1268name = "thread_local"
1269version = "1.1.10"
1270source = "registry+https://github.com/rust-lang/crates.io-index"
1271checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070"
1272dependencies = [
1273 "cfg-if",
1274]
1275
1276[[package]]
1277name = "time"
1278version = "0.3.55"
1279source = "registry+https://github.com/rust-lang/crates.io-index"
1280checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134"
1281dependencies = [
1282 "deranged",
1283 "num-conv",
1284 "powerfmt",
1285 "serde_core",
1286 "time-core",
1287 "time-macros",
1288]
1289
1290[[package]]
1291name = "time-core"
1292version = "0.1.9"
1293source = "registry+https://github.com/rust-lang/crates.io-index"
1294checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
1295
1296[[package]]
1297name = "time-macros"
1298version = "0.2.32"
1299source = "registry+https://github.com/rust-lang/crates.io-index"
1300checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85"
1301dependencies = [
1302 "num-conv",
1303 "time-core",
1304]
1305
1306[[package]]
1307name = "timeoutinator"
1308version = "0.1.0"
1309dependencies = [
1310 "chrono",
1311 "dotenvy",
1312 "serenity",
1313 "tokio",
1314 "tracing",
1315 "tracing-subscriber",
1316]
1317
1318[[package]]
1319name = "tinystr"
1320version = "0.8.3"
1321source = "registry+https://github.com/rust-lang/crates.io-index"
1322checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
1323dependencies = [
1324 "displaydoc",
1325 "zerovec",
1326]
1327
1328[[package]]
1329name = "tinyvec"
1330version = "1.12.0"
1331source = "registry+https://github.com/rust-lang/crates.io-index"
1332checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f"
1333dependencies = [
1334 "tinyvec_macros",
1335]
1336
1337[[package]]
1338name = "tinyvec_macros"
1339version = "0.1.1"
1340source = "registry+https://github.com/rust-lang/crates.io-index"
1341checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
1342
1343[[package]]
1344name = "tokio"
1345version = "1.53.1"
1346source = "registry+https://github.com/rust-lang/crates.io-index"
1347checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
1348dependencies = [
1349 "bytes",
1350 "libc",
1351 "mio",
1352 "pin-project-lite",
1353 "socket2",
1354 "tokio-macros",
1355 "windows-sys 0.61.2",
1356]
1357
1358[[package]]
1359name = "tokio-macros"
1360version = "2.7.2"
1361source = "registry+https://github.com/rust-lang/crates.io-index"
1362checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
1363dependencies = [
1364 "proc-macro2",
1365 "quote",
1366 "syn 3.0.3",
1367]
1368
1369[[package]]
1370name = "tokio-rustls"
1371version = "0.25.0"
1372source = "registry+https://github.com/rust-lang/crates.io-index"
1373checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
1374dependencies = [
1375 "rustls 0.22.4",
1376 "rustls-pki-types",
1377 "tokio",
1378]
1379
1380[[package]]
1381name = "tokio-rustls"
1382version = "0.26.4"
1383source = "registry+https://github.com/rust-lang/crates.io-index"
1384checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
1385dependencies = [
1386 "rustls 0.23.43",
1387 "tokio",
1388]
1389
1390[[package]]
1391name = "tokio-tungstenite"
1392version = "0.21.0"
1393source = "registry+https://github.com/rust-lang/crates.io-index"
1394checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
1395dependencies = [
1396 "futures-util",
1397 "log",
1398 "rustls 0.22.4",
1399 "rustls-pki-types",
1400 "tokio",
1401 "tokio-rustls 0.25.0",
1402 "tungstenite",
1403 "webpki-roots 0.26.11",
1404]
1405
1406[[package]]
1407name = "tokio-util"
1408version = "0.7.19"
1409source = "registry+https://github.com/rust-lang/crates.io-index"
1410checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
1411dependencies = [
1412 "bytes",
1413 "futures-core",
1414 "futures-sink",
1415 "pin-project-lite",
1416 "tokio",
1417]
1418
1419[[package]]
1420name = "tower"
1421version = "0.5.3"
1422source = "registry+https://github.com/rust-lang/crates.io-index"
1423checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
1424dependencies = [
1425 "futures-core",
1426 "futures-util",
1427 "pin-project-lite",
1428 "sync_wrapper",
1429 "tokio",
1430 "tower-layer",
1431 "tower-service",
1432]
1433
1434[[package]]
1435name = "tower-http"
1436version = "0.6.11"
1437source = "registry+https://github.com/rust-lang/crates.io-index"
1438checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
1439dependencies = [
1440 "bitflags",
1441 "bytes",
1442 "futures-util",
1443 "http",
1444 "http-body",
1445 "pin-project-lite",
1446 "tower",
1447 "tower-layer",
1448 "tower-service",
1449 "url",
1450]
1451
1452[[package]]
1453name = "tower-layer"
1454version = "0.3.3"
1455source = "registry+https://github.com/rust-lang/crates.io-index"
1456checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
1457
1458[[package]]
1459name = "tower-service"
1460version = "0.3.3"
1461source = "registry+https://github.com/rust-lang/crates.io-index"
1462checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
1463
1464[[package]]
1465name = "tracing"
1466version = "0.1.44"
1467source = "registry+https://github.com/rust-lang/crates.io-index"
1468checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
1469dependencies = [
1470 "log",
1471 "pin-project-lite",
1472 "tracing-attributes",
1473 "tracing-core",
1474]
1475
1476[[package]]
1477name = "tracing-attributes"
1478version = "0.1.31"
1479source = "registry+https://github.com/rust-lang/crates.io-index"
1480checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
1481dependencies = [
1482 "proc-macro2",
1483 "quote",
1484 "syn 2.0.119",
1485]
1486
1487[[package]]
1488name = "tracing-core"
1489version = "0.1.36"
1490source = "registry+https://github.com/rust-lang/crates.io-index"
1491checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
1492dependencies = [
1493 "once_cell",
1494 "valuable",
1495]
1496
1497[[package]]
1498name = "tracing-log"
1499version = "0.2.0"
1500source = "registry+https://github.com/rust-lang/crates.io-index"
1501checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
1502dependencies = [
1503 "log",
1504 "once_cell",
1505 "tracing-core",
1506]
1507
1508[[package]]
1509name = "tracing-subscriber"
1510version = "0.3.23"
1511source = "registry+https://github.com/rust-lang/crates.io-index"
1512checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
1513dependencies = [
1514 "nu-ansi-term",
1515 "sharded-slab",
1516 "smallvec",
1517 "thread_local",
1518 "tracing-core",
1519 "tracing-log",
1520]
1521
1522[[package]]
1523name = "try-lock"
1524version = "0.2.5"
1525source = "registry+https://github.com/rust-lang/crates.io-index"
1526checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
1527
1528[[package]]
1529name = "tungstenite"
1530version = "0.21.0"
1531source = "registry+https://github.com/rust-lang/crates.io-index"
1532checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
1533dependencies = [
1534 "byteorder",
1535 "bytes",
1536 "data-encoding",
1537 "http",
1538 "httparse",
1539 "log",
1540 "rand 0.8.7",
1541 "rustls 0.22.4",
1542 "rustls-pki-types",
1543 "sha1",
1544 "thiserror 1.0.69",
1545 "url",
1546 "utf-8",
1547]
1548
1549[[package]]
1550name = "typemap_rev"
1551version = "0.3.0"
1552source = "registry+https://github.com/rust-lang/crates.io-index"
1553checksum = "74b08b0c1257381af16a5c3605254d529d3e7e109f3c62befc5d168968192998"
1554
1555[[package]]
1556name = "typenum"
1557version = "1.20.1"
1558source = "registry+https://github.com/rust-lang/crates.io-index"
1559checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
1560
1561[[package]]
1562name = "unicase"
1563version = "2.9.0"
1564source = "registry+https://github.com/rust-lang/crates.io-index"
1565checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
1566
1567[[package]]
1568name = "unicode-ident"
1569version = "1.0.24"
1570source = "registry+https://github.com/rust-lang/crates.io-index"
1571checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
1572
1573[[package]]
1574name = "untrusted"
1575version = "0.9.0"
1576source = "registry+https://github.com/rust-lang/crates.io-index"
1577checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
1578
1579[[package]]
1580name = "url"
1581version = "2.5.8"
1582source = "registry+https://github.com/rust-lang/crates.io-index"
1583checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
1584dependencies = [
1585 "form_urlencoded",
1586 "idna",
1587 "percent-encoding",
1588 "serde",
1589 "serde_derive",
1590]
1591
1592[[package]]
1593name = "utf-8"
1594version = "0.7.6"
1595source = "registry+https://github.com/rust-lang/crates.io-index"
1596checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
1597
1598[[package]]
1599name = "utf8_iter"
1600version = "1.0.4"
1601source = "registry+https://github.com/rust-lang/crates.io-index"
1602checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
1603
1604[[package]]
1605name = "valuable"
1606version = "0.1.1"
1607source = "registry+https://github.com/rust-lang/crates.io-index"
1608checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
1609
1610[[package]]
1611name = "version_check"
1612version = "0.9.5"
1613source = "registry+https://github.com/rust-lang/crates.io-index"
1614checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
1615
1616[[package]]
1617name = "want"
1618version = "0.3.1"
1619source = "registry+https://github.com/rust-lang/crates.io-index"
1620checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
1621dependencies = [
1622 "try-lock",
1623]
1624
1625[[package]]
1626name = "wasi"
1627version = "0.11.1+wasi-snapshot-preview1"
1628source = "registry+https://github.com/rust-lang/crates.io-index"
1629checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
1630
1631[[package]]
1632name = "wasm-bindgen"
1633version = "0.2.127"
1634source = "registry+https://github.com/rust-lang/crates.io-index"
1635checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70"
1636dependencies = [
1637 "cfg-if",
1638 "once_cell",
1639 "rustversion",
1640 "wasm-bindgen-macro",
1641 "wasm-bindgen-shared",
1642]
1643
1644[[package]]
1645name = "wasm-bindgen-futures"
1646version = "0.4.77"
1647source = "registry+https://github.com/rust-lang/crates.io-index"
1648checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950"
1649dependencies = [
1650 "js-sys",
1651 "wasm-bindgen",
1652]
1653
1654[[package]]
1655name = "wasm-bindgen-macro"
1656version = "0.2.127"
1657source = "registry+https://github.com/rust-lang/crates.io-index"
1658checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1"
1659dependencies = [
1660 "quote",
1661 "wasm-bindgen-macro-support",
1662]
1663
1664[[package]]
1665name = "wasm-bindgen-macro-support"
1666version = "0.2.127"
1667source = "registry+https://github.com/rust-lang/crates.io-index"
1668checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284"
1669dependencies = [
1670 "bumpalo",
1671 "proc-macro2",
1672 "quote",
1673 "syn 2.0.119",
1674 "wasm-bindgen-shared",
1675]
1676
1677[[package]]
1678name = "wasm-bindgen-shared"
1679version = "0.2.127"
1680source = "registry+https://github.com/rust-lang/crates.io-index"
1681checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf"
1682dependencies = [
1683 "unicode-ident",
1684]
1685
1686[[package]]
1687name = "wasm-streams"
1688version = "0.4.2"
1689source = "registry+https://github.com/rust-lang/crates.io-index"
1690checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
1691dependencies = [
1692 "futures-util",
1693 "js-sys",
1694 "wasm-bindgen",
1695 "wasm-bindgen-futures",
1696 "web-sys",
1697]
1698
1699[[package]]
1700name = "web-sys"
1701version = "0.3.104"
1702source = "registry+https://github.com/rust-lang/crates.io-index"
1703checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30"
1704dependencies = [
1705 "js-sys",
1706 "wasm-bindgen",
1707]
1708
1709[[package]]
1710name = "web-time"
1711version = "1.1.0"
1712source = "registry+https://github.com/rust-lang/crates.io-index"
1713checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
1714dependencies = [
1715 "js-sys",
1716 "wasm-bindgen",
1717]
1718
1719[[package]]
1720name = "webpki-roots"
1721version = "0.26.11"
1722source = "registry+https://github.com/rust-lang/crates.io-index"
1723checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
1724dependencies = [
1725 "webpki-roots 1.0.9",
1726]
1727
1728[[package]]
1729name = "webpki-roots"
1730version = "1.0.9"
1731source = "registry+https://github.com/rust-lang/crates.io-index"
1732checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
1733dependencies = [
1734 "rustls-pki-types",
1735]
1736
1737[[package]]
1738name = "windows-core"
1739version = "0.62.2"
1740source = "registry+https://github.com/rust-lang/crates.io-index"
1741checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
1742dependencies = [
1743 "windows-implement",
1744 "windows-interface",
1745 "windows-link",
1746 "windows-result",
1747 "windows-strings",
1748]
1749
1750[[package]]
1751name = "windows-implement"
1752version = "0.60.2"
1753source = "registry+https://github.com/rust-lang/crates.io-index"
1754checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
1755dependencies = [
1756 "proc-macro2",
1757 "quote",
1758 "syn 2.0.119",
1759]
1760
1761[[package]]
1762name = "windows-interface"
1763version = "0.59.3"
1764source = "registry+https://github.com/rust-lang/crates.io-index"
1765checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
1766dependencies = [
1767 "proc-macro2",
1768 "quote",
1769 "syn 2.0.119",
1770]
1771
1772[[package]]
1773name = "windows-link"
1774version = "0.2.1"
1775source = "registry+https://github.com/rust-lang/crates.io-index"
1776checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
1777
1778[[package]]
1779name = "windows-result"
1780version = "0.4.1"
1781source = "registry+https://github.com/rust-lang/crates.io-index"
1782checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
1783dependencies = [
1784 "windows-link",
1785]
1786
1787[[package]]
1788name = "windows-strings"
1789version = "0.5.1"
1790source = "registry+https://github.com/rust-lang/crates.io-index"
1791checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
1792dependencies = [
1793 "windows-link",
1794]
1795
1796[[package]]
1797name = "windows-sys"
1798version = "0.52.0"
1799source = "registry+https://github.com/rust-lang/crates.io-index"
1800checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
1801dependencies = [
1802 "windows-targets",
1803]
1804
1805[[package]]
1806name = "windows-sys"
1807version = "0.61.2"
1808source = "registry+https://github.com/rust-lang/crates.io-index"
1809checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
1810dependencies = [
1811 "windows-link",
1812]
1813
1814[[package]]
1815name = "windows-targets"
1816version = "0.52.6"
1817source = "registry+https://github.com/rust-lang/crates.io-index"
1818checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
1819dependencies = [
1820 "windows_aarch64_gnullvm",
1821 "windows_aarch64_msvc",
1822 "windows_i686_gnu",
1823 "windows_i686_gnullvm",
1824 "windows_i686_msvc",
1825 "windows_x86_64_gnu",
1826 "windows_x86_64_gnullvm",
1827 "windows_x86_64_msvc",
1828]
1829
1830[[package]]
1831name = "windows_aarch64_gnullvm"
1832version = "0.52.6"
1833source = "registry+https://github.com/rust-lang/crates.io-index"
1834checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
1835
1836[[package]]
1837name = "windows_aarch64_msvc"
1838version = "0.52.6"
1839source = "registry+https://github.com/rust-lang/crates.io-index"
1840checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
1841
1842[[package]]
1843name = "windows_i686_gnu"
1844version = "0.52.6"
1845source = "registry+https://github.com/rust-lang/crates.io-index"
1846checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
1847
1848[[package]]
1849name = "windows_i686_gnullvm"
1850version = "0.52.6"
1851source = "registry+https://github.com/rust-lang/crates.io-index"
1852checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
1853
1854[[package]]
1855name = "windows_i686_msvc"
1856version = "0.52.6"
1857source = "registry+https://github.com/rust-lang/crates.io-index"
1858checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
1859
1860[[package]]
1861name = "windows_x86_64_gnu"
1862version = "0.52.6"
1863source = "registry+https://github.com/rust-lang/crates.io-index"
1864checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
1865
1866[[package]]
1867name = "windows_x86_64_gnullvm"
1868version = "0.52.6"
1869source = "registry+https://github.com/rust-lang/crates.io-index"
1870checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
1871
1872[[package]]
1873name = "windows_x86_64_msvc"
1874version = "0.52.6"
1875source = "registry+https://github.com/rust-lang/crates.io-index"
1876checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
1877
1878[[package]]
1879name = "writeable"
1880version = "0.6.3"
1881source = "registry+https://github.com/rust-lang/crates.io-index"
1882checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
1883
1884[[package]]
1885name = "yoke"
1886version = "0.8.3"
1887source = "registry+https://github.com/rust-lang/crates.io-index"
1888checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
1889dependencies = [
1890 "stable_deref_trait",
1891 "yoke-derive",
1892 "zerofrom",
1893]
1894
1895[[package]]
1896name = "yoke-derive"
1897version = "0.8.2"
1898source = "registry+https://github.com/rust-lang/crates.io-index"
1899checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
1900dependencies = [
1901 "proc-macro2",
1902 "quote",
1903 "syn 2.0.119",
1904 "synstructure",
1905]
1906
1907[[package]]
1908name = "zerocopy"
1909version = "0.8.56"
1910source = "registry+https://github.com/rust-lang/crates.io-index"
1911checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb"
1912dependencies = [
1913 "zerocopy-derive",
1914]
1915
1916[[package]]
1917name = "zerocopy-derive"
1918version = "0.8.56"
1919source = "registry+https://github.com/rust-lang/crates.io-index"
1920checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1"
1921dependencies = [
1922 "proc-macro2",
1923 "quote",
1924 "syn 2.0.119",
1925]
1926
1927[[package]]
1928name = "zerofrom"
1929version = "0.1.8"
1930source = "registry+https://github.com/rust-lang/crates.io-index"
1931checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
1932dependencies = [
1933 "zerofrom-derive",
1934]
1935
1936[[package]]
1937name = "zerofrom-derive"
1938version = "0.1.7"
1939source = "registry+https://github.com/rust-lang/crates.io-index"
1940checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
1941dependencies = [
1942 "proc-macro2",
1943 "quote",
1944 "syn 2.0.119",
1945 "synstructure",
1946]
1947
1948[[package]]
1949name = "zeroize"
1950version = "1.9.0"
1951source = "registry+https://github.com/rust-lang/crates.io-index"
1952checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
1953
1954[[package]]
1955name = "zerotrie"
1956version = "0.2.4"
1957source = "registry+https://github.com/rust-lang/crates.io-index"
1958checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
1959dependencies = [
1960 "displaydoc",
1961 "yoke",
1962 "zerofrom",
1963]
1964
1965[[package]]
1966name = "zerovec"
1967version = "0.11.6"
1968source = "registry+https://github.com/rust-lang/crates.io-index"
1969checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
1970dependencies = [
1971 "yoke",
1972 "zerofrom",
1973 "zerovec-derive",
1974]
1975
1976[[package]]
1977name = "zerovec-derive"
1978version = "0.11.3"
1979source = "registry+https://github.com/rust-lang/crates.io-index"
1980checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
1981dependencies = [
1982 "proc-macro2",
1983 "quote",
1984 "syn 2.0.119",
1985]
1986
1987[[package]]
1988name = "zmij"
1989version = "1.0.23"
1990source = "registry+https://github.com/rust-lang/crates.io-index"
1991checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..b2e996b
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,18 @@
1[package]
2name = "timeoutinator"
3version = "0.1.0"
4edition = "2024"
5
6[dependencies]
7serenity = { version = "0.12", default-features = false, features = [
8 "client",
9 "gateway",
10 "model",
11 "builder",
12 "rustls_backend",
13] }
14tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
15chrono = "0.4"
16tracing = "0.1"
17tracing-subscriber = "0.3"
18dotenvy = "0.15"
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7a8d638
--- /dev/null
+++ b/README.md
@@ -0,0 +1,64 @@
1# Timeoutinator
2
3A Discord bot that instantly **timeouts** anyone who posts in a configured channel and **purges** all of their messages from the last 24 hours.
4
5## How it works
6
71. User sends a message in the policed channel.
82. Bot immediately times them out (`Moderate Members` — configurable duration, default 1 hour).
93. Bot bulk-deletes every message that user posted **in any channel of the guild** over the past 24 hours (including the triggering message).
10
11Bots, system messages, and webhook messages are ignored. The bot's own messages are also ignored. Concurrent handling of the same user is deduplicated so rapid-fire spam doesn't cause duplicate timeouts or purge races.
12
13## Setup
14
15### 1. Create a Discord Application
16
171. Go to [discord.com/developers/applications](https://discord.com/developers/applications)
182. Click **New Application** → name it → **Bot** tab → **Add Bot**
193. Under the bot, click **Reset Token** and copy the token — this is your `DISCORD_TOKEN`
20
21### 2. Enable Required Intents
22
23In the **Bot** tab, scroll to **Privileged Gateway Intents**.
24The bot only needs **Message Content** if you want to read message content — by default, only `GUILD_MESSAGES` is required, which is non-privileged. No privileged intents are required.
25
26### 3. Invite the Bot
27
28Use this URL (replace `YOUR_BOT_CLIENT_ID` with the bot's Client ID from the **General Information** tab):
29
30```
31https://discord.com/api/oauth2/authorize?client_id=YOUR_BOT_CLIENT_ID&permissions=1099511702528&scope=bot
32```
33
34Required permissions (encoded in the URL):
35
36| Permission | Why |
37|-------------------------|------------------------------------------|
38| View Channels | See the policed channel and the channels to purge |
39| Read Message History | Fetch messages to purge |
40| Manage Messages | Delete messages via bulk-delete endpoint |
41| Moderate Members | Apply timeouts |
42
43### 4. Run
44
45```bash
46cp .env.example .env # or export the env vars directly
47# edit .env with your token and target channel ID
48
49cargo run --release
50```
51
52## Environment Variables
53
54| Variable | Required | Default | Description |
55|-----------------------|----------|---------|----------------------------------------------------------------|
56| `DISCORD_TOKEN` | ✅ | — | Bot token from the Discord Developer Portal |
57| `TARGET_CHANNEL_ID` | ✅ | — | Snowflake ID of the channel to police (right-click → Copy ID) |
58| `TIMEOUT_MINUTES` | ❌ | `60` | Timeout duration in minutes (1–40320, i.e. up to 28 days) |
59| `PURGE_HOURS` | ❌ | `24` | How far back (hours) to look when deleting messages |
60
61## Requirements
62
63- Rust 1.85+ (edition 2024)
64- Network access (to fetch crates and connect to Discord's gateway)
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..81cae03
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,275 @@
1//! Timeoutinator — a Discord bot that instantly timeouts anyone who posts
2//! in a configured channel and purges that user's messages from the last
3//! 24 hours.
4
5use std::collections::HashSet;
6use std::env;
7use std::sync::atomic::{AtomicU64, Ordering};
8use std::sync::Mutex;
9
10use chrono::{Duration as ChronoDuration, Utc};
11use serenity::async_trait;
12use serenity::builder::GetMessages;
13use serenity::client::{Client, Context, EventHandler};
14use serenity::http::Http;
15use serenity::model::channel::{Message, MessageType};
16use serenity::model::gateway::Ready;
17use serenity::model::id::{ChannelId, MessageId, UserId};
18use serenity::model::Timestamp;
19use serenity::prelude::GatewayIntents;
20
21/// Discord's `GET /channels/{id}/messages` max page size.
22const PAGE_SIZE: u8 = 100;
23/// `DELETE /channels/{id}/messages` accepts at most 100 IDs per request.
24const BULK_DELETE_MAX: usize = 100;
25
26/// The bot's configuration and shared state.
27struct Handler {
28 /// Channel whose messages trigger the timeout + purge.
29 target_channel: ChannelId,
30 /// How long the timeout lasts (minutes).
31 timeout_minutes: i64,
32 /// Purge window for the offender's messages (hours).
33 purge_hours: i64,
34 /// The bot's own user ID, captured on `Ready` (the cache feature is
35 /// disabled, so we track it manually).
36 self_id: AtomicU64,
37 /// Users currently being processed, so a rapid spam click doesn't stack
38 /// concurrent purge/timeout jobs for the same user.
39 in_flight: Mutex<HashSet<UserId>>,
40}
41
42/// RAII guard that frees a user's in-flight slot when the handler is done.
43struct InFlightGuard<'a>(&'a Mutex<HashSet<UserId>>, UserId);
44
45impl<'a> InFlightGuard<'a> {
46 fn try_acquire(lock: &'a Mutex<HashSet<UserId>>, user: UserId) -> Option<Self> {
47 let mut set = lock.lock().ok()?;
48 if set.contains(&user) {
49 None
50 } else {
51 set.insert(user);
52 Some(Self(lock, user))
53 }
54 }
55}
56
57impl Drop for InFlightGuard<'_> {
58 fn drop(&mut self) {
59 if let Ok(mut set) = self.0.lock() {
60 set.remove(&self.1);
61 }
62 }
63}
64
65#[async_trait]
66impl EventHandler for Handler {
67 async fn ready(&self, _ctx: Context, ready: Ready) {
68 self.self_id.store(ready.user.id.get(), Ordering::Relaxed);
69 println!("Logged in as {}", ready.user.name);
70 }
71
72 async fn message(&self, ctx: Context, msg: Message) {
73 // Only police the configured channel.
74 if msg.channel_id != self.target_channel {
75 return;
76 }
77 // Ignore bots (including ourselves) and system messages.
78 if msg.author.bot
79 || !matches!(msg.kind, MessageType::Regular)
80 || self.self_id.load(Ordering::Relaxed) == msg.author.id.get()
81 {
82 return;
83 }
84
85 // Skip if this user is already being handled by an in-flight job.
86 let Some(_guard) = InFlightGuard::try_acquire(&self.in_flight, msg.author.id) else {
87 return;
88 };
89
90 // 1) Timeout the offender.
91 let until = Utc::now() + ChronoDuration::minutes(self.timeout_minutes);
92 match self.timeout_user(&ctx, &msg, until).await {
93 Ok(()) => println!(
94 "Timed out {} ({}) until {}",
95 msg.author.id,
96 msg.author.name,
97 until.to_rfc3339()
98 ),
99 Err(e) => eprintln!("Failed to timeout {}: {e}", msg.author.id),
100 }
101
102 // 2) Purge their messages from the last `purge_hours` in this channel.
103 match self.purge_user_messages(&ctx, &msg).await {
104 Ok(count) if count > 0 => {
105 println!("Deleted {count} message(s) from {}", msg.author.id)
106 }
107 Ok(_) => println!("No messages to purge from {}", msg.author.id),
108 Err(e) => eprintln!("Purge failed for {}: {e}", msg.author.id),
109 }
110 }
111}
112
113impl Handler {
114 /// Timeout the user by disabling their ability to communicate until `until`.
115 async fn timeout_user(
116 &self,
117 ctx: &Context,
118 msg: &Message,
119 until: chrono::DateTime<Utc>,
120 ) -> Result<(), serenity::Error> {
121 let Some(guild_id) = msg.guild_id else {
122 return Ok(()); // not in a guild; nothing to do
123 };
124
125 let mut member = guild_id.member(&ctx.http, msg.author.id).await?;
126 let until_ts = Timestamp::from_unix_timestamp(until.timestamp())
127 .expect("now + timeout minutes is always a valid unix timestamp");
128
129 member
130 .disable_communication_until_datetime(&ctx.http, until_ts)
131 .await
132 }
133
134 /// Delete every message written by `trigger.author` across every channel
135 /// of the guild within the last `purge_hours`, including the trigger
136 /// itself.
137 async fn purge_user_messages(
138 &self,
139 ctx: &Context,
140 trigger: &Message,
141 ) -> Result<usize, serenity::Error> {
142 let Some(guild_id) = trigger.guild_id else {
143 return Ok(0); // not in a guild; nothing to purge
144 };
145
146 // Bulk deletion only works on messages younger than 14 days, so clamp
147 // the window to 336 h even if configured larger.
148 let cutoff = (Utc::now() - ChronoDuration::hours(self.purge_hours.min(336))).timestamp();
149
150 let channels = guild_id.channels(&ctx.http).await?;
151
152 let mut total = 0;
153 for (channel_id, _channel) in channels {
154 // Read the channel's history; skip channels the bot can't see.
155 let mut ids = match self
156 .collect_user_messages(&ctx.http, channel_id, trigger.author.id, cutoff)
157 .await
158 {
159 Ok(ids) => ids,
160 Err(e) => {
161 eprintln!("Skipping channel {channel_id}: {e}");
162 continue;
163 }
164 };
165
166 if channel_id == trigger.channel_id {
167 ids.push(trigger.id);
168 }
169 ids.sort_unstable();
170 ids.dedup();
171
172 if ids.is_empty() {
173 continue;
174 }
175
176 // The bulk endpoint caps each request at 100 messages; batch.
177 for chunk in ids.chunks(BULK_DELETE_MAX) {
178 channel_id.delete_messages(&ctx.http, chunk).await?;
179 }
180 total += ids.len();
181 }
182 Ok(total)
183 }
184
185 /// Collect the IDs of every message by `author_id` in `channel_id` newer
186 /// than `cutoff`, paging back through the channel's history.
187 async fn collect_user_messages(
188 &self,
189 http: &Http,
190 channel_id: ChannelId,
191 author_id: UserId,
192 cutoff: i64,
193 ) -> Result<Vec<MessageId>, serenity::Error> {
194 let mut to_delete: Vec<MessageId> = Vec::new();
195 let mut before = MessageId::new(i64::MAX as u64);
196 let mut pages = 0;
197
198 loop {
199 pages += 1;
200 let page = channel_id
201 .messages(http, GetMessages::new().before(before).limit(PAGE_SIZE))
202 .await?;
203
204 to_delete.extend(page.iter().filter(|m| {
205 m.author.id == author_id && m.timestamp.unix_timestamp() >= cutoff
206 }).map(|m| m.id));
207
208 let still_in_window = page
209 .iter()
210 .any(|m| m.timestamp.unix_timestamp() >= cutoff);
211
212 // Reached the start of the channel, or the current page already
213 // goes back further than the purge window: we're done.
214 if page.len() < PAGE_SIZE as usize || !still_in_window || pages >= 500 {
215 break;
216 }
217 before = page.last().expect("non-empty page").id;
218 }
219
220 Ok(to_delete)
221 }
222}
223
224#[tokio::main]
225async fn main() {
226 dotenvy::dotenv().ok(); // optional .env support
227 tracing_subscriber::fmt()
228 .with_max_level(tracing::Level::INFO)
229 .init();
230
231 let token =
232 env::var("DISCORD_TOKEN").expect("missing env var DISCORD_TOKEN (your bot's token)");
233
234 let channel_id: u64 = env::var("TARGET_CHANNEL_ID")
235 .expect("missing env var TARGET_CHANNEL_ID (the channel to police)")
236 .parse()
237 .expect("TARGET_CHANNEL_ID must be a numeric snowflake (right-click channel -> Copy Channel ID)");
238
239 let timeout_minutes: i64 = env::var("TIMEOUT_MINUTES")
240 .ok()
241 .and_then(|v| v.parse().ok())
242 .unwrap_or(60)
243 .clamp(1, 40_320); // Discord's maximum timeout is 28 days.
244
245 let purge_hours: i64 = env::var("PURGE_HOURS")
246 .ok()
247 .and_then(|v| v.parse().ok())
248 .unwrap_or(24);
249
250 println!(
251 "Policing channel {channel_id}: timeout = {timeout_minutes} min, purge window = {purge_hours} h"
252 );
253
254 // Guild messages only: we never read message content, so the privileged
255 // Message Content intent is not required.
256 let intents = GatewayIntents::GUILD_MESSAGES;
257
258 let handler = Handler {
259 target_channel: ChannelId::new(channel_id),
260 timeout_minutes,
261 purge_hours,
262 self_id: AtomicU64::new(0),
263 in_flight: Mutex::new(HashSet::new()),
264 };
265
266 let mut client = Client::builder(&token, intents)
267 .event_handler(handler)
268 .await
269 .expect("Failed to create Discord client");
270
271 if let Err(e) = client.start().await {
272 eprintln!("Client error: {e:?}");
273 std::process::exit(1);
274 }
275}