diff --git a/.env.example b/.env.example index 178ad4f..67debda 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,2 @@ -TOKEN= -HOST= -MODE= +TELOXIDE_TOKEN= +GITHUB_TOKEN= \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index a206208..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Test CI - -on: [push, pull_request] - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: Clone repository - uses: actions/checkout@v2 - with: - submodules: false - persist-credentials: false - - - name: Set up Deno - uses: denoland/setup-deno@v1 - with: - deno-version: vx.x.x - - - name: Format - run: deno fmt - - - name: Lint - run: deno lint diff --git a/.gitignore b/.gitignore index 451fb35..9eb8abc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .env -.idea \ No newline at end of file + +# Added by cargo +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6d21b2a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2143 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "aquamarine" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a941c39708478e8eea39243b5983f1c42d2717b3620ee91f4a52115fd02ac43f" +dependencies = [ + "itertools", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "crates_io_api" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0346712abc6ffc5b287637815c838f6126ff62df37f12806fa029e66c0ec285c" +dependencies = [ + "chrono", + "futures", + "reqwest", + "serde", + "serde_derive", + "serde_json", + "serde_path_to_error", + "tokio", + "url", +] + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "dptree" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d81175dab5ec79c30e0576df2ed2c244e1721720c302000bb321b107e82e265c" +dependencies = [ + "futures", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "erasable" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f11890ce181d47a64e5d1eb4b6caba0e7bae911a356723740d058a5d0340b7d" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "errno" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "iri-string" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "9.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "155c4d7e39ad04c172c5e3a99c434ea3b4a7ba7960b38ecd562b270b097cce09" +dependencies = [ + "base64", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "linux-raw-sys" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "never" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "octocrab" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfeeafb5fa0da7046229ec3c7b3bd2981aae05c549871192c408d59fc0fffd5" +dependencies = [ + "arc-swap", + "async-trait", + "base64", + "bytes", + "cfg-if", + "chrono", + "either", + "futures", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-timeout", + "jsonwebtoken", + "once_cell", + "percent-encoding", + "pin-project", + "secrecy", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "snafu", + "tokio", + "tower", + "tower-http", + "tracing", + "url", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "pem" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3163d2912b7c3b52d651a055f2c7eec9ba5cd22d26ef75b8dd3a59980b185923" +dependencies = [ + "base64", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "pretty_env_logger" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rc-box" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0690759eabf094030c2cdabc25ade1395bac02210d920d655053c1d49583fd8" +dependencies = [ + "erasable", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "winreg", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustina" +version = "0.1.0" +dependencies = [ + "crates_io_api", + "log", + "octocrab", + "pretty_env_logger", + "serde", + "serde_json", + "teloxide", + "tokio", + "url", + "uuid", +] + +[[package]] +name = "rustix" +version = "0.38.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.21.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "snafu" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +dependencies = [ + "backtrace", + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "takecell" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20f34339676cdcab560c9a82300c4c2581f68b9369aedf0fae86f2ff9565ff3e" + +[[package]] +name = "teloxide" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c63345cf32a8850ebddcdd769dc2d5193d5e231262d5dada264b79da01a664da" +dependencies = [ + "aquamarine", + "bytes", + "derive_more", + "dptree", + "futures", + "log", + "mime", + "pin-project", + "serde", + "serde_json", + "serde_with_macros", + "teloxide-core", + "teloxide-macros", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "url", +] + +[[package]] +name = "teloxide-core" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "303db260110c238e3af77bb9dff18bf7a5b5196f783059b0852aab75f91d5a16" +dependencies = [ + "bitflags 1.3.2", + "bytes", + "chrono", + "derive_more", + "either", + "futures", + "log", + "mime", + "never", + "once_cell", + "pin-project", + "rc-box", + "reqwest", + "serde", + "serde_json", + "serde_with_macros", + "take_mut", + "takecell", + "thiserror", + "tokio", + "tokio-util", + "url", + "uuid", +] + +[[package]] +name = "teloxide-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1d653b093dba5e44cada57a516f572167df37b8a619443e59c8c517bb6d804" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "bitflags 2.4.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "getrandom", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "wasm-streams" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f1a754b --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "rustina" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +teloxide = { version = "0.12", features = ["macros"] } +log = "0.4" +pretty_env_logger = "0.5.0" +tokio = { version = "1.8", features = ["rt-multi-thread", "macros"] } +url = "2.4.1" +crates_io_api = "0.8.2" +uuid = { version = "1.5.0", features = ["v4"] } +serde_json = "1.0.108" +serde = { version = "1.0.192", features = ["derive"] } +octocrab = { version = "0.32.0" } diff --git a/core.ts b/core.ts deleted file mode 100644 index 97f1ae1..0000000 --- a/core.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { blue, Bot, serve, webhookCallback } from "./deps.ts"; -import "./utils/config.ts"; -import env from "./utils/config.ts"; -import delta from "./delta/mod.ts"; -import { Telegraph } from "./deps.ts"; - -export const bot = new Bot(env["TOKEN"] || ""); -export const handle = webhookCallback(bot, "std/http"); -export const editor = new Telegraph({ accessToken: env["EDITOR"] }); - -const initializer = async () => { - await console.log(blue("[INFO]"), `bot is starting on ${env["HOST"]}`); - await delta(bot); - await bot.catch((error) => { - console.log(error, error.ctx.api); - }); -}; - -const webhook = async () => { - await console.log(blue("[INFO]"), `bot is starting on ${env["HOST"]}`); - await serve(async (req) => { - const url = new URL(req.url); - - if (req.method == "POST") { - switch (url.pathname) { - case "/bot": - try { - return await handle(req); - } catch (err) { - console.error(err); - return new Response("Nope, not working..."); - } - default: - return new Response("What you're trying to post?"); - } - } - - switch (url.pathname) { - case "/webhook": - try { - await bot.api.setWebhook(`https://${url.hostname}/bot`); - return new Response("Done. Set"); - } catch (_) { - return new Response("Couldn't succeed with installing webhook"); - } - default: - return Response.redirect("https://t.me/rustinabot", 302); - } - }); -}; - -const polling = async () => { - await bot.start(); -}; - -export const launch = async () => { - switch (env["HOST"]) { - case "WEBHOOK": - await initializer(); - await webhook(); - break; - case "POLLING": - await initializer(); - await polling(); - break; - default: - throw new Error("Deploy method not validated!"); - } -}; - -await launch(); diff --git a/delta/about.ts b/delta/about.ts deleted file mode 100644 index e695119..0000000 --- a/delta/about.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import isPrivate from "../hooks/isPrivate.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); - -export const message = `Hurmatli foydalanuvchi! \n` + - `\n` + - `Bizning botimiz aktiv tarzda shakllantirib boriladi. ` + - `Buning ustida esa bir necha avtor va dasturchilar turadi, ` + - `ushbu havolalar orqali bizning sinovchilarimizdan biriga aylaning ` + - `va biz bilan botimiz, hamda guruhimiz ishlatish qulayligini oshiring.`; - -export const keyboard = new InlineKeyboard().url( - `Ochiq Havolalar`, - `https://github.com/rust-lang-uz/rustina`, -); - -composer.command("about", isPrivate, async (ctx: Context): Promise => { - await reply(ctx, message, keyboard); -}); - -export default composer; diff --git a/delta/channel.ts b/delta/channel.ts deleted file mode 100644 index 19e1991..0000000 --- a/delta/channel.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Composer, Context } from "../deps.ts"; - -const composer = new Composer(); - -composer.on("message:text", async (ctx: Context): Promise => { - if (ctx?.message?.from?.username) { - if ( - ctx?.message?.from?.username === "Channel_Bot" - ) { - await ctx.deleteMessage(); - } - } -}); - -export default composer; diff --git a/delta/groups.ts b/delta/groups.ts deleted file mode 100644 index 396a2b6..0000000 --- a/delta/groups.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import communities from "../communities.json" assert { type: "json" }; -import pager from "../utils/pager.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); -const ctxMenuText = - "Telegramdagi Rust Hamjamiyatlari yoki Guruhlari:\nAgar o'zingizni guruhingizni qo'shmoqchi bo'lsangiz, bizni community.json ni yangilang!"; - -composer.command("group", async (ctx: Context): Promise => { - const keyboard = new InlineKeyboard(); - - for (const community of pager(1)) { - keyboard.text( - community.name, - `detail_${1}_${community.telegram.replace("@", "")}`, - ).row(); - } - - if (pager(2).length > 0) { - keyboard.text(`Keyingi ➡️`, `group_2`); - } - - await reply(ctx, ctxMenuText, keyboard, { - disable_web_page_preview: true, - }); -}); - -composer.callbackQuery(/^group_(\d+)$/, async (ctx: Context) => { - const page = Number(ctx.match![1]); - const keyboard = new InlineKeyboard(); - - for (const community of pager(page)) { - keyboard.text( - community.name, - `detail_${page}_${community.telegram.replace("@", "")}`, - ).row(); - } - - if (pager(page - 1).length > 0) { - keyboard.text(`⬅️ Oldingi`, `group_${page - 1}`); - } - - if (pager(page + 1).length > 0) { - keyboard.text(`Keyingi ➡️`, `group_${page + 1}`); - } - - await ctx.editMessageText(ctxMenuText, { - parse_mode: "HTML", - reply_markup: keyboard, - disable_web_page_preview: true, - }); -}); - -composer.callbackQuery(/^detail_(\d+)_(.*)$/, async (ctx: Context) => { - const keyboard = new InlineKeyboard(); - const page = ctx.match![1]; - const result = communities.filter((com) => - com.telegram.replace("@", "") === ctx.match![2] - ); - - if (result.length) { - const data = result[0]; - - if (data.telegram) { - keyboard.url( - `Telegram`, - `https://t.me/${data.telegram.replace("@", "")}`, - ); - } - - if (data.link) { - keyboard.url(`Web`, data.link); - } - - keyboard.row().text(`🔙 Orqaga`, `group_${page}`); - - await ctx.editMessageText( - `${data.name}` + - `\n` + - `\n` + - `${data.about}` + - `\n` + - `\n` + - `Use the following buttons to get to the links:`, - { - parse_mode: "HTML", - reply_markup: keyboard, - }, - ); - } else { - await ctx.editMessageText(`Ushbu guruh mavjud emas!`, { - parse_mode: "HTML", - reply_markup: new InlineKeyboard().text(`🔙 Orqaga`, `group_${page}`), - }); - } -}); - -export default composer; diff --git a/delta/help.ts b/delta/help.ts deleted file mode 100644 index a3f3034..0000000 --- a/delta/help.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Composer, Context } from "../deps.ts"; -import * as start from "./start.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); - -export const message = `Mavjud komandalar ro'yxati:` + - `\n` + - `\n` + - `/doc - reply qilingan odamga dok borligi haqida eslatish` + - `\n` + - `/useful - rust haqida foydali yoki kerakli ma'lumotlar` + - `\n` + - `/last - eng oxirgi reliz haqida qisqacha ma'lumot` + - `\n` + - `/version - biron anniq reliz haqida to'liq ma'lumot` + - `\n` + - `/off - reply qilingan odamga offtop borligi haqida eslatish` + - `\n` + - `/nometa - to'g'ri savol berish haqida eslatma` + - `\n` + - `/group - rust ga oid guruh va hamjamiyatlar` + - `\n` + - `/help - ushbu xabarni qayta ko'rsatish` + - `\n` + - `/about - ushbu botimizning rivojlantirish qismi` + - `\n` + - `/rules - qoidalarni aks ettirish` + - `\n` + - `/which - ushbu guruh va foydalanuvchi metrik ma'lumotlarini ko'rsatish`; -export const keyboard = start.keyboard; - -composer.command("help", async (ctx: Context): Promise => { - await reply(ctx, message, keyboard); -}); - -export default composer; diff --git a/delta/inline.ts b/delta/inline.ts deleted file mode 100644 index b350d04..0000000 --- a/delta/inline.ts +++ /dev/null @@ -1,101 +0,0 @@ -// deno-lint-ignore-file no-explicit-any -import { api, Composer, Context, InlineKeyboard } from "../deps.ts"; -import encoder from "../utils/encoder.ts"; - -const composer = new Composer(); - -composer.inlineQuery(/(.*)/ig, async (ctx: Context): Promise => { - if (ctx.inlineQuery?.query) { - const request = await api.search(ctx.inlineQuery?.query, 50); - - if (request.meta.total === 0) { - return await ctx.answerInlineQuery([{ - type: "article", - id: "404", - title: "Xatolik yuz berdi!", - description: `Ushbu ${ctx.inlineQuery?.query} ga oid natija topilmadi!`, - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "rand", - ), - input_message_content: { - message_text: - `"${ctx.inlineQuery?.query}" ga oid natija mavjud emas!` + - `\n` + - `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring!`, - parse_mode: "HTML", - disable_web_page_preview: true, - }, - }]); - } - - return await ctx.answerInlineQuery( - request.crates.map((item) => ({ - type: "article", - id: crypto.randomUUID(), - title: item.name, - url: `https://crates.io/crates/${item.id}`, - description: item.description, - reply_markup: (() => { - const keyboard = new InlineKeyboard(); - keyboard.url(`Crate`, `https://crates.io/crates/${item.name}`); - if (item.homepage) keyboard.url(`Asosiy`, item.homepage).row(); - if (item.documentation) { - keyboard.url(`Dokumentatsiya`, item.documentation).row(); - } - if (item.repository) keyboard.url(`Repozitoriya`, item.repository); - return keyboard; - })(), - input_message_content: { - message_text: `🦀 Rust Telegram Cratelari 🦀\n\n` + - `📦 Nomi: ${item.name}` + - `\n` + - `🚨 Oxirgi versiya: ${item.newest_version} \n` + - `🎚 Yuklab olingan: yaqin orada: ${item.recent_downloads} | hammasi: ${item.downloads} \n` + - `⌚️ Yaratilgan: ${ - new Date(item.created_at).toLocaleString("uz") - } \n` + - `📡 Yangilangan: ${ - new Date(item.updated_at).toLocaleString("uz") - } \n` + - `📰 Ma'lumot: ${ - (encoder(item.description)).substring(0, 100) - }${item.description.length > 100 ? "..." : ""} \n\n` + - `🔌 Cargo.toml fayliga qo'shib qo'ying: \n` + - `[dependencies]\n${item.name} = "${item.max_stable_version}"`, - parse_mode: "HTML", - disable_web_page_preview: true, - }, - })), - { cache_time: 1 }, // { cache_time: 24 * 3600 }, - ); - } - - if (!ctx.inlineQuery?.query) { - return await ctx.answerInlineQuery([{ - type: "article", - id: "101", - title: "Qidirishni boshlang!", - description: "Qidirmoqchi bo'lgan paketingiz nomini yozing!", - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "rand", - ), - input_message_content: { - message_text: `Salom foydalanuvchi!` + - `\n` + - `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz crates.io ` + - `Rust dasturlash tili paketlar registridan web sahifani ishlatmasdan turib ` + - `telegram o'zida kerakli paketlarni qidirishingiz mumkin! Ushbu qulaylik ` + - `yozish uchun o'zimizning API SDK ishlatildi` + - `Qidirishni boshlash uchun: ` + - `\n` + - `@rustaceanbot <nomi>`, - parse_mode: "HTML", - disable_web_page_preview: true, - }, - }]); - } -}); - -export default composer; diff --git a/delta/latest.ts b/delta/latest.ts deleted file mode 100644 index 38d30b3..0000000 --- a/delta/latest.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import type { Release } from "../types/Github.d.ts"; -import { last } from "../utils/generator.ts"; -import hecker from "../utils/checker.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); - -export const message = async (data: Release) => - // make a message about the release date of the new release - `Hozirgi eng oxirgi versiya bu ${data.tag_name} va ushbu reliz ${ - new Date(data.published_at).toLocaleDateString("uz") - } da e'lon qilingan ${data.author.login} tomonidan` + - `\n` + - `\n` + - `Ushbu oxirgi relizni o'rnatish uchun terminalingizda rustup update buyrug'ini ishga tushuring!`; - -export const keyboard = (data: Release) => - new InlineKeyboard().url("Ko'proq ma'lumotlar", data.html_url); - -composer.command("last", async (ctx: Context): Promise => { - const req = await last(); - await reply(ctx, await message(req), keyboard(req)); -}); - -export default composer; diff --git a/delta/mod.ts b/delta/mod.ts deleted file mode 100644 index e1a8816..0000000 --- a/delta/mod.ts +++ /dev/null @@ -1,29 +0,0 @@ -import start from "./start.ts"; -import help from "./help.ts"; -import inline from "./inline.ts"; -import which from "./which.ts"; -import { Bot } from "../deps.ts"; -import about from "./about.ts"; -import rules from "./rules.ts"; -import channel from "./channel.ts"; -import trigger from "./trigger.ts"; -import groups from "./groups.ts"; -import useful from "./useful.ts"; -import latest from "./latest.ts"; -import version from "./version.ts"; - -export default async (bot: Bot) => { - await bot - .use(start) - .use(help) - .use(inline) - .use(which) - .use(groups) - .use(useful) - .use(latest) - .use(version) - .use(about) - .use(rules) - .use(trigger) - .use(channel); -}; diff --git a/delta/rules.ts b/delta/rules.ts deleted file mode 100644 index dc2e4de..0000000 --- a/delta/rules.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import isPrivate from "../hooks/isPrivate.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); - -export const message = `Hurmatli guruh a'zosi... ` + - `\n` + - `\n` + - `Iltimos qoidalarga oz bo'lsada vaqt ajratishni unutmang, bu muhim! Ushbu guruhda quyidagi harakatlar taqiqlanadi:` + - `\n` + - `\n` + - `* Besabab bir-birini kamsitish yoki so'kinish` + - `\n` + - `* Sababsiz guruhga spam yozaverish yoki tashash` + - `\n` + - `* So'ralgan narsani yana qayta ezmalash ` + - `\n` + - `* Administratorlarga nisbatan juddayam qattiq kritika` + - `\n` + - `* Faoliyat ustidan shikoyat qilaverish yoki nolish` + - `\n` + - `\n` + - `Ushbu qoidalarni doimiy tarzda buzish, butunlay ban yoki bir necha ogohlantirishlirga olib keladi!`; - -export const keyboard = new InlineKeyboard().url( - `Guruhga qaytish`, - `https://t.me/rustlanguz`, -); - -composer.command("rules", isPrivate, async (ctx: Context): Promise => { - await reply(ctx, message, keyboard); -}); - -export default composer; diff --git a/delta/start.ts b/delta/start.ts deleted file mode 100644 index a657435..0000000 --- a/delta/start.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); - -export const message: string = - `Assalomu alaykum, hurmatli Rustacean! \n` + - `\n` + - `Sizni ko'rib turganimdan bag'oyatda xursandman. ` + - `Men O'zbek Rust jamiyati tomonidan yaratilgan bot hisoblanib, ` + - `O'zbek Rust jamiyati foydalanuvchilari uchun foydali resurslarni yetkazish, saqlash va ` + - `ularni saralash uchun xizmat qilaman.`; - -export const keyboard = new InlineKeyboard() - .url("Jamiyat", "https://t.me/rustlanguz") - .url("Web Sahifa", "https://rust-lang.uz"); - -composer.command("start", async (ctx: Context): Promise => { - await reply(ctx, message, keyboard); -}); - -export default composer; diff --git a/delta/trigger.ts b/delta/trigger.ts deleted file mode 100644 index 704de4c..0000000 --- a/delta/trigger.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import isReply from "../hooks/isReply.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); - -composer.command("off", isReply, async (ctx: Context): Promise => { - if (ctx?.message?.reply_to_message?.from?.id === ctx.me.id) { - await ctx.reply(`Ha-ha... yaxshi urinish!`); - await ctx.reply(`Ha-ha... yaxshi urinish!`, { - parse_mode: "HTML", - }); - } else { - await ctx.api.deleteMessage( - ctx.message!.chat!.id, - ctx.message!.reply_to_message!.message_id, - ); - await ctx.api.deleteMessage( - ctx.message!.chat!.id, - ctx.message!.message_id, - ); - - const message = - `Hurmatli ${ctx?.message?.reply_to_message?.from?.first_name},` + - `\n` + - `\n` + - `Tushunishim bo'yicha siz mavzudan chetlayashayabsiz. Iltimos, ` + - `quyidagi tugmachani bosish orqali bizning offtop guruhga o'tib oling! ` + - `Offtopic guruhimizda istalgan mavzuda suhbatlashish ruxsat etiladi. Boshqalarga halaqit qilmayliga 😉` + - `\n` + - `\n` + - `Hurmat ila, Rustina (Rastina)`; - - const keyboard = new InlineKeyboard().url( - `Offtop Chat`, - `https://t.me/rustlanguz_offtopic`, - ); - - await reply(ctx, message, keyboard); - } -}); - -composer.command("nometa", isReply, async (ctx: Context): Promise => { - if (ctx?.message?.reply_to_message?.from?.id === ctx.me.id) { - await ctx.reply(`Ha-ha... yaxshi urinish!`); - } else { - await ctx.api.deleteMessage( - ctx.message!.chat!.id, - ctx.message!.reply_to_message!.message_id, - ); - - await ctx.api.deleteMessage( - ctx.message!.chat!.id, - ctx.message!.message_id, - ); - - const message = - `Hurmatli ${ctx?.message?.reply_to_message?.from?.first_name},` + - `\n` + - `\n` + - `Tushunishim bo'yicha siz boshqalarni vaqtini isrof qilayabsiz. Iltimos, ` + - `quyidagi tugmachani bosish orqali to'g'ri savol berishni o'rganing! ` + - `Boshqalarni ham sizni kutgani ko'p vaqti yo'q. Hammaning vaqtini hurmat qilayliga 😉` + - `\n` + - `\n` + - `Hurmat ila, Rustina (Rastina)`; - - const keyboard = new InlineKeyboard().url( - `Nometa Qo'llanmasi`, - `https://nometa.uz/`, - ); - - await reply(ctx, message, keyboard); - } -}); - -composer.command("nonoff", isReply, async (ctx: Context): Promise => { - if (ctx?.message?.reply_to_message?.from?.id === ctx.me.id) { - await ctx.reply(`Ha-ha... yaxshi urinish!`); - } else { - await ctx.api.deleteMessage( - ctx.message!.chat!.id, - ctx.message!.reply_to_message!.message_id, - ); - - await ctx.api.deleteMessage( - ctx.message!.chat!.id, - ctx.message!.message_id, - ); - - const message = - `Hurmatli ${ctx?.message?.reply_to_message?.from?.first_name},` + - `\n` + - `\n` + - `Chunishim bo'yicha siz mavzuga kirib ketayabsiz. Iltimos, ` + - `quyidagi tugmachani bosish orqali bizning asosiy guruhga o'tib oling! ` + - `Linux haqida iloji boricha asosiy guruhimizda suhbatlashish tavsiya etiladi. Offtopchilarga halaqit qilmayliga 😉` + - `\n` + - `\n` + - `Hurmat ila, Rustina (Rastina)`; - - const keyboard = new InlineKeyboard().url( - `Asosiy Chat`, - `https://t.me/rustlanguz`, - ); - - await reply(ctx, message, keyboard); - } -}); - -composer.command("doc", isReply, async (ctx: Context): Promise => { - if (ctx?.message?.reply_to_message?.from?.id === ctx.me.id) { - await reply(ctx, `Ha-ha... yaxshi urinish!`); - } else { - const message = - `Demak, ${ctx?.message?.reply_to_message?.from?.first_name},` + - `\n` + - `\n` + - `Bir bor ekan, bir yo'q ekan... Qadim o'tgan zamonlarda dokumentatsiya ` + - `bo'lgan ekan. Aytishlariga qaraganda, undan deyarli hamma savollarga ` + - `javob olsa bo'larkanda. Yanachi, unga avtorlar shunchalik ko'p vaqt ajratishar ` + - `ekanu, lekin uni sanoqligina odam o'qisharkan. Attang...`; - - await reply(ctx, message); - } -}); - -export default composer; diff --git a/delta/useful.ts b/delta/useful.ts deleted file mode 100644 index 236b600..0000000 --- a/delta/useful.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import { - categories, - Category, - indexer, - material, - pager, -} from "../utils/picker.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); -const ctxMainMenuText = - "Rustga oid foydali materiallar:\nAgar o'zingizdan material qo'shmoqchi bo'lsangiz, bizni source.json ni yangilang!"; - -composer.command("useful", async (ctx: Context): Promise => { - const keyboard = new InlineKeyboard(); - - for (const category of categories()) { - keyboard.text( - category.charAt(0).toUpperCase() + category.slice(1).replaceAll("_", " "), - `category_${category}_1`, - ).row(); - } - - await reply(ctx, ctxMainMenuText, keyboard, { - disable_web_page_preview: true, - }); -}); - -composer.callbackQuery("useful", async (ctx: Context): Promise => { - const keyboard = new InlineKeyboard(); - - for (const category of categories()) { - keyboard.text( - category.charAt(0).toUpperCase() + category.slice(1).replaceAll("_", " "), - `category_${category}_1`, - ).row(); - } - - await ctx.editMessageText(ctxMainMenuText, { - parse_mode: "HTML", - reply_markup: keyboard, - disable_web_page_preview: true, - }); -}); - -composer.callbackQuery(/^category_(.*)_(\d+)$/, async (ctx: Context) => { - const page = Number(ctx.match![2]); - const category = ctx.match![1] as Category; - const keyboard = new InlineKeyboard(); - - for (const material of pager(category, page)) { - keyboard.text( - material.name, - `material_${page}_${category}_${indexer(category, material)}`, - ).row(); - } - - if (pager(category, page - 1).length > 0) { - keyboard.text(`⬅️ Oldingi`, `category_${category}_${page - 1}`); - } - - if (pager(category, page + 1).length > 0) { - keyboard.text(`Keyingi ➡️`, `category_${category}_${page + 1}`); - } - - keyboard.row().text(`🔙 Orqaga`, `useful`); - - await ctx.editMessageText( - `Siz hozirda ${ - category.charAt(0).toUpperCase() + category.slice(1).replaceAll("_", " ") - } kategoriyasi ichida turibsiz.\n` + - `Iltimos, keltirilgan materiallardan birini tanlang...`, - { - parse_mode: "HTML", - reply_markup: keyboard, - disable_web_page_preview: true, - }, - ); -}); - -composer.callbackQuery(/^material_(\d+)_(.*)_(\d+)$/, async (ctx: Context) => { - const keyboard = new InlineKeyboard(); - const page = Number(ctx.match![1]); - const cat = ctx.match![2] as Category; - const index = Number(ctx.match![3]); - const result = material(cat, index); - - if (result) { - const data = result; - - if (data.link) { - keyboard.url(`Web Sahifasi`, data.link); - } - - keyboard.row().text(`🔙 Orqaga`, `category_${cat}_${page}`); - - await ctx.editMessageText( - `${data.name}` + - `\n` + - `\n` + - `${data.desc}` + - `\n` + - `\n` + - `Ushbu pastdagi tugmacha orqali lavha ga o'tib oling:`, - { - parse_mode: "HTML", - reply_markup: keyboard, - }, - ); - } else { - await ctx.editMessageText(`Ushbu material mavjud emas!`, { - parse_mode: "HTML", - reply_markup: new InlineKeyboard().text( - `🔙 Orqaga`, - `category_${cat}_${page}`, - ), - }); - } -}); - -export default composer; diff --git a/delta/version.ts b/delta/version.ts deleted file mode 100644 index ef5a680..0000000 --- a/delta/version.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import { finder, pager as generator } from "../utils/generator.ts"; -import hecker from "../utils/checker.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); -const ctxMenuText = "Rust Dasturlash tili versiyalari:"; - -composer.command("version", async (ctx: Context): Promise => { - const keyboard = new InlineKeyboard(); - - for (const release of await generator(1)) { - keyboard.text( - release.tag_name, - `changelog_${1}_${release.id}`, - ).row(); - } - - if ((await generator(2)).length > 0) { - keyboard.text(`Keyingi ➡️`, `version_2`); - } - - await reply(ctx, ctxMenuText, keyboard, { - disable_web_page_preview: true, - }); -}); - -composer.callbackQuery(/^version_(\d+)$/, async (ctx: Context) => { - const page = Number(ctx.match![1]); - const keyboard = new InlineKeyboard(); - - for (const release of await generator(page)) { - keyboard.text( - release.tag_name, - `changelog_${page}_${release.id}`, - ).row(); - } - - if (page > 1) { - keyboard.text(`⬅️ Oldingi`, `version_${page - 1}`); - } - - if ((await generator(page + 1)).length > 0) { - keyboard.text(`Keyingi ➡️`, `version_${page + 1}`); - } - - await ctx.editMessageText(ctxMenuText, { - parse_mode: "HTML", - reply_markup: keyboard, - disable_web_page_preview: true, - }); -}); - -composer.callbackQuery(/^changelog_(\d+)_(\d+)$/, async (ctx: Context) => { - const keyboard = new InlineKeyboard(); - const page = Number(ctx.match![1]); - const data = await finder(Number(ctx.match![2])); - - keyboard.url( - `📝 GitHub da o'qish`, - data.html_url, - ); - - keyboard.row().text(`🔙 Orqaga`, `version_${page}`); - - await ctx.editMessageText( - `${data.name}` + - `\n` + - `\n` + - `Yaratildi: ${ - new Date(data.created_at).toLocaleDateString("uz") - }` + - `\n` + - `E'lon qilindi: ${ - new Date(data.published_at).toLocaleDateString("uz") - }` + - `\n` + - `O'rnatish: rustup install ${data.tag_name}` + - `\n` + - `\n` + - `"Instant view" yoki quyidagi tugma orqali ko'proq ma'lumot oling:`, - { - parse_mode: "HTML", - reply_markup: keyboard, - }, - ); -}); - -export default composer; diff --git a/delta/which.ts b/delta/which.ts deleted file mode 100644 index 180e968..0000000 --- a/delta/which.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Composer, Context } from "../deps.ts"; -import isGroup from "../hooks/isGroup.ts"; -import { reply } from "../utils/sender.ts"; - -const composer = new Composer(); - -composer.command("which", isGroup, async (ctx: Context): Promise => { - const status = (await ctx.getChatMember(ctx!.from!.id)).status; - - const message = `Rustacean ${ctx!.from!.first_name} metrikasi:` + - `\n` + - `\n` + - `Ismi: ${ctx!.from!.first_name} ` + `\n` + - (ctx?.from?.username && "Username: @" + ctx.from.username + `\n`) + - (ctx?.chat?.id && `Chat ID: ${ctx.chat.id}` + `\n`) + - `Status: ${status}`; - - await reply(ctx, message); -}); - -export default composer; diff --git a/deno.json b/deno.json deleted file mode 100644 index ab4c52b..0000000 --- a/deno.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "fmt": { - "exclude": [ - "all.json" - ] - } -} diff --git a/deno.lock b/deno.lock deleted file mode 100644 index 3e074d1..0000000 --- a/deno.lock +++ /dev/null @@ -1,182 +0,0 @@ -{ - "version": "2", - "remote": { - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=imports/optimized/@grammyjs/types.js": "fabf6997a3adf11e45d11e3c4d58d0634ab98f9d72f3116f3694123818ccd457", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/api.d.ts": "8198d0f61fe0c0b35d824e10405d0b8a1d842b2e5339ef5dd6027e7b521c3047", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/bot-command-scope.d.ts": "86c5f851bfb0eb1eddf0a309710de30c307b6c5fdaf7609b1fc455d72a2b750e", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/callback.d.ts": "0b7f6c3625c80d894bf3733ada1380f7cd53e14dd9593394d584f00b6c1954c5", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/index.d.ts": "9bdbddce52c91f61c478681eda997525cb028c561bb94ead0f799f4aafb49fc6", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/inline.d.ts": "adde52500fd04693f88fecdcf069c3663954dd0baa644b9c78c1d8c8bec32559", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/manage.d.ts": "194c5c7df20f9410f3cecf97110b608dc6491fe8c4182c38e53ca95ffec58df2", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/message.d.ts": "89aa19a7621850406bbb2dbf8eb77e29581d55f1d26469646b0f03741ca7b2f4", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/passport.d.ts": "ceeffb3c37c0843cf53049343473106327994415f8f6057e02bc904a2278c57a", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/payment.d.ts": "163170c512d0f7bdd56dc6eb021c172fffcddb8e2742318e6f3973a27962e2d0", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/proxied.d.ts": "7bbfd1f2431ec17f980b719568aeb6cde2dbbfcd67532149fe8b8933251dfec3", - "https://cdn.skypack.dev/-/@grammyjs/types@v2.6.0-cPMaGVlPbprnM8Sq7dE3/dist=es2019,mode=types/update.d.ts": "73b0130f0a488e54f6537eac633fc5cad4b7e50fdcd620c82cc1776457930e4d", - "https://cdn.skypack.dev/-/debug@v4.3.4-o4liVvMlOnQWbLSYZMXw/dist=es2019,mode=imports/optimized/debug.js": "671100993996e39b501301a87000607916d4d2d9f8fc8e9c5200ae5ba64a1389", - "https://cdn.skypack.dev/-/ms@v2.1.2-giBDZ1IA5lmQ3ZXaa87V/dist=es2019,mode=imports/optimized/ms.js": "fd88e2d51900437011f1ad232f3393ce97db1b87a7844b3c58dd6d65562c1276", - "https://cdn.skypack.dev/@grammyjs/types@v2.6.0?dts": "2871c1b8a348fcc9a3752158b2e2f9c618fe2ca9176edbaa9cf18454434f51db", - "https://cdn.skypack.dev/debug@4.3.4": "7b1d010cc930f71b940ba5941da055bc181115229e29de7214bdb4425c68ea76", - "https://cdn.skypack.dev/debug@^4.3.3": "7b1d010cc930f71b940ba5941da055bc181115229e29de7214bdb4425c68ea76", - "https://deno.land/std@0.123.0/_util/assert.ts": "2f868145a042a11d5ad0a3c748dcf580add8a0dbc0e876eaa0026303a5488f58", - "https://deno.land/std@0.123.0/_util/os.ts": "dfb186cc4e968c770ab6cc3288bd65f4871be03b93beecae57d657232ecffcac", - "https://deno.land/std@0.123.0/async/deferred.ts": "ab60d46ba561abb3b13c0c8085d05797a384b9f182935f051dc67136817acdee", - "https://deno.land/std@0.123.0/bytes/bytes_list.ts": "3bff6a09c72b2e0b1e92e29bd3b135053894196cca07a2bba842901073efe5cb", - "https://deno.land/std@0.123.0/bytes/equals.ts": "69f55fdbd45c71f920c1a621e6c0865dc780cd8ae34e0f5e55a9497b70c31c1b", - "https://deno.land/std@0.123.0/bytes/mod.ts": "fedb80b8da2e7ad8dd251148e65f92a04c73d6c5a430b7d197dc39588c8dda6f", - "https://deno.land/std@0.123.0/io/buffer.ts": "8f10342821b81990acf859cdccb4e4031c7c9187a0ffc3ed6b356ee29ecc6681", - "https://deno.land/std@0.123.0/io/types.d.ts": "89a27569399d380246ca7cdd9e14d5e68459f11fb6110790cc5ecbd4ee7f3215", - "https://deno.land/std@0.123.0/path/_constants.ts": "1247fee4a79b70c89f23499691ef169b41b6ccf01887a0abd131009c5581b853", - "https://deno.land/std@0.123.0/path/_interface.ts": "1fa73b02aaa24867e481a48492b44f2598cd9dfa513c7b34001437007d3642e4", - "https://deno.land/std@0.123.0/path/_util.ts": "2e06a3b9e79beaf62687196bd4b60a4c391d862cfa007a20fc3a39f778ba073b", - "https://deno.land/std@0.123.0/path/common.ts": "f41a38a0719a1e85aa11c6ba3bea5e37c15dd009d705bd8873f94c833568cbc4", - "https://deno.land/std@0.123.0/path/glob.ts": "7bf2349e818e332a830f3d8874c3f45dd7580b6c742ed50dbf6282d84ab18405", - "https://deno.land/std@0.123.0/path/mod.ts": "4465dc494f271b02569edbb4a18d727063b5dbd6ed84283ff906260970a15d12", - "https://deno.land/std@0.123.0/path/posix.ts": "34349174b9cd121625a2810837a82dd8b986bbaaad5ade690d1de75bbb4555b2", - "https://deno.land/std@0.123.0/path/separator.ts": "8fdcf289b1b76fd726a508f57d3370ca029ae6976fcde5044007f062e643ff1c", - "https://deno.land/std@0.123.0/path/win32.ts": "11549e8c6df8307a8efcfa47ad7b2a75da743eac7d4c89c9723a944661c8bd2e", - "https://deno.land/std@0.123.0/streams/conversion.ts": "7ff9af42540063fa72003ab31a377ba9dde8532d43b16329b933c37a6d7aac5f", - "https://deno.land/std@0.123.0/streams/delimiter.ts": "25a35824fffaaf620f7304bf4522eb4fc8b205a9e98120e8956ea113ec6898aa", - "https://deno.land/std@0.123.0/streams/merge.ts": "493cee5e547f6f0304d1891f3126701e707c0162f375b5bf26d8541b08e52c62", - "https://deno.land/std@0.123.0/streams/mod.ts": "fb4b333ae079bfaefa7601ac4b6f591ab6ddfbdd47f5cb10f6280cfba892bf96", - "https://deno.land/std@0.128.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0", - "https://deno.land/std@0.128.0/async/debounce.ts": "564273ef242bcfcda19a439132f940db8694173abffc159ea34f07d18fc42620", - "https://deno.land/std@0.128.0/async/deferred.ts": "bc18e28108252c9f67dfca2bbc4587c3cbf3aeb6e155f8c864ca8ecff992b98a", - "https://deno.land/std@0.128.0/async/delay.ts": "cbbdf1c87d1aed8edc7bae13592fb3e27e3106e0748f089c263390d4f49e5f6c", - "https://deno.land/std@0.128.0/async/mod.ts": "a28709190a1966cb50e5815ef269bb588ee192373cde73b1096641820dc52a36", - "https://deno.land/std@0.128.0/async/mux_async_iterator.ts": "f4d1d259b0c694d381770ddaaa4b799a94843eba80c17f4a2ec2949168e52d1e", - "https://deno.land/std@0.128.0/async/pool.ts": "97b0dd27c69544e374df857a40902e74e39532f226005543eabacb551e277082", - "https://deno.land/std@0.128.0/async/tee.ts": "1341feb1f5b1a96f8628d0f8fc07d8c43d3813423f18a63bf1b4785568d21b1f", - "https://deno.land/std@0.128.0/fmt/colors.ts": "4575bb20edc666d3ae75fa9fac75f20e4cd423b280008094b05e423cc85047bb", - "https://deno.land/std@0.128.0/http/server.ts": "10c3a7814666cdbabd6f9c18acdcc4593e222275a628280a4868881445fbb5bc", - "https://deno.land/std@0.184.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", - "https://deno.land/std@0.184.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", - "https://deno.land/std@0.184.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8", - "https://deno.land/std@0.184.0/bytes/bytes_list.ts": "31d664f4d42fa922066405d0e421c56da89d751886ee77bbe25a88bf0310c9d0", - "https://deno.land/std@0.184.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", - "https://deno.land/std@0.184.0/io/buffer.ts": "17f4410eaaa60a8a85733e8891349a619eadfbbe42e2f319283ce2b8f29723ab", - "https://deno.land/std@0.184.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", - "https://deno.land/std@0.184.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", - "https://deno.land/std@0.184.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", - "https://deno.land/std@0.184.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", - "https://deno.land/std@0.184.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", - "https://deno.land/std@0.184.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c", - "https://deno.land/std@0.184.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", - "https://deno.land/std@0.184.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", - "https://deno.land/std@0.184.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", - "https://deno.land/std@0.184.0/streams/_common.ts": "f45cba84f0d813de3326466095539602364a9ba521f804cc758f7a475cda692d", - "https://deno.land/std@0.184.0/streams/buffer.ts": "d5b3d7d0299114e5b2ea895a8bf202a687fd915c5282f8096c7bae23b5a04407", - "https://deno.land/std@0.184.0/streams/byte_slice_stream.ts": "225d57263a34325d7c96cb3dafeb478eec0e6fd05cd0458d678752eadd132bb4", - "https://deno.land/std@0.184.0/streams/copy.ts": "75cbc795ff89291df22ddca5252de88b2e16d40c85d02840593386a8a1454f71", - "https://deno.land/std@0.184.0/streams/delimiter_stream.ts": "f69e849b3d1f59f02424497273f411105a6f76a9f13da92aeeb9a2d554236814", - "https://deno.land/std@0.184.0/streams/early_zip_readable_streams.ts": "4005fa74162b943f79899e5d7cb96adcbc0a6b867f9144974ed12d30e0a556e1", - "https://deno.land/std@0.184.0/streams/iterate_reader.ts": "bbec1d45c2df2c0c5920bad0549351446fdc8e0886d99e95959b259dbcdb6072", - "https://deno.land/std@0.184.0/streams/limited_bytes_transform_stream.ts": "05dc592ffaab83257494d22dd53917e56243c26e5e3129b3f13ddbbbc4785048", - "https://deno.land/std@0.184.0/streams/limited_transform_stream.ts": "d69ab790232c1b86f53621ad41ef03c235f2abb4b7a1cd51960ad6e12ee55e38", - "https://deno.land/std@0.184.0/streams/merge_readable_streams.ts": "5d6302888f4bb0616dafb5768771be0aec9bedc05fbae6b3d726d05ffbec5b15", - "https://deno.land/std@0.184.0/streams/mod.ts": "c07ec010e700b9ea887dc36ca08729828bc7912f711e4054e24d33fd46282252", - "https://deno.land/std@0.184.0/streams/read_all.ts": "ee319772fb0fd28302f97343cc48dfcf948f154fd0d755d8efe65814b70533be", - "https://deno.land/std@0.184.0/streams/readable_stream_from_iterable.ts": "cd4bb9e9bf6dbe84c213beb1f5085c326624421671473e410cfaecad15f01865", - "https://deno.land/std@0.184.0/streams/readable_stream_from_reader.ts": "bfc416c4576a30aac6b9af22c9dc292c20c6742141ee7c55b5e85460beb0c54e", - "https://deno.land/std@0.184.0/streams/reader_from_iterable.ts": "55f68110dce3f8f2c87b834d95f153bc904257fc65175f9f2abe78455cb8047c", - "https://deno.land/std@0.184.0/streams/reader_from_stream_reader.ts": "fa4971e5615a010e49492c5d1688ca1a4d17472a41e98b498ab89a64ebd7ac73", - "https://deno.land/std@0.184.0/streams/text_delimiter_stream.ts": "20e680ab8b751390e359288ce764f9c47d164af11a263870746eeca4bc7d976b", - "https://deno.land/std@0.184.0/streams/text_line_stream.ts": "0f2c4b33a5fdb2476f2e060974cba1347cefe99a4af33c28a57524b1a34750fa", - "https://deno.land/std@0.184.0/streams/to_transform_stream.ts": "7f55fc0b14cf3ed0f8d10d8f41d05bdc40726e44a65c37f58705d10a615f0159", - "https://deno.land/std@0.184.0/streams/writable_stream_from_writer.ts": "56fff5c82fb736fdd669b567cc0b2bbbe0351002cd13254eae26c366e2bed89a", - "https://deno.land/std@0.184.0/streams/write_all.ts": "aec90152978581ea62d56bb53a5cbf487e6a89c902f87c5969681ffbdf32b998", - "https://deno.land/std@0.184.0/streams/writer_from_stream_writer.ts": "07c7ee025151a190f37fc42cbb01ff93afc949119ebddc6e0d0df14df1bf6950", - "https://deno.land/std@0.184.0/streams/zip_readable_streams.ts": "a9d81aa451240f79230add674809dbee038d93aabe286e2d9671e66591fc86ca", - "https://deno.land/std@0.184.0/types.d.ts": "dbaeb2c4d7c526db9828fc8df89d8aecf53b9ced72e0c4568f97ddd8cda616a4", - "https://deno.land/std@0.188.0/async/abortable.ts": "fd682fa46f3b7b16b4606a5ab52a7ce309434b76f820d3221bdfb862719a15d7", - "https://deno.land/std@0.188.0/async/deadline.ts": "58f72a3cc0fcb731b2cc055ba046f4b5be3349ff6bf98f2e793c3b969354aab2", - "https://deno.land/std@0.188.0/async/debounce.ts": "adab11d04ca38d699444ac8a9d9856b4155e8dda2afd07ce78276c01ea5a4332", - "https://deno.land/std@0.188.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8", - "https://deno.land/std@0.188.0/async/delay.ts": "73aa04cec034c84fc748c7be49bb15cac3dd43a57174bfdb7a4aec22c248f0dd", - "https://deno.land/std@0.188.0/async/mod.ts": "f04344fa21738e5ad6bea37a6bfffd57c617c2d372bb9f9dcfd118a1b622e576", - "https://deno.land/std@0.188.0/async/mux_async_iterator.ts": "70c7f2ee4e9466161350473ad61cac0b9f115cff4c552eaa7ef9d50c4cbb4cc9", - "https://deno.land/std@0.188.0/async/pool.ts": "f1b8d3df4d7fd3c73f8cbc91cc2e8b8e950910f1eab94230b443944d7584c657", - "https://deno.land/std@0.188.0/async/retry.ts": "dd19d93033d8eaddbfcb7654c0366e9d3b0a21448bdb06eba4a7d8a8cf936a92", - "https://deno.land/std@0.188.0/async/tee.ts": "47e42d35f622650b02234d43803d0383a89eb4387e1b83b5a40106d18ae36757", - "https://deno.land/std@0.188.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", - "https://deno.land/std@0.188.0/http/server.ts": "1b23463b5b36e4eebc495417f6af47a6f7d52e3294827a1226d2a1aab23d9d20", - "https://deno.land/x/crates@v1.0.1/api.ts": "5166e6c9867e577bdb4183e7a099739469a854850f1ea7fc45c759d89bb7f789", - "https://deno.land/x/crates@v1.0.1/client.ts": "1448f7658dc2740b6a8d65cb3fb172c86d2506b0c4fa3cd5305d7b4f6d343c92", - "https://deno.land/x/crates@v1.0.1/mod.ts": "0ac461462f26518ef47fca42cc87c3c3e2f607231479fb85e3356e1310cba43f", - "https://deno.land/x/crates@v1.0.1/types/info.ts": "0204979bb2e9785245748e4a54bab6aca2b1bba4f1cdac58e8a70f0225025fd3", - "https://deno.land/x/crates@v1.0.1/types/mod.ts": "ab02d523917e8cc1398ba1e73f8557efaaa7beefec3c78c87451abb85b5e1c79", - "https://deno.land/x/crates@v1.0.1/types/search.ts": "fafa578a104ca199f2c49397de90baff0722d11268345a140ad74a57a903ce38", - "https://deno.land/x/deno_dom@v0.1.38/build/deno-wasm/deno-wasm.js": "98b1ad24a1c13284557917659402202e5c5258ab1431b3f3a82434ad36ffa05a", - "https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts": "bfd999a493a6974e9fca4d331bee03bfb68cfc600c662cd0b48b21d67a2a8ba0", - "https://deno.land/x/deno_dom@v0.1.38/src/api.ts": "0ff5790f0a3eeecb4e00b7d8fbfa319b165962cf6d0182a65ba90f158d74f7d7", - "https://deno.land/x/deno_dom@v0.1.38/src/constructor-lock.ts": "59714df7e0571ec7bd338903b1f396202771a6d4d7f55a452936bd0de9deb186", - "https://deno.land/x/deno_dom@v0.1.38/src/deserialize.ts": "f4d34514ca00473ca428b69ad437ba345925744b5d791cb9552e2d7a0e7b0439", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/document-fragment.ts": "a40c6e18dd0efcf749a31552c1c9a6f7fa614452245e86ee38fc92ba0235e5ae", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/document.ts": "b8f4e4ccabaaa063d6562a0f2f8dea9c0419515d63d8bd79bfde95f7cd64bd93", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/dom-parser.ts": "609097b426f8c2358f3e5d2bca55ed026cf26cdf86562e94130dfdb0f2537f92", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/element.ts": "77c454e228dfeb5c570da5aa61d91850400116bfa0f5a85505acdd3c667171a4", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/elements/html-template-element.ts": "127bb291bb08afeb7e9a66294a5aa6ff2780f4eb4601fa6f7869fe8b70a81472", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/html-collection.ts": "ae90197f5270c32074926ad6cf30ee07d274d44596c7e413c354880cebce8565", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/node-list.ts": "4c6e4b4585301d4147addaccd90cb5f5a80e8d6290a1ba7058c5e3dfea16e15d", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/node.ts": "3069e6fc93ac4111a136ed68199d76673339842b9751610ba06f111ba7dc10a7", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/selectors/custom-api.ts": "852696bd58e534bc41bd3be9e2250b60b67cd95fd28ed16b1deff1d548531a71", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/selectors/nwsapi-types.ts": "c43b36c36acc5d32caabaa54fda8c9d239b2b0fcbce9a28efb93c84aa1021698", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/selectors/nwsapi.js": "985d7d8fc1eabbb88946b47a1c44c1b2d4aa79ff23c21424219f1528fa27a2ff", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/selectors/selectors.ts": "83eab57be2290fb48e3130533448c93c6c61239f2a2f3b85f1917f80ca0fdc75", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/selectors/sizzle-types.ts": "78149e2502409989ce861ed636b813b059e16bc267bb543e7c2b26ef43e4798b", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/selectors/sizzle.js": "c3aed60c1045a106d8e546ac2f85cc82e65f62d9af2f8f515210b9212286682a", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/utils-types.ts": "96db30e3e4a75b194201bb9fa30988215da7f91b380fca6a5143e51ece2a8436", - "https://deno.land/x/deno_dom@v0.1.38/src/dom/utils.ts": "55f3e9dc71d6c4a54605888d3f99d26fb0cf9973924709f159252a6933ceeabe", - "https://deno.land/x/deno_dom@v0.1.38/src/parser.ts": "b65eb7e673fa7ca611de871de109655f0aa9fa35ddc1de73df1a5fc2baafc332", - "https://deno.land/x/dotenv@v3.2.0/mod.ts": "077b48773de9205266a0b44c3c3a3c3083449ed64bb0b6cc461b95720678d38e", - "https://deno.land/x/dotenv@v3.2.0/util.ts": "693730877b13f8ead2b79b2aa31e2a0652862f7dc0c5f6d2f313f4d39c7b7670", - "https://deno.land/x/grammy@v1.16.1/bot.ts": "885e3b11a5bb16f923dc09d9351bdf2d2bda8cb29dc1c85d0c3930d59b256f68", - "https://deno.land/x/grammy@v1.16.1/composer.ts": "1d2e164f9934466553d7f9bf9bf2fe65a1f453b7f7ce3cf57066d87382c6dac2", - "https://deno.land/x/grammy@v1.16.1/context.ts": "eb582b86219d66979c0a1ff06b3c705f7418157687d2f92c74bceabdae968dbf", - "https://deno.land/x/grammy@v1.16.1/convenience/frameworks.ts": "f5cc53bd8f2b939b847997f5a6fd1043f5be0b69747f2039eed79a76cd1ec719", - "https://deno.land/x/grammy@v1.16.1/convenience/keyboard.ts": "5d284a61750731e413bd7292c07e48ce1b3e4e69cee87372e3dc69faae7d8b4d", - "https://deno.land/x/grammy@v1.16.1/convenience/session.ts": "f9b7a0737cb813810731a3c29c3f5f84a457f493f9e7651e132daab9b58b08e9", - "https://deno.land/x/grammy@v1.16.1/convenience/webhook.ts": "f1da7d6426171fb7b5d5f6b59633f91d3bab9a474eea821f714932650965eb9e", - "https://deno.land/x/grammy@v1.16.1/core/api.ts": "5d2f479696e273d41a7f87fbf174a9cef7e82f1b7d25e73e8b505dc24c80e423", - "https://deno.land/x/grammy@v1.16.1/core/client.ts": "8914f13b2cb69f16104a9711e4fea0a4500edd0950736dcc3ac078ab46f7a5ab", - "https://deno.land/x/grammy@v1.16.1/core/error.ts": "4638b2127ebe60249c78b83011d468f5e1e1a87748d32fe11a8200d9f824ad13", - "https://deno.land/x/grammy@v1.16.1/core/payload.ts": "420e17c3c2830b5576ea187cfce77578fe09f1204b25c25ea2f220ca7c86e73b", - "https://deno.land/x/grammy@v1.16.1/filter.ts": "2c341f376bff726ca300e547843abcd989219cd10a05ae612844efaaa2cefe50", - "https://deno.land/x/grammy@v1.16.1/mod.ts": "6d96b0c7b4c8b9448b9f9903a95a78c3379febd36b0f6485ad567d79b153c794", - "https://deno.land/x/grammy@v1.16.1/platform.deno.ts": "a6b2425761dd47067de3ad342754b598dc9d931e8bbeb94e647508905e295b20", - "https://deno.land/x/grammy@v1.16.1/types.deno.ts": "b7378afc2779a4e6aecb274bee0fcf5c69968b0074627686d7ff7e4dba6b7022", - "https://deno.land/x/grammy@v1.16.1/types.ts": "729415590dfa188dbe924dea614dff4e976babdbabb28a307b869fc25777cdf0", - "https://deno.land/x/grammy@v1.7.0/bot.ts": "9e368e705feb87b5a17c312c57eae5421322c4f5249bbc8f179b9bd919386ffc", - "https://deno.land/x/grammy@v1.7.0/composer.ts": "6a70b043b58fe509b0607b2e1a2b9e721327645b94c350c278e50417bc3731b9", - "https://deno.land/x/grammy@v1.7.0/context.ts": "9252605b86c0fc9a4e431857dd808ce88d7868ef9e7d7e60ecd9544c569445a4", - "https://deno.land/x/grammy@v1.7.0/convenience/frameworks.deno.ts": "aa4e1df1dd5c610e900ff3779f0b320e6e688cd067900f71c000c34138ff023c", - "https://deno.land/x/grammy@v1.7.0/convenience/keyboard.ts": "39fe5119085de94bcd4b0b8a216b254afa8dda8595d73052355590ee943d8d17", - "https://deno.land/x/grammy@v1.7.0/convenience/session.ts": "e44b538eb8cffacf68c75d158c2a504c9077560bd0ff385430161385173ac1df", - "https://deno.land/x/grammy@v1.7.0/convenience/webhook.ts": "07c23c5830f49e42c2f33a49a3100f7ba69d54d6f23770b43eda5b5d608de77d", - "https://deno.land/x/grammy@v1.7.0/core/api.ts": "ed32fbefb98935657f92efed4feb97057379bbb2b1558ca0ceec9d758a2bf0c2", - "https://deno.land/x/grammy@v1.7.0/core/client.ts": "9f30bf49573c30af4f379388f620b6f511acd7fbae1cb998168d8c046b96e15f", - "https://deno.land/x/grammy@v1.7.0/core/error.ts": "400bb976677f0ce620402b025fef36887395760c00a74c7e2c7833e074e33465", - "https://deno.land/x/grammy@v1.7.0/core/payload.ts": "294a570a432090bc8cd0cda9a6eb07682831967d2a0562d913467afff4d0b419", - "https://deno.land/x/grammy@v1.7.0/filter.ts": "0f9b3ac87ad930958578a689030a277e1ab3b7bff100bc9b236feea44e393414", - "https://deno.land/x/grammy@v1.7.0/mod.ts": "31d8dc2b34a990c05199348245c4ef441277627e3661be8c448bf92502021a33", - "https://deno.land/x/grammy@v1.7.0/platform.deno.ts": "0a6f2be374f7165ef0176066c0e31b4c004b0147681d370615c37d1cc375842e", - "https://deno.land/x/grammy_types@v3.1.1/api.ts": "efc90a31eb6f59ae5e7a4cf5838f46529e2fa6fa7e97a51a82dbd28afad21592", - "https://deno.land/x/grammy_types@v3.1.1/inline.ts": "8b94cee32f193dc5c689202a78d6525f6c167cc3e10b5e568c0315f654654586", - "https://deno.land/x/grammy_types@v3.1.1/manage.ts": "0872ba14a17318bc9a3b8911bea2f24e92bae84a9d0493251454a7b03c357614", - "https://deno.land/x/grammy_types@v3.1.1/markup.ts": "73348ed0be8926a3057fe7d9e60212326b65bb0fe7848f3cf198dd0eb42734f4", - "https://deno.land/x/grammy_types@v3.1.1/message.ts": "e21f2df52dd1948353a93db742bcc3b4deacf9f7117b70c358bde7042d79cf83", - "https://deno.land/x/grammy_types@v3.1.1/methods.ts": "91d345f824360650c1c2aaaebb1bed8bab7df0bb38570cc7a5c58f9b7bb2c658", - "https://deno.land/x/grammy_types@v3.1.1/mod.ts": "42b1229baba254db0e5b9232580940e3c14e02048d5a982d29c67d2c86dc14e0", - "https://deno.land/x/grammy_types@v3.1.1/passport.ts": "e3fb63aec96510bcc317ef48fd25b435444b8f407502d7568c00fce15f2958fd", - "https://deno.land/x/grammy_types@v3.1.1/payment.ts": "d23e9038c5b479b606e620dd84e3e67b6642ada110a962f2d5b5286e99ec7de5", - "https://deno.land/x/grammy_types@v3.1.1/settings.ts": "5e989f5bd6c587d55673bd8052293869aa2f372e9223dd7f6e28632bfe021b6e", - "https://deno.land/x/grammy_types@v3.1.1/update.ts": "b60c2aa5f8060a3fa429dda282cb5c7267899fa17bb9000e248f31abadfb5087", - "https://deno.land/x/marky@v1.1.6/marky.ts": "9c90564d79a7a4d704faef20ac97619cd20b967e48885351b6ef8a22ffdf99eb", - "https://deno.land/x/marky@v1.1.6/mod.ts": "fcae8411be5ae4399695689883dc09d0f279d59369f4562a9f2762d47cce39f4", - "https://deno.land/x/marky@v1.1.6/parsers.ts": "494d7611f2d316cfe8c2f88abd1558ddb5afb62b7af89f71f39c3154919169a7", - "https://deno.land/x/telegraph@v1.0.2/deps.ts": "990bc76aad450e24e0a7817aa09160f68f6b670121d4528a26cdb16654cd3b0f", - "https://deno.land/x/telegraph@v1.0.2/src/parse.ts": "628abafbc08d9580b229ec0c316aa6d8ab2591eda7165c3c8b6c074760cbf629", - "https://deno.land/x/telegraph@v1.0.2/src/telegraph.ts": "c6e282ba4fee683a35c242b1f12b505e51519deca5cb42746b7eaf6d6ca6e0b9", - "https://deno.land/x/telegraph@v1.0.2/src/types.ts": "6c46ce878850c652244d0b0be2d2ec264092b1bfd282de5da0ff349c2240ca45" - } -} diff --git a/deps.ts b/deps.ts deleted file mode 100644 index 3d734fd..0000000 --- a/deps.ts +++ /dev/null @@ -1,22 +0,0 @@ -export { - Bot, - Composer, - Context, - InlineKeyboard, - InputFile, - webhookCallback, -} from "https://deno.land/x/grammy@v1.16.1/mod.ts"; -export { - blue, - bold, - green, - red, - yellow, -} from "https://deno.land/std@0.188.0/fmt/colors.ts"; -export { config } from "https://deno.land/x/dotenv@v3.2.0/mod.ts"; -export { serve } from "https://deno.land/std@0.188.0/http/server.ts"; -export type { NextFunction } from "https://deno.land/x/grammy@v1.16.1/mod.ts"; -export { api, Types } from "https://deno.land/x/crates@v1.0.1/mod.ts"; -export type { Page } from "https://deno.land/x/telegraph@v1.0.2/src/types.ts"; -export { parseMarkdown } from "https://deno.land/x/telegraph@v1.0.2/src/parse.ts"; -export { Telegraph } from "https://deno.land/x/telegraph@v1.0.2/src/telegraph.ts"; diff --git a/hooks/isGroup.ts b/hooks/isGroup.ts deleted file mode 100644 index f581b98..0000000 --- a/hooks/isGroup.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Context, NextFunction } from "../deps.ts"; - -export default async (ctx: Context, next: NextFunction) => { - if (ctx.chat!.type === "private") { - return await ctx.reply(`⚠️ Bu komanda faqat guruh uchun!`); - } - await next(); -}; diff --git a/hooks/isHome.ts b/hooks/isHome.ts deleted file mode 100644 index 2f20ea3..0000000 --- a/hooks/isHome.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Context, InlineKeyboard, NextFunction } from "../deps.ts"; -import { reply } from "../utils/sender.ts"; - -export default async (ctx: Context, next: NextFunction) => { - if (ctx.chat!.id !== -1001518595284) { - return await reply( - ctx, - `⚠️ Bu komanda faqat o'zimizni guruh uchun`, - new InlineKeyboard().url( - `Guruhimizga o'ting`, - `https://t.me/rustlanguz`, - ), - ); - } - await next(); -}; diff --git a/hooks/isPrivate.ts b/hooks/isPrivate.ts deleted file mode 100644 index a629120..0000000 --- a/hooks/isPrivate.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Context, InlineKeyboard, NextFunction } from "../deps.ts"; - -export default async (ctx: Context, next: NextFunction) => { - if (ctx.chat!.type !== "private") { - return await ctx.reply(`⚠️ Bu komanda faqat shaxsiy chat uchun!`, { - reply_markup: new InlineKeyboard().url( - `Shaxsiy Chat`, - `https://t.me/rustlanguz`, - ), - }); - } - await next(); -}; diff --git a/hooks/isReply.ts b/hooks/isReply.ts deleted file mode 100644 index 2f112c4..0000000 --- a/hooks/isReply.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { reply } from "../utils/sender.ts"; -import { Context, NextFunction } from "../deps.ts"; -import topics from "../topics.json" assert { type: "json" }; - -export default async (ctx: Context, next: NextFunction) => { - if (!ctx.message?.is_topic_message) { - return await reply( - ctx, - `⚠️ Biz topicda emasmiz bu komandani ishlatish uchun!`, - ); - } - - if ( - !ctx.message?.reply_to_message || - Object.values(topics).includes(ctx.message!.reply_to_message!.message_id) - ) { - return await reply(ctx, `↪ Reply bilan ko'rsatingchi habarni!`); - } - await next(); -}; diff --git a/mod.ts b/mod.ts deleted file mode 100644 index 13873f9..0000000 --- a/mod.ts +++ /dev/null @@ -1 +0,0 @@ -import "./core.ts"; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..db2c043 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,5 @@ +# unstable_features = true +# format_strings = true +# imports_granularity = "Crate" +# merge_imports = true +max_width = 100 \ No newline at end of file diff --git a/source.json b/source.json index f084eeb..dcc3577 100644 --- a/source.json +++ b/source.json @@ -12,8 +12,8 @@ }, { "name": "Rust Cookbook", - "desc": "https://rust-lang-nursery.github.io/rust-cookbook/", - "link": "Learn Rust good practices with practical code samples" + "desc": "Learn Rust good practices with practical code samples", + "link": "https://rust-lang-nursery.github.io/rust-cookbook/" }, { "name": "CIS 198", diff --git a/src/functions/about.rs b/src/functions/about.rs new file mode 100644 index 0000000..29e464e --- /dev/null +++ b/src/functions/about.rs @@ -0,0 +1,33 @@ +use crate::{hooks, utils::keyboard::Keyboard}; +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +static TEXT: &str = r#" +Hurmatli foydalanuvchi! + +Bizning botimiz aktiv tarzda shakllantirib boriladi. Buning ustida esa bir necha avtor va dasturchilar turadi, ushbu havolalar orqali bizning sinovchilarimizdan biriga aylaning va biz bilan botimiz, hamda guruhimiz ishlatish qulayligini oshiring. +"#; + +pub async fn command(bot: &Bot, msg: &Message) -> ResponseResult<()> { + if !msg.chat.is_private() { + return { + hooks::is_private(bot, msg).await.unwrap(); + Ok(()) + }; + } + + bot.send_message(msg.chat.id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard()) + .await?; + + Ok(()) +} + +pub fn keyboard() -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + keyboard.url("Ochiq Havolalar", "https://github.com/rust-lang-uz/rustina") +} diff --git a/src/functions/groups.rs b/src/functions/groups.rs new file mode 100644 index 0000000..91637ba --- /dev/null +++ b/src/functions/groups.rs @@ -0,0 +1,118 @@ +use crate::utils::{ + groups::{Group, Groups}, + keyboard::Keyboard, +}; +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +static TEXT: &str = "Telegramdagi Rust Hamjamiyatlari yoki Guruhlari:\nAgar o'zingizni guruhingizni qo'shmoqchi bo'lsangiz, bizni community.json ni yangilang!"; + +pub async fn command(bot: &Bot, msg: &Message, groups: &Groups) -> ResponseResult<()> { + bot.send_message(msg.chat.id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_list(groups, 1)) + .await?; + + Ok(()) +} + +pub async fn callback_list( + bot: &Bot, + q: &CallbackQuery, + args: &Vec<&str>, + groups: &Groups, +) -> ResponseResult<()> { + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_list(groups, args[0].parse().unwrap_or(1))) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub async fn callback_detail(bot: &Bot, q: &CallbackQuery, args: &Vec<&str>) -> ResponseResult<()> { + let groups: Groups = Groups::new(); + let find = groups.find_group(args[1..].join("_").to_string()); + + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, view_detail(&find)) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_detail(args[0].parse().unwrap_or(1), &find)) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub fn view_detail(data: &Option) -> String { + match data { + Some(d) => { + format!( + "{}\n\n{}\n\nUse the following buttons to get to the links:", + d.name, d.about + ) + } + None => "Ushbu guruh mavjud emas!".to_string(), + } +} + +pub fn keyboard_list(groups: &Groups, page: i32) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + for group in groups.get_groups(page, 5) { + keyboard.text( + &group.name, + &format!( + "detail_{}_{}", + page, + group.telegram.clone().replace('@', "") + ), + ); + keyboard.row(); + } + + if !groups.get_groups(page + 1, 5).is_empty() { + keyboard.text("Keyingi ➡️", &format!("group_{}", page + 1)); + } + + if page > 1 { + keyboard.text("⬅️ Oldingi", &format!("group_{}", page - 1)); + } + + keyboard.get() +} + +pub fn keyboard_detail(page: i32, data: &Option) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + if let Some(group) = data { + keyboard.url("Telegram", &format!("https://t.me/{}", group.telegram)); + + if group.link.is_some() { + keyboard.url("Web", &group.link.clone().unwrap()); + } + + keyboard.row(); + + keyboard.text("🔙 Orqaga", &format!("group_{}", page)); + } else { + keyboard.text("🔙 Orqaga", &format!("group_{}", page)); + } + + keyboard.get() +} diff --git a/src/functions/help.rs b/src/functions/help.rs new file mode 100644 index 0000000..b438238 --- /dev/null +++ b/src/functions/help.rs @@ -0,0 +1,43 @@ +use super::start::keyboard; +use crate::Command; +use teloxide::{payloads::SendMessageSetters, prelude::*, types::ParseMode}; + +static TEXT: &[(&str, &str)] = &[ + ("docs", "reply qilingan odamga dok borligi haqida eslatish"), + ("useful", "rust haqida foydali yoki kerakli ma'lumotlar"), + ("latest", "eng oxirgi reliz haqida qisqacha ma'lumot"), + ("version", "biron anniq reliz haqida to'liq ma'lumot"), + ( + "off", + "reply qilingan odamga offtop borligi haqida eslatish", + ), + ("group", "rust ga oid guruh va hamjamiyatlar"), + ("help", "ushbu xabarni qayta ko'rsatish"), + ("about", "ushbu botimizning rivojlantirish qismi"), + ("rules", "qoidalarni aks ettirish"), + ( + "which", + "ushbu guruh va foydalanuvchi metrik ma'lumotlarini ko'rsatish", + ), +]; + +pub async fn command(bot: &Bot, msg: &Message, _cmd: &Command) -> ResponseResult<()> { + let mut text = String::new(); + + text.push_str("Mavjud komandalar ro'yxati:\n\n"); + + for cmd in TEXT { + text.push('/'); + text.push_str(cmd.0); + text.push_str(" - "); + text.push_str(format!("{text}", text = cmd.1).as_str()); + text.push('\n'); + } + + bot.send_message(msg.chat.id, text) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard()) + .await?; + + Ok(()) +} diff --git a/src/functions/inline.rs b/src/functions/inline.rs new file mode 100644 index 0000000..1359557 --- /dev/null +++ b/src/functions/inline.rs @@ -0,0 +1,87 @@ +use crates_io_api::{AsyncClient, Crate, CratesQuery}; +use std::error::Error; +use teloxide::{prelude::*, types::*}; + +use crate::utils::inlines::*; + +pub async fn inline( + bot: Bot, + crates_client: AsyncClient, + q: InlineQuery, +) -> Result<(), Box> { + if q.query.is_empty() { + return { + bot.answer_inline_query( + q.id, + vec![InlineQueryResultArticle::new( + "101", + "Qidirishni boshlang!", + InputMessageContent::Text( + InputMessageContentText::new(NO_INPUT) + .parse_mode(ParseMode::Html) + .disable_web_page_preview(true), + ), + ) + .reply_markup(err_keyboard()) + .into()], + ) + .await?; + Ok(()) + }; + } + + let request: CratesQuery = CratesQuery::builder() + .search(q.query.clone()) + .page(1) + .page_size(50) + .build(); + + let request: Vec = crates_client.crates(request).await.unwrap().crates; + + if request.is_empty() { + return { + bot.answer_inline_query( + q.id, + vec![InlineQueryResultArticle::new( + "404", + "Xatolik yuz berdi!", + InputMessageContent::Text( + InputMessageContentText::new( + format!("{} ga oid natija mavjud emas!\nIltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring!", + q.query.clone()) + ) + .parse_mode(ParseMode::Html) + .disable_web_page_preview(true), + ), + ) + .reply_markup(err_keyboard()) + .into()], + ) + .await?; + Ok(()) + }; + } + + let request: Vec = request + .iter() + .map(|c: &Crate| { + InlineQueryResult::Article( + InlineQueryResultArticle::new( + uuid::Uuid::new_v4(), + c.name.clone(), + InputMessageContent::Text( + InputMessageContentText::new(view_generate(c)) + .parse_mode(ParseMode::Html) + .disable_web_page_preview(true), + ), + ) + .description(c.description.clone().unwrap()) + .url(url::Url::parse(&format!("https://crates.io/crates/{}", c.id)).unwrap()) + .reply_markup(kb_generate(c)), + ) + }) + .collect(); + + bot.answer_inline_query(q.id, request).send().await?; + Ok(()) +} diff --git a/src/functions/latest.rs b/src/functions/latest.rs new file mode 100644 index 0000000..2b3fc82 --- /dev/null +++ b/src/functions/latest.rs @@ -0,0 +1,38 @@ +use crate::utils::{github::GitHub, keyboard::Keyboard}; +use octocrab::models::repos::Release; +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +pub async fn command(bot: &Bot, github: GitHub, msg: &Message) -> ResponseResult<()> { + let latest = github.get_latest().await.unwrap(); + + bot.send_message(msg.chat.id, view(&latest)) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard(&latest)) + .await?; + + Ok(()) +} + +pub fn view(release: &Release) -> String { + format!( + "Hozirgi eng oxirgi versiya bu \ + {} va ushbu reliz {} da e'lon qilingan \ + {} tomonidan.\ + \n\n\ + ", + release.tag_name, + release.tag_name, + release.published_at.unwrap().date_naive(), + release.author.html_url, + release.author.login, + ) +} + +pub fn keyboard(release: &Release) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + keyboard.url("Ko'proq ma'lumotlar", release.html_url.as_str()) +} diff --git a/src/functions/mod.rs b/src/functions/mod.rs new file mode 100644 index 0000000..5fbd3b9 --- /dev/null +++ b/src/functions/mod.rs @@ -0,0 +1,97 @@ +#![allow(clippy::single_match)] + +pub mod about; +pub mod groups; +pub mod help; +pub mod inline; +pub mod latest; +pub mod offtop; +pub mod rules; +pub mod start; +pub mod useful; +pub mod version; + +pub use inline::inline; + +use crate::utils::{github::GitHub, groups::Groups, resources::Resources}; +use crate::Command; +use std::error::Error; +use teloxide::{prelude::*, types::*}; + +pub async fn commands( + bot: Bot, + me: Me, + msg: Message, + cmd: Command, + github: GitHub, + groups: Groups, + resources: Resources, +) -> Result<(), Box> { + let _ = match cmd { + Command::Start => crate::functions::start::command(&bot, &msg).await, + Command::Help => crate::functions::help::command(&bot, &msg, &cmd).await, + Command::Rules => crate::functions::rules::command(&bot, &msg).await, + Command::About => crate::functions::about::command(&bot, &msg).await, + Command::Group => crate::functions::groups::command(&bot, &msg, &groups).await, + Command::Latest => crate::functions::latest::command(&bot, github, &msg).await, + Command::Version => crate::functions::version::command(&bot, github, &msg).await, + Command::Off => crate::functions::offtop::command(&bot, &msg, &me).await, + Command::Useful => crate::functions::useful::command(&bot, &msg, &resources).await, + }; + + Ok(()) +} + +pub async fn callback( + bot: Bot, + q: CallbackQuery, + github: GitHub, + groups: Groups, + resources: Resources, +) -> Result<(), Box> { + let mut args: Vec<&str> = Vec::new(); + + if let Some(data) = q.data.clone() { + if data.contains('_') { + args = data.split('_').collect(); + } else { + args.push(&data); + } + + let _ = match args.remove(0) { + "group" => crate::functions::groups::callback_list(&bot, &q, &args, &groups).await, + "detail" => crate::functions::groups::callback_detail(&bot, &q, &args).await, + "version" => crate::functions::version::callback_list(&bot, &q, &args, github).await, + "changelog" => { + crate::functions::version::callback_detail(&bot, &q, &args, github).await + } + "useful" => crate::functions::useful::callback_list(&bot, &q, &resources).await, + "category" => { + crate::functions::useful::callback_category_list(&bot, &q, &args, &resources).await + } + "material" => { + crate::functions::useful::callback_material_detail(&bot, &q, &args, &resources) + .await + } + _ => Ok(()), + }; + } + + Ok(()) +} + +pub async fn triggers(bot: Bot, msg: Message) -> Result<(), Box> { + if let Some(user) = msg.from() { + if let Some(username) = user.username.clone() { + if username == "Channel_Bot" { + // try to delete message and ignore error + match bot.delete_message(msg.chat.id, msg.id).await { + Ok(_) => {} + Err(_) => {} + } + } + } + } + + Ok(()) +} diff --git a/src/functions/offtop.rs b/src/functions/offtop.rs new file mode 100644 index 0000000..014d496 --- /dev/null +++ b/src/functions/offtop.rs @@ -0,0 +1,47 @@ +use teloxide::{prelude::*, types::*}; + +static TEXT_FAIL: &str = "Ha-ha... yaxshi urinish!"; +static TEXT_NON_REPLY: &str = "↪ Reply bilan ko'rsatingchi habarni!"; + +pub async fn command(bot: &Bot, msg: &Message, me: &Me) -> ResponseResult<()> { + if msg.reply_to_message().is_none() { + return { + bot.send_message(msg.chat.id, TEXT_NON_REPLY).await?; + Ok(()) + }; + } + + // if replied person is bot itself, send fail message + if let Some(user) = msg.reply_to_message().as_ref().unwrap().from() { + if user.username.clone().unwrap() == me.username() { + return { + bot.send_message(msg.chat.id, TEXT_FAIL).await?; + Ok(()) + }; + } + } + + bot.delete_message(msg.chat.id, msg.id).await?; + bot.delete_message(msg.chat.id, msg.reply_to_message().unwrap().id) + .await?; + + bot.send_message(msg.chat.id, view(msg.reply_to_message().unwrap())) + .parse_mode(ParseMode::Html) + .await?; + + Ok(()) +} + +pub fn view(msg: &Message) -> String { + format!( + "Hurmatli {},\ + \n\n\ + Tushunishim bo'yicha siz mavzudan chetlayashayabsiz. Iltimos, \ + quyidagi tugmachani bosish orqali bizning offtop guruhga o'tib oling! \ + Offtopic guruhimizda istalgan mavzuda suhbatlashish ruxsat etiladi. Boshqalarga halaqit qilmayliga 😉\ + \n\n\ + Hurmat ila, Rustina (Rastina)", + msg.from().unwrap().id, + msg.from().unwrap().first_name + ) +} diff --git a/src/functions/rules.rs b/src/functions/rules.rs new file mode 100644 index 0000000..c5da183 --- /dev/null +++ b/src/functions/rules.rs @@ -0,0 +1,41 @@ +use crate::{hooks, utils::keyboard::Keyboard}; +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +static TEXT: &str = r#" +Hurmatli guruh a'zosi... + +Iltimos qoidalarga oz bo'lsada vaqt ajratishni unutmang, bu muhim! Ushbu guruhda quyidagi harakatlar taqiqlanadi: + +* Besabab bir-birini kamsitish yoki so'kinish +* Sababsiz guruhga spam yozaverish yoki tashash +* So'ralgan narsani yana qayta ezmalash +* Administratorlarga nisbatan juddayam qattiq kritika +* Faoliyat ustidan shikoyat qilaverish yoki nolish + +Ushbu qoidalarni doimiy tarzda buzish, butunlay ban yoki bir necha ogohlantirishlirga olib keladi! +"#; + +pub async fn command(bot: &Bot, msg: &Message) -> ResponseResult<()> { + if !msg.chat.is_private() { + return { + hooks::is_private(bot, msg).await.unwrap(); + Ok(()) + }; + } + + bot.send_message(msg.chat.id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard()) + .await?; + + Ok(()) +} + +pub fn keyboard() -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + keyboard.url("Guruhga qaytish", "https://t.me/rustlanguz") +} diff --git a/src/functions/start.rs b/src/functions/start.rs new file mode 100644 index 0000000..832d5b7 --- /dev/null +++ b/src/functions/start.rs @@ -0,0 +1,27 @@ +use crate::utils::keyboard::Keyboard; +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +static TEXT: &str = r#" +Assalomu alaykum, hurmatli Rustacean! + +Sizni ko'rib turganimdan bag'oyatda xursandman. Men O'zbek Rust jamiyati tomonidan yaratilgan bot hisoblanib, O'zbek Rust jamiyati foydalanuvchilari uchun foydali resurslarni yetkazish, saqlash va ularni saralash uchun xizmat qilaman. +"#; + +pub async fn command(bot: &Bot, msg: &Message) -> ResponseResult<()> { + bot.send_message(msg.chat.id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard()) + .await?; + + Ok(()) +} + +pub fn keyboard() -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + keyboard.url("Jamiyat", "https://t.me/rustlanguz"); + keyboard.url("Web Sahifa", "https://rust-lang.uz") +} diff --git a/src/functions/useful.rs b/src/functions/useful.rs new file mode 100644 index 0000000..04ce2d1 --- /dev/null +++ b/src/functions/useful.rs @@ -0,0 +1,155 @@ +use crate::utils::{ + keyboard::Keyboard, + resources::{Resource, Resources}, +}; +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +static TEXT: &str = "Rustga oid foydali materiallar:\n\ +Agar o'zingizdan material qo'shmoqchi bo'lsangiz, bizni \ +\ +source.json ni yangilang!"; + +pub async fn command(bot: &Bot, msg: &Message, resources: &Resources) -> ResponseResult<()> { + let categories = resources.get_keys(); + + bot.send_message(msg.chat.id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_list(categories)) + .disable_web_page_preview(true) + .await?; + + Ok(()) +} + +pub async fn callback_list( + bot: &Bot, + q: &CallbackQuery, + resources: &Resources, +) -> ResponseResult<()> { + let categories = resources.get_keys(); + + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_list(categories)) + .disable_web_page_preview(true) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + + Ok(()) +} + +pub async fn callback_category_list( + bot: &Bot, + q: &CallbackQuery, + args: &Vec<&str>, + resources: &Resources, +) -> ResponseResult<()> { + let find = resources.get_materials(args.join("_").as_str()).unwrap(); + + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, view_category_list(&args.join(" "))) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_category_list(find, args.join("_"))) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub async fn callback_material_detail( + bot: &Bot, + q: &CallbackQuery, + args: &Vec<&str>, + resources: &Resources, +) -> ResponseResult<()> { + let find = resources + .get_material(args[1..].join("_").as_str(), args[0].parse().unwrap()) + .unwrap(); + + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, view_material_detail(find)) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_material_detail(find, args[1..].join("_"))) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub fn view_category_list(category: &str) -> String { + format!("Siz hozirda {}{} kategoriyasi ichida turibsiz.\nIltimos, keltirilgan materiallardan birini tanlang...", + &category[0..1].to_uppercase(), &category[1..].replace('_', " ")) +} + +pub fn view_material_detail(material: &Resource) -> String { + format!( + "{}\n\n{}\n\nUshbu pastdagi tugmacha orqali lavha ga o'tib oling:", + material.name, material.desc + ) +} + +pub fn keyboard_list(categories: Vec) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + for category in categories { + keyboard.text( + &format!( + "{}{}", + &category[0..1].to_uppercase(), + &category[1..].replace('_', " ") + ), + &format!("category_{}", category), + ); + keyboard.row(); + } + + keyboard.get() +} + +pub fn keyboard_category_list(material: &[Resource], category: String) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + for (index, value) in material.iter().enumerate() { + keyboard.text( + &format!( + "{}{}", + &value.name[0..1].to_uppercase(), + &value.name[1..].replace('_', " ") + ), + &format!("material_{}_{}", index, category), + ); + keyboard.row(); + } + + keyboard.text("🔙 Orqaga", "useful"); + + keyboard.get() +} + +pub fn keyboard_material_detail(resource: &Resource, category: String) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + keyboard.url("Web Sahifasi", &resource.link); + keyboard.row(); + keyboard.text("🔙 Orqaga", &format!("category_{}", category)); + + keyboard.get() +} diff --git a/src/functions/version.rs b/src/functions/version.rs new file mode 100644 index 0000000..b1d4559 --- /dev/null +++ b/src/functions/version.rs @@ -0,0 +1,121 @@ +use crate::utils::{github::GitHub, keyboard::Keyboard}; +use octocrab::models::repos::Release; +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +static TEXT: &str = "Rust Dasturlash tili versiyalari:"; + +pub async fn command(bot: &Bot, github: GitHub, msg: &Message) -> ResponseResult<()> { + let versions = github.get_list(1).await.unwrap(); + let next_page = github.get_list(2).await.unwrap(); + + bot.send_message(msg.chat.id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_list(1, versions, Some(next_page))) + .await?; + + Ok(()) +} + +pub async fn callback_list( + bot: &Bot, + q: &CallbackQuery, + args: &Vec<&str>, + github: GitHub, +) -> ResponseResult<()> { + let page = args[0].parse::().unwrap(); + let versions: Vec = github.get_list(page).await.unwrap(); + let next_page = github.get_list(page + 1).await.unwrap(); + + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_list(page, versions, Some(next_page))) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub async fn callback_detail( + bot: &Bot, + q: &CallbackQuery, + args: &Vec<&str>, + github: GitHub, +) -> ResponseResult<()> { + let page = args[0].parse::().unwrap(); + let version: Release = github.get_detail(args[1]).await.unwrap(); + + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, view_detail(&version)) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_detail(page, version)) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub fn view_detail(release: &Release) -> String { + format!( + "{}\n\n\ + Yaratildi: {}\n\ + E'lon qilindi: {}\n\ + O'rnatish: rustup install {}\n\n\ + \"Instant view\" yoki quyidagi tugma orqali ko'proq ma'lumot oling:", + release.html_url, + release.name.clone().unwrap(), + release.created_at.unwrap().format("%d.%m.%Y"), + release.published_at.unwrap().format("%d.%m.%Y"), + release.tag_name + ) +} + +pub fn keyboard_list( + page: u32, + releases: Vec, + next_page: Option>, +) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + for release in releases { + keyboard.text( + &release.tag_name, + &format!("changelog_{}_{}", page, release.tag_name), + ); + keyboard.row(); + } + + if page > 1 { + keyboard.text("⬅️ Oldingi", &format!("version_{}", page - 1)); + } + + if next_page.is_some() && !next_page.unwrap().is_empty() { + keyboard.text("Keyingi ➡️", &format!("version_{}", page + 1)); + } + + keyboard.get() +} + +pub fn keyboard_detail(page: u32, release: Release) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + keyboard.url("📝 GitHub da o'qish", release.html_url.as_str()); + keyboard.row(); + keyboard.text("🔙 Orqaga", &format!("version_{}", page)); + + keyboard.get() +} diff --git a/src/hooks/is_private.rs b/src/hooks/is_private.rs new file mode 100644 index 0000000..16783cc --- /dev/null +++ b/src/hooks/is_private.rs @@ -0,0 +1,23 @@ +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::{InlineKeyboardMarkup, ParseMode}, +}; + +use crate::utils::keyboard::Keyboard; + +static TEXT: &str = "⚠️ Bu komanda faqat shaxsiy chat uchun!"; + +pub fn keyboard() -> InlineKeyboardMarkup { + let mut keyboard: Keyboard = Keyboard::new(); + keyboard.url("Shaxsiy Chat", "https://t.me/rusttest_stage_bot") +} + +pub async fn is_private(bot: &Bot, msg: &Message) -> ResponseResult<()> { + bot.send_message(msg.chat.id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard()) + .await?; + + Ok(()) +} diff --git a/src/hooks/mod.rs b/src/hooks/mod.rs new file mode 100644 index 0000000..887384c --- /dev/null +++ b/src/hooks/mod.rs @@ -0,0 +1,3 @@ +pub mod is_private; + +pub use is_private::is_private; diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..fbc9464 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,56 @@ +pub mod functions; +pub mod hooks; +pub mod utils; + +use teloxide::{ + dispatching::{UpdateFilterExt, UpdateHandler}, + prelude::*, + utils::command::BotCommands, +}; + +#[derive(BotCommands, Clone, Debug)] +#[command(rename_rule = "lowercase", parse_with = "split")] +#[command(description = "These are the commands that I can understand:")] +pub enum Command { + /// List existing commands + Help, + + /// Starting point of the bot + Start, + + /// Rules of our chat + Rules, + + /// About the bot + About, + + /// Available groups + Group, + + /// Latest version + Latest, + + /// Specific version + Version, + + /// Report offtopic + Off, + + /// Useful resources + Useful, +} + +pub fn handler() -> UpdateHandler> { + dptree::entry() + // Inline Queries + .branch(Update::filter_inline_query().endpoint(functions::inline)) + // Callbacks + .branch(Update::filter_callback_query().endpoint(functions::callback)) + // Commands + .branch( + Update::filter_message() + .filter_command::() + .endpoint(functions::commands), + ) + .branch(Update::filter_message().endpoint(functions::triggers)) +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..22c9b38 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,41 @@ +use crates_io_api::AsyncClient; +use rustina::{ + handler, + utils::{github::GitHub, groups::Groups, resources::Resources}, +}; +use std::error::Error; +use teloxide::prelude::*; + +#[tokio::main] +async fn main() -> Result<(), Box> { + pretty_env_logger::init(); + log::info!("Starting Rustina Assistant..."); + + let bot = Bot::from_env(); + + let groups = Groups::new(); + let github = GitHub::new(); + let crates_client = AsyncClient::new( + "Rustina Assistant (rust@maid.uz)", + std::time::Duration::from_millis(100), + ) + .unwrap(); + let resources = Resources::new(); + + Dispatcher::builder(bot, handler()) + .dependencies(dptree::deps![crates_client, github, groups, resources]) + // If no handler succeeded to handle an update, this closure will be called + .default_handler(|upd| async move { + log::warn!("Unhandled update: {:?}", upd); + }) + // If the dispatcher fails for some reason, execute this handler + .error_handler(LoggingErrorHandler::with_custom_text( + "An error has occurred in the dispatcher", + )) + .enable_ctrlc_handler() + .build() + .dispatch() + .await; + + Ok(()) +} diff --git a/src/utils/github.rs b/src/utils/github.rs new file mode 100644 index 0000000..53dbd9a --- /dev/null +++ b/src/utils/github.rs @@ -0,0 +1,71 @@ +use octocrab::{models::repos::Release, Octocrab}; +use std::error::Error; + +#[derive(Clone, Debug)] +pub struct GitHub { + client: Octocrab, +} + +impl Default for GitHub { + fn default() -> Self { + Self::new() + } +} + +impl GitHub { + pub fn new() -> Self { + Self { + client: Octocrab::builder() + .add_header( + "User-Agent".parse().unwrap(), + "Rustina Assistant (rust@maid.uz)".to_string(), + ) + .add_header( + "Authorization".parse().unwrap(), + std::env::var("GITHUB_TOKEN").unwrap(), + ) + .build() + .unwrap(), + } + } + + pub async fn get_latest(&self) -> Result> { + let latest = self + .client + .repos("rust-lang", "rust") + .releases() + .get_latest() + .await?; + + Ok(latest) + } + + pub async fn get_list(&self, page: u32) -> Result, Box> { + let versions = self + .client + .repos("rust-lang", "rust") + .releases() + .list() + .per_page(5) + .page(page) + .send() + .await? + .take_items(); + + Ok(versions) + } + + pub async fn get_detail( + &self, + tag_name: &str, + ) -> Result> { + let detail = self + .client + .repos("rust-lang", "rust") + .releases() + .get_by_tag(tag_name) + .await?; + + Ok(detail) + } +} diff --git a/src/utils/groups.rs b/src/utils/groups.rs new file mode 100644 index 0000000..7f71628 --- /dev/null +++ b/src/utils/groups.rs @@ -0,0 +1,63 @@ +use serde::{Deserialize, Serialize}; + +static GROUPS: &str = include_str!("../../communities.json"); + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Group { + pub name: String, + pub about: String, + pub telegram: String, + pub link: Option, +} + +#[derive(Debug, Clone)] +pub struct Groups { + groups: Vec, +} + +impl Default for Groups { + fn default() -> Self { + Self::new() + } +} + +impl Groups { + pub fn new() -> Self { + let json: Vec = serde_json::from_str(GROUPS).unwrap(); + + Self { groups: json } + } + + pub fn get_groups(&self, page_number: i32, page_size: i32) -> Vec { + let start = (page_number - 1) * page_size; + let end = page_number * page_size; + + if start < 0 || end < 0 { + return Vec::new(); + } + + if start as usize > self.groups.len() { + return Vec::new(); + } + + if end as usize > self.groups.len() { + return self.groups[start as usize..].to_vec(); + } + + self.groups[start as usize..end as usize].to_vec() + } + + pub fn find_group(&self, query: String) -> Option { + let search: Vec<&Group> = self + .groups + .iter() + .filter(|group| group.telegram[1..] == query) + .collect(); + + if search.is_empty() { + return None; + } + + Some(search[0].clone()) + } +} diff --git a/src/utils/inlines.rs b/src/utils/inlines.rs new file mode 100644 index 0000000..62d0167 --- /dev/null +++ b/src/utils/inlines.rs @@ -0,0 +1,91 @@ +use super::keyboard::Keyboard; +use crates_io_api::Crate; +use teloxide::types::*; + +pub static NO_INPUT: &str = r#" +Salom foydalanuvchi! + +Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz crates.io Rust dasturlash tili paketlar registridan web sahifani ishlatmasdan turib telegram o'zida kerakli paketlarni qidirishingiz mumkin! Ushbu qulaylik yozish uchun o'zimizning API SDK ishlatildi. + +Qidirishni boshlash uchun: +@rustaceanbot <nomi> +"#; + +pub fn view_generate(c: &Crate) -> String { + let mut result = String::from("🦀 Rust Telegram Cratelari 🦀\n\n"); + + result.push_str(&format!("📦 Nomi: {}\n", c.name)); + result.push_str(&format!( + "🚨 Oxirgi versiya: {}\n", + c.max_version + )); + result.push_str(&format!( + "🎚 Yuklab olingan: yaqin orada: {} | hammasi: {}\n", + c.recent_downloads.unwrap(), + c.downloads + )); + result.push_str(&format!( + "⌚️ Yaratilgan: {}\n", + c.created_at.date_naive() + )); + result.push_str(&format!( + "📡 Yangilangan: {}\n", + c.updated_at.date_naive() + )); + result.push_str(&format!( + "📰 Ma'lumot: {}{}\n\n", + if c.description.clone().unwrap().len() > 100 { + c.description + .clone() + .unwrap() + .chars() + .take(100) + .collect::() + } else { + c.description.clone().unwrap() + }, + if c.description.clone().unwrap().len() > 100 { + "..." + } else { + "" + } + )); + result.push_str("🔌 Cargo.toml fayliga qo'shib qo'ying: \n"); + result.push_str(&format!( + "[dependencies]\n{} = \"{}\"", + c.name, c.max_version + )); + + result +} + +pub fn kb_generate(c: &Crate) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + keyboard.url( + "Crate", + format!("https://crates.io/crates/{}", c.name).as_str(), + ); + + if c.homepage.is_some() { + keyboard.url("Asosiy", &c.homepage.clone().unwrap()); + keyboard.row(); + } + + if c.documentation.is_some() { + keyboard.url("Dokumentatsiya", &c.documentation.clone().unwrap()); + keyboard.row(); + } + + if c.repository.is_some() { + keyboard.url("Repozitoriya", &c.repository.clone().unwrap()); + keyboard.row(); + } + + keyboard.get() +} + +pub fn err_keyboard() -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + keyboard.switch_inline_current("Qayta urinib ko'ramizmi?", "rand") +} diff --git a/src/utils/keyboard.rs b/src/utils/keyboard.rs new file mode 100644 index 0000000..e1ebf4d --- /dev/null +++ b/src/utils/keyboard.rs @@ -0,0 +1,62 @@ +use teloxide::types::{InlineKeyboardButton, InlineKeyboardMarkup}; +use url::Url; + +#[derive(Clone)] +pub struct Keyboard { + keyboard: Vec>, +} + +impl Default for Keyboard { + fn default() -> Self { + Keyboard::new() + } +} + +impl Keyboard { + pub fn new() -> Self { + Self { + keyboard: vec![vec![]], + } + } + + /// Add a text callback to keyboard + pub fn text(&mut self, text: &str, callback: &str) -> InlineKeyboardMarkup { + self.keyboard + .last_mut() + .unwrap() + .push(InlineKeyboardButton::callback(text, callback)); + + self.get() + } + + /// Add an url button to keyboard + pub fn url(&mut self, text: &str, url: &str) -> InlineKeyboardMarkup { + let parsed_url = Url::parse(url).unwrap(); + + self.keyboard + .last_mut() + .unwrap() + .push(InlineKeyboardButton::url(text, parsed_url)); + + self.get() + } + + pub fn switch_inline_current(&mut self, text: &str, query: &str) -> InlineKeyboardMarkup { + self.keyboard.last_mut().unwrap().push( + InlineKeyboardButton::switch_inline_query_current_chat(text, query), + ); + + self.get() + } + + /// Add next buttons from new line + pub fn row(&mut self) -> InlineKeyboardMarkup { + self.keyboard.push(vec![]); + self.get() + } + + /// Return the final result + pub fn get(&self) -> InlineKeyboardMarkup { + InlineKeyboardMarkup::new(self.keyboard.clone()) + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..81184b8 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,5 @@ +pub mod github; +pub mod groups; +pub mod inlines; +pub mod keyboard; +pub mod resources; diff --git a/src/utils/resources.rs b/src/utils/resources.rs new file mode 100644 index 0000000..b240c6a --- /dev/null +++ b/src/utils/resources.rs @@ -0,0 +1,42 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +static RESOURCE: &str = include_str!("../../source.json"); + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Resource { + pub name: String, + pub desc: String, + pub link: String, +} + +#[derive(Clone, Debug)] +pub struct Resources { + materials: HashMap>, +} + +impl Default for Resources { + fn default() -> Self { + Self::new() + } +} + +impl Resources { + pub fn new() -> Self { + Resources { + materials: serde_json::from_str(RESOURCE).unwrap(), + } + } + + pub fn get_keys(&self) -> Vec { + self.materials.keys().map(|k| k.to_string()).collect() + } + + pub fn get_materials(&self, key: &str) -> Option<&Vec> { + self.materials.get(key) + } + + pub fn get_material(&self, key: &str, index: usize) -> Option<&Resource> { + self.materials.get(key).and_then(|v| v.get(index)) + } +} diff --git a/types/Github.d.ts b/types/Github.d.ts deleted file mode 100644 index b4f5f38..0000000 --- a/types/Github.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -export interface Reactions { - url: string; - total_count: number; - "+1": number; - "-1": number; - laugh: number; - hooray: number; - confused: number; - heart: number; - rocket: number; - eyes: number; -} - -export interface ReleaseAuthor { - "login": string; - "id": number; - "node_id": string; - "avatar_url": string; - "gravatar_id": string; - "url": string; - "html_url": string; - "followers_url": string; - "following_url": string; - "gists_url": string; - "starred_url": string; - "subscriptions_url": string; - "organizations_url": string; - "repos_url": string; - "events_url": string; - "received_events_url": string; - "type": string; - "site_admin": boolean; -} - -export interface Release { - "url": string; - "assets_url": string; - "upload_url": string; - "html_url": string; - "id": number; - "author": ReleaseAuthor; - "node_id": string; - "tag_name": string; - "target_commitish": string; - "name": string; - "draft": boolean; - "prerelease": boolean; - "created_at": string | Date; - "published_at": string | Date; - "assets": []; - "tarball_url": string; - "zipball_url": string; - "body": string; - "reactions": Reactions; -} diff --git a/utils/checker.ts b/utils/checker.ts deleted file mode 100644 index 3ffaedc..0000000 --- a/utils/checker.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { editor } from "../core.ts"; -import type { Page } from "../deps.ts"; -import { parseMarkdown } from "../deps.ts"; - -export const hecker = async ( - version: string, - content: string, -): Promise => { - const existing = await editor.getPages(); - - for (const some of existing.pages) { - if (some.title === `Rust ${version}`) { - return some; - } - } - - return await editor.create({ - title: `Rust ${version}`, - content: parseMarkdown(content) || - "Oops, something happened while fetching data", - }); -}; - -export default hecker; diff --git a/utils/config.ts b/utils/config.ts deleted file mode 100644 index 0116f32..0000000 --- a/utils/config.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { config } from "../deps.ts"; - -const inits = () => { - if (Deno.env.get("MODE") === "NOFS") { - return Deno.env.toObject(); - } else { - return config(); - } -}; - -const dots = inits(); - -export default dots; diff --git a/utils/encoder.ts b/utils/encoder.ts deleted file mode 100644 index b945090..0000000 --- a/utils/encoder.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default (input: string) => - input.replaceAll(/[\u00A0-\u9999<>\&]/g, (i) => { - return "&#" + i.charCodeAt(0) + ";"; - }); diff --git a/utils/generator.ts b/utils/generator.ts deleted file mode 100644 index e151ef6..0000000 --- a/utils/generator.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { Release } from "../types/Github.d.ts"; - -export const finder = async (id: number) => { - const request = await fetch( - `https://api.github.com/repos/rust-lang/rust/releases/${id}`, - ); - - return await request.json() as Release; -}; - -export const pager = async (page: number, size = 5) => { - const request = await fetch( - `https://api.github.com/repos/rust-lang/rust/releases?per_page=${size}&page=${page}`, - ); - - return await request.json() as Release[]; -}; - -export const last = async () => { - const request = await fetch( - `https://api.github.com/repos/rust-lang/rust/releases/latest`, - ); - - return await request.json() as Release; -}; diff --git a/utils/pager.ts b/utils/pager.ts deleted file mode 100644 index 11b8e0f..0000000 --- a/utils/pager.ts +++ /dev/null @@ -1,8 +0,0 @@ -import communities from "../communities.json" assert { type: "json" }; - -export default (page_number: number, page_size = 5) => { - return communities.slice( - (page_number - 1) * page_size, - page_number * page_size, - ); -}; diff --git a/utils/picker.ts b/utils/picker.ts deleted file mode 100644 index bc551d0..0000000 --- a/utils/picker.ts +++ /dev/null @@ -1,38 +0,0 @@ -import source from "../source.json" assert { type: "json" }; - -export type Category = - | "tutorial" - | "podcasts" - | "books" - | "videos" - | "more" - | "even_more"; - -export interface Material { - name: string; - desc: string; - link: string; -} - -export const categories = (): string[] => { - return Object.keys(source); -}; - -export const indexer = (category: Category, element: Material) => { - return source[category].indexOf(element); -}; - -export const material = (category: Category, index: number): Material => { - return source[category][index]; -}; - -export const pager = ( - category: Category, - page_number: number, - page_size = 5, -): Material[] => { - return source[category].slice( - (page_number - 1) * page_size, - page_number * page_size, - ); -}; diff --git a/utils/sender.ts b/utils/sender.ts deleted file mode 100644 index 15c59c3..0000000 --- a/utils/sender.ts +++ /dev/null @@ -1,31 +0,0 @@ -// deno-lint-ignore-file no-explicit-any -import { Context, InlineKeyboard } from "../deps.ts"; - -/** - * Reply to message api but with topics support - * @param ctx Context from Grammy.js middleware - * @param message The message you want to send - * @param buttons InlineKeyboard button to attach to the message - * @param configs Other configs to pass to the api - */ -export const reply = async ( - ctx: Context, - message: string, - buttons?: InlineKeyboard, - configs?: { [key: string]: any }, -): Promise => { - const config: { [key: string]: any } = { - parse_mode: "HTML", - ...configs, - }; - - if (ctx.message!.is_topic_message) { - config["message_thread_id"] = ctx.message!.message_thread_id; - } - - if (buttons) { - config["reply_markup"] = buttons; - } - - return await ctx.reply(message, config); -};