Files
2026-10-18 23:48:22 +05:30

190 lines
7.1 KiB
JSON

{
"name": "Telegram Drive Organizer",
"description": "Telegram bot that downloads channel videos (whole channel or an /upload message range) into Google Drive topic folders.",
"keywords": [
"telegram",
"google-drive",
"telethon",
"video",
"worker"
],
"stack": "heroku-24",
"buildpacks": [
{
"url": "heroku/python"
}
],
"formation": {
"worker": {
"quantity": 1,
"size": "basic"
}
},
"addons": [
{
"plan": "heroku-postgresql:essential-0",
"as": "DATABASE"
}
],
"env": {
"TELEGRAM_MODE": {
"description": "How the bot reads the channel: 'user' (your Telegram account; full history; needs TELEGRAM_SESSION_STRING) or 'bot' (bot admin of the channel; new posts, best-effort history).",
"value": "user",
"required": true
},
"TELEGRAM_API_ID": {
"description": "Numeric API ID from https://my.telegram.org > API development tools. Needed in both modes.",
"required": true
},
"TELEGRAM_API_HASH": {
"description": "API hash from https://my.telegram.org > API development tools. Keep secret.",
"required": true
},
"TELEGRAM_BOT_TOKEN": {
"description": "Bot token from @BotFather. Provides the admin command interface (/run, /status, ...); in bot mode it also reads the channel.",
"required": true
},
"TELEGRAM_SESSION_STRING": {
"description": "Only for TELEGRAM_MODE=user: string session created locally with `python main.py login --session-string`. Grants access to your account - keep secret.",
"required": false
},
"ADMIN_USER_IDS": {
"description": "Comma-separated numeric Telegram user IDs allowed to run commands (get yours from @userinfobot).",
"required": true
},
"SOURCE_CHANNEL_ID": {
"description": "Source channel: @username, https://t.me/... link, or numeric -100... ID.",
"required": true
},
"GOOGLE_AUTH_MODE": {
"description": "'oauth' for a personal Google Drive (uses GOOGLE_OAUTH_TOKEN_JSON) or 'service_account' for a Shared Drive (uses GOOGLE_SERVICE_ACCOUNT_JSON).",
"value": "oauth",
"required": true
},
"GOOGLE_OAUTH_TOKEN_JSON": {
"description": "Required when GOOGLE_AUTH_MODE=oauth: contents of credentials/token.json produced locally by `python main.py drive-auth` (raw JSON or base64).",
"required": false
},
"GOOGLE_SERVICE_ACCOUNT_JSON": {
"description": "Required when GOOGLE_AUTH_MODE=service_account: the service-account key JSON (raw or base64). Service accounts only work with a Shared Drive they are a member of.",
"required": false
},
"GOOGLE_DRIVE_SCOPE": {
"description": "'drive.file' (least privilege; the bot only sees folders it created) or 'drive' (needed to use a folder you created yourself). Must match the scope used during drive-auth.",
"value": "drive.file",
"required": false
},
"GOOGLE_DRIVE_ROOT_FOLDER_ID": {
"description": "ID of the Drive folder that will contain the topic folders (the part after /folders/ in its URL). Empty = top level of My Drive.",
"required": false
},
"DRIVE_SHARED_DRIVE_ID": {
"description": "Shared Drive ID when the root folder lives in a Shared Drive (service-account setups).",
"required": false
},
"DRIVE_SHARE_MODE": {
"description": "'none' keeps uploads private (default). 'anyone_with_link' makes every uploaded file readable by anyone with the link.",
"value": "none",
"required": false
},
"PROCESS_MODE": {
"description": "'existing' (channel history only), 'new' (new posts only) or 'both'.",
"value": "both",
"required": false
},
"START_MESSAGE_ID": {
"description": "First channel message ID to consider when scanning history.",
"value": "1",
"required": false
},
"INCLUDE_DOCUMENT_VIDEOS": {
"description": "Also process videos that were sent as files/documents.",
"value": "true",
"required": false
},
"FILTER_TOPICS": {
"description": "Optional comma-separated list of Topic values to process; others are recorded as SKIPPED.",
"required": false
},
"FILTER_BATCHES": {
"description": "Optional comma-separated list of Batch values to process.",
"required": false
},
"BATCH_SUBFOLDERS_ENABLED": {
"description": "true = Root/Batch/Topic folders; false = Root/Topic (default).",
"value": "false",
"required": false
},
"DUPLICATE_POLICY": {
"description": "When a different file already has the same name in the topic folder: suffix_number ('Name (2).mp4'), suffix_message_id ('Name [123].mp4'), skip, or fail. Files are never overwritten.",
"value": "suffix_number",
"required": false
},
"MAX_RETRIES": {
"description": "Automatic retries for a failing video before it is marked FAILED.",
"value": "4",
"required": false
},
"RETRY_DELAY": {
"description": "Base retry delay in seconds (doubles on each retry, capped by RETRY_MAX_DELAY).",
"value": "30",
"required": false
},
"PROGRESS_INTERVAL": {
"description": "Seconds between edits of the Telegram progress message.",
"value": "10",
"required": false
},
"DOWNLOAD_DIR": {
"description": "Temporary download directory on the dyno's ephemeral disk.",
"value": "/tmp/telegram_drive_bot",
"required": false
},
"UPLOAD_CHUNK_SIZE": {
"description": "Resumable upload chunk size (multiple of 256KB). Held in memory per chunk; 8MB suits 512MB dynos.",
"value": "8MB",
"required": false
},
"MIN_FREE_DISK_SPACE": {
"description": "Free disk space to keep in reserve; a download is not started if it would go below this.",
"value": "512MB",
"required": false
},
"AUTO_START": {
"description": "true = start processing at every boot. Otherwise processing starts with /run and then resumes automatically after restarts.",
"value": "false",
"required": false
},
"LOG_LEVEL": {
"description": "debug, info, warning or error.",
"value": "info",
"required": false
},
"UPLOAD_RESTRICT_TO_SOURCE_CHANNEL": {
"description": "true = /upload links must point to SOURCE_CHANNEL_ID; false = any channel the Telegram account or bot can access.",
"value": "true",
"required": false
},
"UPLOAD_SETUP_TIMEOUT": {
"description": "Minutes before an unfinished /upload setup (waiting for links or /confirm) expires.",
"value": "30",
"required": false
},
"UPLOAD_MAX_RANGE": {
"description": "Largest number of message IDs one /upload task may cover.",
"value": "5000",
"required": false
},
"KEEP_FAILED_DOWNLOADS": {
"description": "Keep local files of failed videos on the dyno disk (default false: delete; they are downloaded again on retry).",
"value": "false",
"required": false
},
"TEMP_CLEANUP_INTERVAL": {
"description": "Seconds between sweeps that delete abandoned temporary files.",
"value": "3600",
"required": false
}
}
}