Spaces:
Paused
Paused
Update server.js
Browse files
server.js
CHANGED
|
@@ -451,7 +451,7 @@ fileRouter.get('/:botToken/getFile', async (req, res) => {
|
|
| 451 |
}
|
| 452 |
}
|
| 453 |
}
|
| 454 |
-
res.json(fileInfo);
|
| 455 |
} catch (error) {
|
| 456 |
console.error(`Error in /:botToken/getFile for file_id ${file_id}:`, error);
|
| 457 |
res.status(500).json({ error: 'Server error processing getFile request.', details: error.message });
|
|
@@ -539,27 +539,14 @@ app.use(PROXY_TELEGRAM_PATH_PREFIX, createProxyMiddleware({
|
|
| 539 |
app.get('/', (req, res) => {
|
| 540 |
const spaceHost = process.env.SPACE_HOST;
|
| 541 |
const baseUrl = req.protocol + '://' + (spaceHost || req.get('host'));
|
| 542 |
-
const
|
| 543 |
-
const
|
| 544 |
-
const
|
| 545 |
-
const
|
| 546 |
-
const
|
| 547 |
-
|
| 548 |
-
const
|
| 549 |
-
|
| 550 |
-
result: {
|
| 551 |
-
file_id: "EXAMPLE_FILE_ID",
|
| 552 |
-
file_unique_id: "EXAMPLE_UNIQUE_ID",
|
| 553 |
-
file_size: 123456,
|
| 554 |
-
file_path: `${TELEGRAM_DATA_DIR.replace(/</g, '<').replace(/>/g, '>')}/${relativeFilePathPh.replace(/</g, '<').replace(/>/g, '>')}`,
|
| 555 |
-
direct_download_link_by_path: `${baseUrl}/file/${relativeFilePathPh}`,
|
| 556 |
-
delete_link_by_path: `${baseUrl}/file/deleteFile?file=${encodeURIComponent(relativeFilePathPh.replace(/</g, '<').replace(/>/g, '>'))}`,
|
| 557 |
-
encrypted_download_link_by_path: encryptionKeyBuffer ? `${baseUrl}/file/downloadEncrypted?payload=${encryptedPayloadPh}` : "Encryption disabled",
|
| 558 |
-
direct_download_link_by_id: `${baseUrl}/file/${botTokenPh}/downloadFile?file_id=${fileIdPh}`,
|
| 559 |
-
delete_link_by_id: `${baseUrl}/file/${botTokenPh}/deleteById?file_id=${fileIdPh}`,
|
| 560 |
-
encrypted_download_link_by_id: encryptionKeyBuffer ? `${baseUrl}/file/downloadEncrypted?payload=${encryptedPayloadPh}` : "Encryption disabled"
|
| 561 |
-
}
|
| 562 |
-
}, null, 2).replace(/</g, '<').replace(/>/g, '>');
|
| 563 |
|
| 564 |
const htmlDoc = `
|
| 565 |
<!DOCTYPE html>
|
|
@@ -567,309 +554,138 @@ app.get('/', (req, res) => {
|
|
| 567 |
<head>
|
| 568 |
<meta charset="UTF-8">
|
| 569 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 570 |
-
<title>
|
| 571 |
<style>
|
| 572 |
-
body { font-family:
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
|
| 580 |
-
|
| 581 |
-
pre code { background-color: transparent; padding: 0; }
|
| 582 |
-
.endpoint-group { margin-bottom: 30px; padding: 20px; border: 1px solid #bdc3c7; border-radius: 5px; background-color: #fff; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
|
| 583 |
-
.endpoint-group h3 { margin-top: 0; border-bottom: 1px solid #ecf0f1; padding-bottom: 0.5em;}
|
| 584 |
-
.endpoint-group p { margin-bottom: 0.5em; }
|
| 585 |
-
.endpoint-group strong { color: #2980b9; }
|
| 586 |
-
.lang-toggle { text-align: center; margin-bottom: 30px; padding: 10px; background-color: #f8f9fa; border-radius: 5px;}
|
| 587 |
-
.lang-toggle button { padding: 10px 20px; margin: 0 8px; cursor: pointer; border: none; background-color: #e9ecef; color: #495057; border-radius: 4px; font-weight: bold; transition: background-color 0.2s, color 0.2s;}
|
| 588 |
-
.lang-toggle button.active { background-color: #007bff; color: white; }
|
| 589 |
.ru, .en { display: none; }
|
| 590 |
.ru.active, .en.active { display: block; }
|
| 591 |
-
table { width: 100%; border-collapse: collapse; margin
|
| 592 |
-
th, td { border: 1px solid #
|
| 593 |
-
th { background-color: #
|
| 594 |
-
td code { font-size: 90%; }
|
| 595 |
-
.param-table th:first-child { width: 20%; }
|
| 596 |
-
.param-table th:nth-child(2) { width: 15%; }
|
| 597 |
-
.param-table th:nth-child(3) { width: 15%; }
|
| 598 |
-
.param-table th:last-child { width: 50%; }
|
| 599 |
-
.note { background-color: #e7f3fe; border-left: 4px solid #2196F3; padding: 10px 15px; margin: 1.5em 0; border-radius: 0 4px 4px 0; }
|
| 600 |
-
.note strong { color: #1e88e5; }
|
| 601 |
-
.badge { background-color: #2ecc71; color: white; padding: 0.2em 0.6em; border-radius: 10px; font-size: 0.8em; margin-right: 5px; display: inline-block; vertical-align: middle;}
|
| 602 |
-
.badge-get { background-color: #3498db; }
|
| 603 |
-
.badge-post { background-color: #2ecc71; }
|
| 604 |
-
.badge-delete { background-color: #e74c3c; }
|
| 605 |
-
.endpoint-header { display: flex; align-items: center; margin-bottom: 0.5em; }
|
| 606 |
-
.endpoint-header .badge { margin-right: 10px; font-weight: bold; padding: 0.3em 0.7em;}
|
| 607 |
-
.endpoint-header code { font-size: 1.1em; font-weight: bold; }
|
| 608 |
</style>
|
| 609 |
</head>
|
| 610 |
<body>
|
| 611 |
-
<div class="
|
| 612 |
-
<
|
| 613 |
-
|
| 614 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 615 |
</div>
|
| 616 |
|
| 617 |
-
<
|
| 618 |
-
|
| 619 |
-
<
|
| 620 |
-
<
|
| 621 |
-
|
| 622 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
<
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
<
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
| 657 |
-
<
|
| 658 |
-
|
| 659 |
-
|
| 660 |
-
|
| 661 |
-
<table class="param-table">
|
| 662 |
-
<thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead>
|
| 663 |
-
<tbody>
|
| 664 |
-
<tr><td><code>TOKEN</code></td><td>string</td><td>Да</td><td>Токен вашего Telegram бота.</td></tr>
|
| 665 |
-
</tbody>
|
| 666 |
-
</table>
|
| 667 |
-
<h4>Параметры Query:</h4>
|
| 668 |
-
<table class="param-table">
|
| 669 |
-
<thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead>
|
| 670 |
-
<tbody>
|
| 671 |
-
<tr><td><code>file_id</code></td><td>string</td><td>Да</td><td>Идентификатор файла.</td></tr>
|
| 672 |
-
<tr><td><code>link_expiry_hours</code></td><td>integer</td><td>Нет</td><td>Срок действия для генерируемых зашифрованных ссылок в часах. <code>-1</code> для бессрочных. По умолчанию: <code>${DEFAULT_LINK_EXPIRY_HOURS}</code>.</td></tr>
|
| 673 |
-
</tbody>
|
| 674 |
-
</table>
|
| 675 |
-
<p><strong>Пример URL:</strong> <code>${baseUrl}/file/${botTokenPh}/getFile?file_id=${fileIdPh}&link_expiry_hours=2</code></p>
|
| 676 |
-
<h4>Пример Ответа (JSON):</h4>
|
| 677 |
-
<pre><code>${exampleGetFileResponse}</code></pre>
|
| 678 |
-
</section>
|
| 679 |
-
|
| 680 |
-
<section class="endpoint-group">
|
| 681 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/list</code></div>
|
| 682 |
-
<p><strong>Описание:</strong> Возвращает список файлов, их размеры и общий размер для указанного бота в его директории внутри <code>TELEGRAM_DATA_DIR</code>.</p>
|
| 683 |
-
<h4>Параметры Query:</h4>
|
| 684 |
-
<table class="param-table">
|
| 685 |
-
<thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead>
|
| 686 |
-
<tbody>
|
| 687 |
-
<tr><td><code>token</code></td><td>string</td><td>Да</td><td>Токен Telegram бота, для которого нужно получить список файлов.</td></tr>
|
| 688 |
-
</tbody>
|
| 689 |
-
</table>
|
| 690 |
-
<p><strong>Пример URL:</strong> <code>${baseUrl}/file/list?token=${botTokenPh}</code></p>
|
| 691 |
-
</section>
|
| 692 |
-
|
| 693 |
-
<section class="endpoint-group">
|
| 694 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/{TOKEN}/downloadFile</code></div>
|
| 695 |
-
<p><strong>Описание:</strong> Скачивает файл по его ID. Внутренне вызывает <code>getFile</code> для получения пути к файлу.</p>
|
| 696 |
-
<h4>Параметры Path:</h4>
|
| 697 |
-
<table class="param-table"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead><tbody><tr><td><code>TOKEN</code></td><td>string</td><td>Да</td><td>Токен бота.</td></tr></tbody></table>
|
| 698 |
-
<h4>Параметры Query:</h4>
|
| 699 |
-
<table class="param-table"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead><tbody><tr><td><code>file_id</code></td><td>string</td><td>Да</td><td>Идентификатор файла.</td></tr></tbody></table>
|
| 700 |
-
<p><strong>Пример URL:</strong> <code>${baseUrl}/file/${botTokenPh}/downloadFile?file_id=${fileIdPh}</code></p>
|
| 701 |
-
</section>
|
| 702 |
-
|
| 703 |
-
<section class="endpoint-group">
|
| 704 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/{RELATIVE_FILE_PATH_WITH_TOKEN}</code></div>
|
| 705 |
-
<p><strong>Описание:</strong> Скачивает файл по его полному относительному пути внутри <code>TELEGRAM_DATA_DIR</code>. Путь должен включать директорию с именем токена бота.</p>
|
| 706 |
-
<h4>Параметры Path:</h4>
|
| 707 |
-
<table class="param-table"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead><tbody><tr><td><code>RELATIVE_FILE_PATH_WITH_TOKEN</code></td><td>string</td><td>Да</td><td>Относительный путь к файлу, например, <code>${relativeFilePathPh}</code>.</td></tr></tbody></table>
|
| 708 |
-
<p><strong>Пример URL:</strong> <code>${baseUrl}/file/${relativeFilePathPh}</code></p>
|
| 709 |
-
</section>
|
| 710 |
-
|
| 711 |
-
<section class="endpoint-group">
|
| 712 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/downloadEncrypted</code></div>
|
| 713 |
-
<p><strong>Описание:</strong> Скачивает файл, используя зашифрованную полезную нагрузку (payload), полученную из эндпоинта <code>/file/{TOKEN}/getFile</code>. Проверяет срок действия ссылки.</p>
|
| 714 |
-
<h4>Параметры Query:</h4>
|
| 715 |
-
<table class="param-table"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead><tbody><tr><td><code>payload</code></td><td>string</td><td>Да</td><td>Зашифрованная строка.</td></tr></tbody></table>
|
| 716 |
-
<p><strong>Пример URL:</strong> <code>${baseUrl}/file/downloadEncrypted?payload=${encryptedPayloadPh}</code></p>
|
| 717 |
-
</section>
|
| 718 |
-
|
| 719 |
-
<section class="endpoint-group">
|
| 720 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/deleteFile</code></div>
|
| 721 |
-
<p><strong>Описание:</strong> Удаляет файл по его относительному пути внутри <code>TELEGRAM_DATA_DIR</code>.</p>
|
| 722 |
-
<h4>Параметры Query:</h4>
|
| 723 |
-
<table class="param-table"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead><tbody><tr><td><code>file</code></td><td>string</td><td>Да</td><td>Относительный путь к файлу, например, <code>${relativeFilePathPh}</code>.</td></tr></tbody></table>
|
| 724 |
-
<p><strong>Пример URL:</strong> <code>${baseUrl}/file/deleteFile?file=${encodeURIComponent(relativeFilePathPh.replace(/</g, '<').replace(/>/g, '>'))}</code></p>
|
| 725 |
-
</section>
|
| 726 |
-
|
| 727 |
-
<section class="endpoint-group">
|
| 728 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/{TOKEN}/deleteById</code></div>
|
| 729 |
-
<p><strong>Описание:</strong> Удаляет файл по его ID. Внутренне вызывает <code>getFile</code> для получения пути.</p>
|
| 730 |
-
<h4>Параметры Path:</h4>
|
| 731 |
-
<table class="param-table"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead><tbody><tr><td><code>TOKEN</code></td><td>string</td><td>Да</td><td>Токен бота.</td></tr></tbody></table>
|
| 732 |
-
<h4>Параметры Query:</h4>
|
| 733 |
-
<table class="param-table"><thead><tr><th>Параметр</th><th>Тип</th><th>Обязательный</th><th>Описание</th></tr></thead><tbody><tr><td><code>file_id</code></td><td>string</td><td>Да</td><td>Идентификатор файла.</td></tr></tbody></table>
|
| 734 |
-
<p><strong>Пример URL:</strong> <code>${baseUrl}/file/${botTokenPh}/deleteById?file_id=${fileIdPh}</code></p>
|
| 735 |
-
</section>
|
| 736 |
-
|
| 737 |
-
<h2>3. Общие Замечания</h2>
|
| 738 |
-
<div class="note">
|
| 739 |
-
<p><strong>Шифрование ссылок:</strong> ${encryptionKeyBuffer ? `Включено. Для генерации зашифрованных ссылок необходим секрет <code>LINK_ENCRYPTION_KEY</code>.` : `Отключено. Установите секрет <code>LINK_ENCRYPTION_KEY</code> для включения.`}</p>
|
| 740 |
-
<p><strong>Срок действия ссылок по умолчанию:</strong> <code>${DEFAULT_LINK_EXPIRY_HOURS}</code> часов (<code>-1</code> означает бессрочные). Может быть переопределен параметром <code>link_expiry_hours</code> в запросах к <code>/file/{TOKEN}/getFile</code>.</p>
|
| 741 |
-
<p><strong>Gist:</strong> ${ENV_GIST_ID && GITHUB_USERNAME ? `Информация о данном Space и доступных URL автоматически обновляется в <a href="https://gist.github.com/${GITHUB_USERNAME}/${ENV_GIST_ID}" target="_blank">этом Gist</a> (файл <code>hf_space_telegram_bot_api_proxy_info.json</code>).` : "Обновление Gist не настроено (отсутствуют <code>ENV_GIST_ID</code> или <code>GITHUB_USERNAME</code>)."}</p>
|
| 742 |
-
</div>
|
| 743 |
</div>
|
| 744 |
|
| 745 |
-
<
|
| 746 |
-
|
| 747 |
-
<
|
| 748 |
-
<
|
| 749 |
-
<
|
| 750 |
-
<
|
| 751 |
-
|
| 752 |
-
<h2>1. Telegram Bot API Proxy (Standard)</h2>
|
| 753 |
-
<section class="endpoint-group">
|
| 754 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><span class="badge badge-post">POST</span><code>${PROXY_TELEGRAM_PATH_PREFIX}/bot${botTokenPh}/{METHOD_NAME}</code></div>
|
| 755 |
-
<p><strong>Description:</strong> Directly proxies requests to your local Telegram Bot API server. This endpoint returns the <strong>unmodified</strong> response from the Telegram API, ensuring full compatibility with standard Telegram clients.</p>
|
| 756 |
-
<h4>Path Parameters:</h4>
|
| 757 |
-
<table class="param-table">
|
| 758 |
-
<thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead>
|
| 759 |
-
<tbody>
|
| 760 |
-
<tr><td><code>TOKEN</code></td><td>string</td><td>Yes</td><td>Your Telegram bot token.</td></tr>
|
| 761 |
-
<tr><td><code>METHOD_NAME</code></td><td>string</td><td>Yes</td><td>The Telegram Bot API method name (e.g., <code>getMe</code>, <code>sendMessage</code>).</td></tr>
|
| 762 |
-
</tbody>
|
| 763 |
-
</table>
|
| 764 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}${PROXY_TELEGRAM_PATH_PREFIX}/bot${botTokenPh}/getMe</code></p>
|
| 765 |
-
</section>
|
| 766 |
-
|
| 767 |
-
<h2>2. Enhanced Tools & File Operations</h2>
|
| 768 |
-
|
| 769 |
-
<section class="endpoint-group">
|
| 770 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/stats</code></div>
|
| 771 |
-
<p><strong>Description:</strong> Retrieves disk usage statistics for the Telegram Bot API data directory.</p>
|
| 772 |
-
<h4>Query Parameters:</h4>
|
| 773 |
-
<table class="param-table">
|
| 774 |
-
<thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead>
|
| 775 |
-
<tbody>
|
| 776 |
-
<tr><td><code>run_ttl_now</code></td><td>boolean</td><td>No</td><td>If <code>true</code>, immediately triggers cleanup of old files based on the <code>FILES_TTL_HOURS</code> setting.</td></tr>
|
| 777 |
-
</tbody>
|
| 778 |
-
</table>
|
| 779 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/stats</code></p>
|
| 780 |
-
<p><strong>Example URL (with cleanup):</strong> <code>${baseUrl}/stats?run_ttl_now=true</code></p>
|
| 781 |
-
<h4>Example Response (JSON):</h4>
|
| 782 |
-
<pre><code>${JSON.stringify({ directory: TELEGRAM_DATA_DIR, fileCount: 120, totalSizeBytes: 512000000, totalSizeHuman: "488.28 MB", files_ttl_hours: FILES_TTL_HOURS > 0 ? FILES_TTL_HOURS : "disabled", ttl_cleanup_on_this_request: { message: "Cleanup completed..." } }, null, 2)}</code></pre>
|
| 783 |
-
</section>
|
| 784 |
-
|
| 785 |
-
<section class="endpoint-group">
|
| 786 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/{TOKEN}/getFile</code></div>
|
| 787 |
-
<p><strong>Description:</strong> Retrieves file information from the Telegram API (via an internal call to <code>/bot{TOKEN}/getFile</code>) and augments the standard Telegram response with additional download and delete links, including time-limited encrypted versions.</p>
|
| 788 |
-
<h4>Path Parameters:</h4>
|
| 789 |
-
<table class="param-table">
|
| 790 |
-
<thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead>
|
| 791 |
-
<tbody>
|
| 792 |
-
<tr><td><code>TOKEN</code></td><td>string</td><td>Yes</td><td>Your Telegram bot token.</td></tr>
|
| 793 |
-
</tbody>
|
| 794 |
-
</table>
|
| 795 |
-
<h4>Query Parameters:</h4>
|
| 796 |
-
<table class="param-table">
|
| 797 |
-
<thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead>
|
| 798 |
-
<tbody>
|
| 799 |
-
<tr><td><code>file_id</code></td><td>string</td><td>Yes</td><td>The file identifier.</td></tr>
|
| 800 |
-
<tr><td><code>link_expiry_hours</code></td><td>integer</td><td>No</td><td>Expiry time for generated encrypted links in hours. <code>-1</code> for indefinite. Default: <code>${DEFAULT_LINK_EXPIRY_HOURS}</code>.</td></tr>
|
| 801 |
-
</tbody>
|
| 802 |
-
</table>
|
| 803 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/file/${botTokenPh}/getFile?file_id=${fileIdPh}&link_expiry_hours=2</code></p>
|
| 804 |
-
<h4>Example Response (JSON):</h4>
|
| 805 |
-
<pre><code>${exampleGetFileResponse}</code></pre>
|
| 806 |
-
</section>
|
| 807 |
-
|
| 808 |
-
<section class="endpoint-group">
|
| 809 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/list</code></div>
|
| 810 |
-
<p><strong>Description:</strong> Returns a list of files, their sizes, and the total size for the specified bot within its directory inside <code>TELEGRAM_DATA_DIR</code>.</p>
|
| 811 |
-
<h4>Query Parameters:</h4>
|
| 812 |
-
<table class="param-table">
|
| 813 |
-
<thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead>
|
| 814 |
-
<tbody>
|
| 815 |
-
<tr><td><code>token</code></td><td>string</td><td>Yes</td><td>The Telegram bot token for which to list files.</td></tr>
|
| 816 |
-
</tbody>
|
| 817 |
-
</table>
|
| 818 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/file/list?token=${botTokenPh}</code></p>
|
| 819 |
-
</section>
|
| 820 |
-
|
| 821 |
-
<section class="endpoint-group">
|
| 822 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/{TOKEN}/downloadFile</code></div>
|
| 823 |
-
<p><strong>Description:</strong> Downloads a file by its ID. Internally calls <code>getFile</code> to retrieve the file path.</p>
|
| 824 |
-
<h4>Path Parameters:</h4>
|
| 825 |
-
<table class="param-table"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>TOKEN</code></td><td>string</td><td>Yes</td><td>Bot token.</td></tr></tbody></table>
|
| 826 |
-
<h4>Query Parameters:</h4>
|
| 827 |
-
<table class="param-table"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>file_id</code></td><td>string</td><td>Yes</td><td>File identifier.</td></tr></tbody></table>
|
| 828 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/file/${botTokenPh}/downloadFile?file_id=${fileIdPh}</code></p>
|
| 829 |
-
</section>
|
| 830 |
-
|
| 831 |
-
<section class="endpoint-group">
|
| 832 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/{RELATIVE_FILE_PATH_WITH_TOKEN}</code></div>
|
| 833 |
-
<p><strong>Description:</strong> Downloads a file by its full relative path within <code>TELEGRAM_DATA_DIR</code>. The path must include the bot token directory.</p>
|
| 834 |
-
<h4>Path Parameters:</h4>
|
| 835 |
-
<table class="param-table"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>RELATIVE_FILE_PATH_WITH_TOKEN</code></td><td>string</td><td>Yes</td><td>Relative file path, e.g., <code>${relativeFilePathPh}</code>.</td></tr></tbody></table>
|
| 836 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/file/${relativeFilePathPh}</code></p>
|
| 837 |
-
</section>
|
| 838 |
-
|
| 839 |
-
<section class="endpoint-group">
|
| 840 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/downloadEncrypted</code></div>
|
| 841 |
-
<p><strong>Description:</strong> Downloads a file using an encrypted payload obtained from the <code>/file/{TOKEN}/getFile</code> endpoint. Validates link expiry.</p>
|
| 842 |
-
<h4>Query Parameters:</h4>
|
| 843 |
-
<table class="param-table"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>payload</code></td><td>string</td><td>Yes</td><td>Encrypted string.</td></tr></tbody></table>
|
| 844 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/file/downloadEncrypted?payload=${encryptedPayloadPh}</code></p>
|
| 845 |
-
</section>
|
| 846 |
-
|
| 847 |
-
<section class="endpoint-group">
|
| 848 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/deleteFile</code></div>
|
| 849 |
-
<p><strong>Description:</strong> Deletes a file by its relative path within <code>TELEGRAM_DATA_DIR</code>.</p>
|
| 850 |
-
<h4>Query Parameters:</h4>
|
| 851 |
-
<table class="param-table"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>file</code></td><td>string</td><td>Yes</td><td>Relative file path, e.g., <code>${relativeFilePathPh}</code>.</td></tr></tbody></table>
|
| 852 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/file/deleteFile?file=${encodeURIComponent(relativeFilePathPh.replace(/</g, '<').replace(/>/g, '>'))}</code></p>
|
| 853 |
-
</section>
|
| 854 |
-
|
| 855 |
-
<section class="endpoint-group">
|
| 856 |
-
<div class="endpoint-header"><span class="badge badge-get">GET</span><code>/file/{TOKEN}/deleteById</code></div>
|
| 857 |
-
<p><strong>Description:</strong> Deletes a file by its ID. Internally calls <code>getFile</code> to retrieve the path.</p>
|
| 858 |
-
<h4>Path Parameters:</h4>
|
| 859 |
-
<table class="param-table"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>TOKEN</code></td><td>string</td><td>Yes</td><td>Bot token.</td></tr></tbody></table>
|
| 860 |
-
<h4>Query Parameters:</h4>
|
| 861 |
-
<table class="param-table"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>file_id</code></td><td>string</td><td>Yes</td><td>File identifier.</td></tr></tbody></table>
|
| 862 |
-
<p><strong>Example URL:</strong> <code>${baseUrl}/file/${botTokenPh}/deleteById?file_id=${fileIdPh}</code></p>
|
| 863 |
-
</section>
|
| 864 |
-
|
| 865 |
-
<h2>3. General Notes</h2>
|
| 866 |
-
<div class="note">
|
| 867 |
-
<p><strong>Link Encryption:</strong> ${encryptionKeyBuffer ? `Enabled. Requires the <code>LINK_ENCRYPTION_KEY</code> secret to generate encrypted links.` : `Disabled. Set the <code>LINK_ENCRYPTION_KEY</code> secret to enable.`}</p>
|
| 868 |
-
<p><strong>Default Link Expiry:</strong> <code>${DEFAULT_LINK_EXPIRY_HOURS}</code> hours (<code>-1</code> means indefinite). Can be overridden by the <code>link_expiry_hours</code> parameter in <code>/file/{TOKEN}/getFile</code> requests.</p>
|
| 869 |
-
<p><strong>Gist:</strong> ${ENV_GIST_ID && GITHUB_USERNAME ? `Information about this Space and available URLs is automatically updated in <a href="https://gist.github.com/${GITHUB_USERNAME}/${ENV_GIST_ID}" target="_blank">this Gist</a> (file <code>hf_space_telegram_bot_api_proxy_info.json</code>).` : "Gist update is not configured (<code>ENV_GIST_ID</code> or <code>GITHUB_USERNAME</code> missing)."}</p>
|
| 870 |
-
</div>
|
| 871 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 872 |
</div>
|
|
|
|
| 873 |
<script>
|
| 874 |
function setLang(lang) {
|
| 875 |
document.querySelectorAll('.ru, .en').forEach(el => el.classList.remove('active'));
|
|
@@ -889,7 +705,6 @@ app.get('/', (req, res) => {
|
|
| 889 |
app.listen(APP_PORT, () => {
|
| 890 |
console.log(`Main app (Proxy & Tools) listening on port ${APP_PORT}`);
|
| 891 |
console.log(`Telegram Bot API (internal) should be on port ${INTERNAL_TELEGRAM_API_PORT}`);
|
| 892 |
-
console.log(`Documentation available at /`);
|
| 893 |
console.log(`Statistics available at /stats`);
|
| 894 |
console.log(`File operations available under /file/`);
|
| 895 |
console.log(`Telegram API (standard) proxied from ${PROXY_TELEGRAM_PATH_PREFIX}/`);
|
|
|
|
| 451 |
}
|
| 452 |
}
|
| 453 |
}
|
| 454 |
+
res.json(fileInfo);
|
| 455 |
} catch (error) {
|
| 456 |
console.error(`Error in /:botToken/getFile for file_id ${file_id}:`, error);
|
| 457 |
res.status(500).json({ error: 'Server error processing getFile request.', details: error.message });
|
|
|
|
| 539 |
app.get('/', (req, res) => {
|
| 540 |
const spaceHost = process.env.SPACE_HOST;
|
| 541 |
const baseUrl = req.protocol + '://' + (spaceHost || req.get('host'));
|
| 542 |
+
const botTokenPlaceholder = "<YOUR_BOT_TOKEN>";
|
| 543 |
+
const fileIdPlaceholder = "<FILE_ID>";
|
| 544 |
+
const methodPlaceholder = "<METHOD_NAME>";
|
| 545 |
+
const categoryPlaceholder = "<CATEGORY>";
|
| 546 |
+
const filenamePlaceholder = "<FILENAME>";
|
| 547 |
+
const relativeFilePathWithTokenPlaceholder = `bot${botTokenPlaceholder}/${categoryPlaceholder}/${filenamePlaceholder}`;
|
| 548 |
+
const linkExpiryPlaceholder = "<HOURS>";
|
| 549 |
+
const encryptedPayloadPlaceholder = "<ENCRYPTED_PAYLOAD>";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 550 |
|
| 551 |
const htmlDoc = `
|
| 552 |
<!DOCTYPE html>
|
|
|
|
| 554 |
<head>
|
| 555 |
<meta charset="UTF-8">
|
| 556 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 557 |
+
<title>Telegram Bot API Proxy & Tools Documentation</title>
|
| 558 |
<style>
|
| 559 |
+
body { font-family: sans-serif; line-height: 1.6; padding: 20px; max-width: 900px; margin: auto; }
|
| 560 |
+
h1, h2, h3, h4 { color: #333; }
|
| 561 |
+
code { background-color: #f4f4f4; padding: 2px 6px; border-radius: 4px; font-family: monospace; word-break: break-all;}
|
| 562 |
+
pre { background-color: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto; }
|
| 563 |
+
.endpoint { margin-bottom: 15px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
|
| 564 |
+
.endpoint strong { display: inline-block; min-width: 70px; }
|
| 565 |
+
.lang-toggle { text-align: center; margin-bottom: 20px; }
|
| 566 |
+
.lang-toggle button { padding: 8px 15px; margin: 0 5px; cursor: pointer; border: 1px solid #ccc; background-color: #eee; border-radius: 4px;}
|
| 567 |
+
.lang-toggle button.active { background-color: #007bff; color: white; border-color: #007bff; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 568 |
.ru, .en { display: none; }
|
| 569 |
.ru.active, .en.active { display: block; }
|
| 570 |
+
table { width: 100%; border-collapse: collapse; margin-bottom: 15px; }
|
| 571 |
+
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
| 572 |
+
th { background-color: #f9f9f9; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 573 |
</style>
|
| 574 |
</head>
|
| 575 |
<body>
|
| 576 |
+
<div class="lang-toggle">
|
| 577 |
+
<button id="lang-ru-btn" onclick="setLang('ru')">Русский</button>
|
| 578 |
+
<button id="lang-en-btn" onclick="setLang('en')">English</button>
|
| 579 |
+
</div>
|
| 580 |
+
|
| 581 |
+
<div class="ru">
|
| 582 |
+
<h1>Прокси Telegram Bot API с расширенными инструментами</h1>
|
| 583 |
+
<p>Этот Space запускает локальный сервер Telegram Bot API и предоставляет многофункциональное Node.js приложение-прокси с дополнительными инструментами.</p>
|
| 584 |
+
<p><strong>Базовый URL вашего Space:</strong> <code>${baseUrl}</code></p>
|
| 585 |
+
|
| 586 |
+
<h2>1. Основные возможности</h2>
|
| 587 |
+
<ul>
|
| 588 |
+
<li>"Чистое" проксирование Telegram Bot API (эндпоинт <code>${PROXY_TELEGRAM_PATH_PREFIX}/</code>).</li>
|
| 589 |
+
<li>Специальный эндпоинт <code>/file/${botTokenPlaceholder}/getFile</code> для получения стандартного ответа Telegram API, дополненного ссылками на скачивание/удаление.</li>
|
| 590 |
+
<li>Управление файлами: статистика, скачивание, удаление, листинг.</li>
|
| 591 |
+
<li>Зашифрованные ссылки с истечением срока действия.</li>
|
| 592 |
+
<li>Автоматическая очистка кэша (TTL).</li>
|
| 593 |
+
<li>Интеграция с GitHub Gist.</li>
|
| 594 |
+
</ul>
|
| 595 |
+
|
| 596 |
+
<h2>2. Прокси Telegram Bot API (Стандартный)</h2>
|
| 597 |
+
<div class="endpoint">
|
| 598 |
+
<strong>URL:</strong> <code>${baseUrl}${PROXY_TELEGRAM_PATH_PREFIX}/bot${botTokenPlaceholder}/${methodPlaceholder}</code><br>
|
| 599 |
+
<strong>Описание:</strong> Используйте этот URL вместо стандартного <code>api.telegram.org</code>. Возвращает <strong>неизмененный</strong> ответ от Telegram API.<br>
|
| 600 |
+
</div>
|
| 601 |
+
|
| 602 |
+
<h2>3. Расширенные инструменты и операции с файлами</h2>
|
| 603 |
+
<h3>3.1. Получение информации о файле с дополнительными ссылками</h3>
|
| 604 |
+
<div class="endpoint">
|
| 605 |
+
<strong>URL:</strong> <code>${baseUrl}/file/${botTokenPlaceholder}/getFile?file_id=${fileIdPlaceholder}</code><br>
|
| 606 |
+
<strong>Метод:</strong> <code>GET</code><br>
|
| 607 |
+
<strong>Описание:</strong> Делает запрос к локальному Telegram API, получает стандартный ответ и дополняет его полями: <code>direct_download_link_by_path</code>, <code>direct_download_link_by_id</code>, <code>delete_link_by_path</code>, <code>delete_link_by_id</code>, <code>encrypted_download_link_by_path</code>, <code>encrypted_download_link_by_id</code>.<br>
|
| 608 |
+
<strong>Управление сроком действия зашифрованных ссылок:</strong> Добавьте параметр <code>?link_expiry_hours=${linkExpiryPlaceholder}</code> к URL (<code>${linkExpiryPlaceholder}</code> - часы, <code>-1</code> для бессрочной). По умолчанию: ${DEFAULT_LINK_EXPIRY_HOURS} ч.
|
| 609 |
+
</div>
|
| 610 |
+
|
| 611 |
+
<h3>3.2. Статистика</h3>
|
| 612 |
+
<div class="endpoint">
|
| 613 |
+
<strong>URL:</strong> <code>${baseUrl}/stats</code><br>
|
| 614 |
+
<strong>Метод:</strong> <code>GET</code><br>
|
| 615 |
+
<strong>Параметры Query:</strong> <code>run_ttl_now=true</code> (опционально) - запустить очистку.<br>
|
| 616 |
+
<strong>Ответ:</strong> JSON со статистикой.
|
| 617 |
</div>
|
| 618 |
|
| 619 |
+
<h3>3.3. Другие операции с файлами (базовый путь: <code>${baseUrl}/file</code>)</h3>
|
| 620 |
+
<table>
|
| 621 |
+
<thead><tr><th>Операция</th><th>URL</th><th>Метод</th><th>Описание</th></tr></thead>
|
| 622 |
+
<tbody>
|
| 623 |
+
<tr><td>Список файлов бота</td><td><code>/list?token=${botTokenPlaceholder}</code></td><td>GET</td><td>JSON со списком файлов и их размерами.</td></tr>
|
| 624 |
+
<tr><td>Скачать по ID</td><td><code>/${botTokenPlaceholder}/downloadFile?file_id=${fileIdPlaceholder}</code></td><td>GET</td><td>Файл для скачивания.</td></tr>
|
| 625 |
+
<tr><td>Скачать по пути</td><td><code>/${relativeFilePathWithTokenPlaceholder}</code></td><td>GET</td><td>Файл для скачивания.</td></tr>
|
| 626 |
+
<tr><td>Скачать по зашифр. ссылке</td><td><code>/downloadEncrypted?payload=${encryptedPayloadPlaceholder}</code></td><td>GET</td><td>Файл, если ссылка действительна.</td></tr>
|
| 627 |
+
<tr><td>Удалить по пути</td><td><code>/deleteFile?file=${relativeFilePathWithTokenPlaceholder}</code></td><td>GET</td><td>JSON с результатом.</td></tr>
|
| 628 |
+
<tr><td>Удалить по ID</td><td><code>/${botTokenPlaceholder}/deleteById?file_id=${fileIdPlaceholder}</code></td><td>GET</td><td>JSON с результатом.</td></tr>
|
| 629 |
+
</tbody>
|
| 630 |
+
</table>
|
| 631 |
+
<p><strong>Замечание о Gist:</strong> Если настроено, информация о Space обновляется в <a href="https://gist.github.com/${GITHUB_USERNAME || "_"}/${ENV_GIST_ID}" target="_blank">вашем Gist</a> (файл <code>hf_space_telegram_bot_api_proxy_info.json</code>).</p>
|
| 632 |
+
<p><strong>Шифрование ссылок:</strong> ${encryptionKeyBuffer ? "Включено" : "Отключено (LINK_ENCRYPTION_KEY не установлен)"}.</p>
|
| 633 |
+
</div>
|
| 634 |
+
|
| 635 |
+
<div class="en">
|
| 636 |
+
<h1>Telegram Bot API Proxy & Tools</h1>
|
| 637 |
+
<p>This Space runs a local Telegram Bot API server and provides a feature-rich Node.js proxy application with additional tools.</p>
|
| 638 |
+
<p><strong>Your Space Base URL:</strong> <code>${baseUrl}</code></p>
|
| 639 |
+
|
| 640 |
+
<h2>1. Core Features</h2>
|
| 641 |
+
<ul>
|
| 642 |
+
<li>"Clean" Telegram Bot API Proxying (<code>${PROXY_TELEGRAM_PATH_PREFIX}/</code> endpoint).</li>
|
| 643 |
+
<li>Dedicated endpoint <code>/file/${botTokenPlaceholder}/getFile</code> to get standard Telegram API response augmented with download/delete links.</li>
|
| 644 |
+
<li>File Management: statistics, download, delete, list.</li>
|
| 645 |
+
<li>Encrypted links with expiry.</li>
|
| 646 |
+
<li>Automatic Cache Cleanup (TTL).</li>
|
| 647 |
+
<li>GitHub Gist Integration.</li>
|
| 648 |
+
</ul>
|
| 649 |
+
|
| 650 |
+
<h2>2. Telegram Bot API Proxy (Standard)</h2>
|
| 651 |
+
<div class="endpoint">
|
| 652 |
+
<strong>URL:</strong> <code>${baseUrl}${PROXY_TELEGRAM_PATH_PREFIX}/bot${botTokenPlaceholder}/${methodPlaceholder}</code><br>
|
| 653 |
+
<strong>Description:</strong> Use this URL instead of the standard <code>api.telegram.org</code>. Returns the <strong>unmodified</strong> response from the Telegram API.<br>
|
| 654 |
+
</div>
|
| 655 |
+
|
| 656 |
+
<h2>3. Enhanced Tools & File Operations</h2>
|
| 657 |
+
<h3>3.1. Get File Info with Augmented Links</h3>
|
| 658 |
+
<div class="endpoint">
|
| 659 |
+
<strong>URL:</strong> <code>${baseUrl}/file/${botTokenPlaceholder}/getFile?file_id=${fileIdPlaceholder}</code><br>
|
| 660 |
+
<strong>Method:</strong> <code>GET</code><br>
|
| 661 |
+
<strong>Description:</strong> Makes a request to the local Telegram API, gets the standard response, and augments it with: <code>direct_download_link_by_path</code>, <code>direct_download_link_by_id</code>, <code>delete_link_by_path</code>, <code>delete_link_by_id</code>, <code>encrypted_download_link_by_path</code>, <code>encrypted_download_link_by_id</code>.<br>
|
| 662 |
+
<strong>Encrypted Link Expiry Management:</strong> Add <code>?link_expiry_hours=${linkExpiryPlaceholder}</code> to the URL (<code>${linkExpiryPlaceholder}</code> is hours, <code>-1</code> for indefinite). Default: ${DEFAULT_LINK_EXPIRY_HOURS}h.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 663 |
</div>
|
| 664 |
|
| 665 |
+
<h3>3.2. Statistics</h3>
|
| 666 |
+
<div class="endpoint">
|
| 667 |
+
<strong>URL:</strong> <code>${baseUrl}/stats</code><br>
|
| 668 |
+
<strong>Method:</strong> <code>GET</code><br>
|
| 669 |
+
<strong>Query Parameters:</strong> <code>run_ttl_now=true</code> (optional) - trigger cleanup.<br>
|
| 670 |
+
<strong>Response:</strong> JSON with statistics.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 671 |
</div>
|
| 672 |
+
|
| 673 |
+
<h3>3.3. Other File Operations (base path: <code>${baseUrl}/file</code>)</h3>
|
| 674 |
+
<table>
|
| 675 |
+
<thead><tr><th>Операция</th><th>URL</th><th>Метод</th><th>Описание</th></tr></thead>
|
| 676 |
+
<tbody>
|
| 677 |
+
<tr><td>List Bot Files</td><td><code>/list?token=${botTokenPlaceholder}</code></td><td>GET</td><td>JSON list of files and their sizes.</td></tr>
|
| 678 |
+
<tr><td>Download by ID</td><td><code>/${botTokenPlaceholder}/downloadFile?file_id=${fileIdPlaceholder}</code></td><td>GET</td><td>The file for download.</td></tr>
|
| 679 |
+
<tr><td>Download by Path</td><td><code>/${relativeFilePathWithTokenPlaceholder}</code></td><td>GET</td><td>The file for download.</td></tr>
|
| 680 |
+
<tr><td>Download via Encrypted Link</td><td><code>/downloadEncrypted?payload=${encryptedPayloadPlaceholder}</code></td><td>GET</td><td>File, if link is valid.</td></tr>
|
| 681 |
+
<tr><td>Delete by Path</td><td><code>/deleteFile?file=${relativeFilePathWithTokenPlaceholder}</code></td><td>GET</td><td>JSON with result.</td></tr>
|
| 682 |
+
<tr><td>Delete by ID</td><td><code>/${botTokenPlaceholder}/deleteById?file_id=${fileIdPlaceholder}</code></td><td>GET</td><td>JSON with result.</td></tr>
|
| 683 |
+
</tbody>
|
| 684 |
+
</table>
|
| 685 |
+
<p><strong>Gist Note:</strong> If configured, Space info is updated in <a href="https://gist.github.com/${GITHUB_USERNAME || "_"}/${ENV_GIST_ID}" target="_blank">your Gist</a> (file <code>hf_space_telegram_bot_api_proxy_info.json</code>).</p>
|
| 686 |
+
<p><strong>Link Encryption:</strong> ${encryptionKeyBuffer ? "Enabled" : "Disabled (LINK_ENCRYPTION_KEY not set)"}.</p>
|
| 687 |
</div>
|
| 688 |
+
|
| 689 |
<script>
|
| 690 |
function setLang(lang) {
|
| 691 |
document.querySelectorAll('.ru, .en').forEach(el => el.classList.remove('active'));
|
|
|
|
| 705 |
app.listen(APP_PORT, () => {
|
| 706 |
console.log(`Main app (Proxy & Tools) listening on port ${APP_PORT}`);
|
| 707 |
console.log(`Telegram Bot API (internal) should be on port ${INTERNAL_TELEGRAM_API_PORT}`);
|
|
|
|
| 708 |
console.log(`Statistics available at /stats`);
|
| 709 |
console.log(`File operations available under /file/`);
|
| 710 |
console.log(`Telegram API (standard) proxied from ${PROXY_TELEGRAM_PATH_PREFIX}/`);
|