mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI-examples.git
synced 2026-08-29 12:26:25 +00:00
update readmes
This commit is contained in:
@@ -1,9 +1,76 @@
|
||||
# RandomFileSenderBot
|
||||
|
||||
This bot will send random file from input folder OR from bot working folder
|
||||
This Kotlin Multiplatform example sends randomly selected local files in response to a Telegram command. It uses long
|
||||
polling and can run on the JVM or as a Kotlin/Native executable.
|
||||
|
||||
## Launch
|
||||
## Behavior
|
||||
|
||||
The bot registers one command:
|
||||
|
||||
- `/send_file` requests one file;
|
||||
- `/send_file N` requests `N` files when `N` is a positive integer; and
|
||||
- a missing or non-numeric count defaults to one. Zero and negative counts select nothing and receive
|
||||
`Nothing selected :(`.
|
||||
|
||||
For each requested file, the picker starts at the configured root. A file root is selected directly; a directory root
|
||||
is searched by choosing one random child at each level until a file is reached. This is not a uniform choice among all
|
||||
files in an uneven directory tree, and the same file may be selected more than once. Zero-byte files and unsuccessful
|
||||
selections are retried. Consequently, a positive request can keep retrying indefinitely when no non-empty file is
|
||||
reachable.
|
||||
|
||||
One file is sent as a document. Multiple files are sent as document media groups, split at Telegram's maximum media
|
||||
group size. All sends enable Telegram's protected-content flag. The bot also prints its own account information at
|
||||
startup and prints polling exceptions.
|
||||
|
||||
## Setup and security
|
||||
|
||||
Create a bot with BotFather and obtain its token. Give the process read access to a dedicated directory containing only
|
||||
files that every bot user may receive, and pass that directory explicitly. The bot has no user or chat allowlist and no
|
||||
file-name or file-type filter; anyone able to send it the command can request files reachable through the configured
|
||||
tree. Protected content is not an access-control mechanism.
|
||||
|
||||
Keep the token private. These launchers accept it on the command line, where it may be retained in shell history or be
|
||||
visible to other local processes. Also avoid roots containing secrets or links to locations outside the intended tree.
|
||||
|
||||
## Arguments
|
||||
|
||||
Both launchers interpret arguments in the same order:
|
||||
|
||||
1. `BOT_TOKEN` (required). Omitting it fails immediately.
|
||||
2. `ROOT_PATH` (optional in code), either a file or directory. Relative paths are resolved from the process working
|
||||
directory; use an explicit absolute path for predictable behavior. The launchers pass an empty path when this
|
||||
argument is omitted, whose filesystem behavior differs by platform and is not a reliable working-directory default.
|
||||
|
||||
Additional arguments are ignored.
|
||||
|
||||
## Launch from the repository root
|
||||
|
||||
### JVM
|
||||
|
||||
```bash
|
||||
../gradlew run --args="BOT_TOKEN[ optional/folder/path]"
|
||||
./gradlew :RandomFileSenderBot:runJvm --args="<BOT_TOKEN> /absolute/path/to/files"
|
||||
```
|
||||
|
||||
The JVM picker uses `java.io.File`. A missing, empty, or unreadable directory produces no selection and therefore causes
|
||||
a positive request to keep retrying.
|
||||
|
||||
### Kotlin/Native
|
||||
|
||||
The shared native configuration selects Linux x64, Linux Arm64, or Windows x64 for the current host. macOS is not
|
||||
configured. Link the debug executable with Gradle, then pass the arguments directly to the generated program:
|
||||
|
||||
```bash
|
||||
./gradlew :RandomFileSenderBot:linkDebugExecutableNative
|
||||
./RandomFileSenderBot/build/bin/native/debugExecutable/RandomFileSenderBot.kexe "<BOT_TOKEN>" "/absolute/path/to/files"
|
||||
```
|
||||
|
||||
On Windows, run
|
||||
`RandomFileSenderBot\build\bin\native\debugExecutable\RandomFileSenderBot.exe "<BOT_TOKEN>" "C:\path\to\files"`
|
||||
after the same Gradle link task. The native picker uses Okio; unlike the JVM picker, inaccessible or invalid paths may
|
||||
raise a filesystem exception that is printed by the polling exception handler.
|
||||
|
||||
## Source sets
|
||||
|
||||
- `commonMain` contains the picker contract and the long-polling bot behavior.
|
||||
- `jvmMain` implements recursive selection with `java.io.File` and provides the suspending JVM entry point.
|
||||
- `nativeMain` implements recursive selection with Okio and provides a `runBlocking` native entry point.
|
||||
|
||||
@@ -18,14 +18,18 @@ import dev.inmo.tgbotapi.types.mediaCountInMediaGroup
|
||||
|
||||
private const val command = "send_file"
|
||||
|
||||
/**
|
||||
* Selects a file by recursively choosing random children below [currentRoot].
|
||||
*
|
||||
* @return the selected file, or `null` when the picker cannot continue from the current root
|
||||
*/
|
||||
expect fun pickFile(currentRoot: MPPFile): MPPFile?
|
||||
|
||||
/**
|
||||
* This bot will send files inside of working directory OR from directory in the second argument.
|
||||
* You may send /send_file command to this bot to get random file from the directory OR
|
||||
* `/send_file $number` when you want to receive required number of files. For example,
|
||||
* /send_file and `/send_file 1` will have the same effect - bot will send one random file.
|
||||
* But if you will send `/send_file 5` it will choose 5 random files and send them as group
|
||||
* Runs the long-polling random-file bot using [token] and serving selections rooted at [folder].
|
||||
*
|
||||
* `/send_file` selects one non-empty file, while `/send_file N` selects `N` files and splits them into valid Telegram
|
||||
* media-group sizes.
|
||||
*/
|
||||
suspend fun doRandomFileSenderBot(token: String, folder: MPPFile) {
|
||||
val bot = telegramBot(token)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import dev.inmo.micro_utils.common.MPPFile
|
||||
import java.io.File
|
||||
|
||||
/** JVM picker backed by [File], returning a file root directly or descending through random directory children. */
|
||||
actual fun pickFile(currentRoot: MPPFile): File? {
|
||||
if (currentRoot.isFile) {
|
||||
return currentRoot
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import dev.inmo.micro_utils.common.MPPFile
|
||||
|
||||
/** JVM entry point; [args] contains the bot token followed by an optional picker root. */
|
||||
suspend fun main(args: Array<String>) {
|
||||
doRandomFileSenderBot(args.first(), MPPFile(args.getOrNull(1) ?: ""))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import dev.inmo.micro_utils.common.MPPFile
|
||||
import okio.FileSystem
|
||||
|
||||
/** Native picker backed by Okio, returning a file root directly or descending through random directory children. */
|
||||
actual fun pickFile(currentRoot: MPPFile): MPPFile? {
|
||||
if (FileSystem.SYSTEM.exists(currentRoot) && FileSystem.SYSTEM.listOrNull(currentRoot) == null) {
|
||||
return currentRoot
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okio.Path.Companion.toPath
|
||||
|
||||
/** Kotlin/Native entry point; [args] contains the bot token followed by an optional picker root. */
|
||||
fun main(args: Array<String>) {
|
||||
runBlocking {
|
||||
doRandomFileSenderBot(args.first(), args.getOrNull(1) ?.toPath() ?: "".toPath())
|
||||
|
||||
Reference in New Issue
Block a user