# BotBhai Telegram Bot Runtime Contract

Human documentation: https://botbhai.top/docs/bot-development
AI-readable contract: https://botbhai.top/docs/bot-development/ai.md

> This document is the source of truth for AI assistants and developers generating user bot code for this platform.

## 1. Runtime truth

- Runtime: plain PHP webhook request lifecycle.
- Supported runnable language: PHP only.
- PHP compatibility target: PHP 8.1+.
- Intended custom project entry: exact lowercase root file `bot.php`.
- Telegram update body: JSON from `php://input`.
- Webhook mode only: no long polling, daemon, infinite loop, persistent worker, Node worker, or Python worker.
- Do not deliver a user Laravel project, Artisan command, migration, or bot `.env`.
- Small helper files/folders are allowed, but `bot.php` is the entry file.

## 2. Actual Create / Start / Restart behavior

1. On **Create Bot**, the platform verifies the BotFather token with Telegram `getMe`.
2. Telegram's verified username is authoritative and is synchronized to the bot record.
3. The platform creates a safe default root `bot.php`.
4. The current application automatically runs the Start activation path once for a newly created bot.
5. **Save**, **Edit**, direct file import, and ZIP import only change private project files. They do not refresh an already running runtime.
6. After changing code:
   - if the bot is running, **Save then Restart**;
   - if the bot is stopped, **Start** or **Deploy**.
7. Start/Deploy validates the PHP project, verifies Telegram identity again, provisions private runtime credentials, creates a protected webhook wrapper, probes the endpoint when possible, and calls Telegram `setWebhook`.
8. Restart force-stops the old webhook/runtime and then performs a fresh Start from current files.
9. Stop removes the Telegram webhook, public runtime wrapper, and private runtime credential directory.
10. Force Stop also asks Telegram to drop pending updates.

### Important missing-file behavior

The runtime currently creates a safe default `bot.php` if root `bot.php` is missing at Start/Restart. Therefore every AI/developer delivery **must still include its intended code as root `bot.php`**. Otherwise the platform may run the generated default bot instead of the intended imported code.

## 3. Managed credentials

The website owns the BotFather token. At Start/Restart the protected runtime defines these constants before loading user code:

- `BOT_TOKEN`
- `BOT_USERNAME`

Rules:

- Use them directly as predefined constants.
- Never hard-code or redefine their values.
- Never request the user to paste them into PHP source.
- Never print, log, serialize, expose, or return the token.
- Do not create token/username placeholders.
- Do not create a bot `.env` for these values.
- `BOT_USERNAME` is normalized without an `@` prefix.
- `ADMIN_ID` is not managed by this contract. Add a clearly marked numeric placeholder only when the requested feature needs an admin Telegram user ID.

Recommended guard:

```php
if (!defined('BOT_TOKEN') || !defined('BOT_USERNAME')) {
    http_response_code(503);
    exit('Runtime credentials unavailable');
}
```

## 4. Minimal working `bot.php`

```php
<?php

declare(strict_types=1);

if (!defined('BOT_TOKEN') || !defined('BOT_USERNAME')) {
    http_response_code(503);
    exit('Runtime credentials unavailable');
}

function telegramApi(string $method, array $data = []): array
{
    $url = 'https://api.telegram.org/bot'.BOT_TOKEN.'/'.$method;
    $ch = curl_init($url);
    if ($ch === false) {
        return ['ok' => false, 'description' => 'Unable to initialize cURL.'];
    }

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $data,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_TIMEOUT => 20,
        CURLOPT_HTTPHEADER => ['Accept: application/json'],
    ]);

    $raw = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if (!is_string($raw)) {
        return ['ok' => false, 'description' => $error !== '' ? $error : 'Telegram request failed.'];
    }

    $decoded = json_decode($raw, true);
    return is_array($decoded)
        ? $decoded
        : ['ok' => false, 'description' => 'Invalid Telegram response.'];
}

$update = json_decode(file_get_contents('php://input') ?: '{}', true);
$message = is_array($update) ? ($update['message'] ?? null) : null;

if (is_array($message) && isset($message['chat']['id'])) {
    $text = trim((string) ($message['text'] ?? ''));

    if (preg_match('~^/start(?:@'.preg_quote(BOT_USERNAME, '~').')?(?:\\s|$)~i', $text)) {
        telegramApi('sendMessage', [
            'chat_id' => (string) $message['chat']['id'],
            'text' => 'Bot is working successfully ✅',
        ]);
    }
}

http_response_code(200);
echo 'OK';
```

## 5. Security constraints enforced at activation

The runtime scans every PHP file before enabling the webhook.

Do not use:

- OS/process execution: `exec`, `shell_exec`, `system`, `passthru`, `proc_open`, `popen`, `pcntl_exec`, `pcntl_fork`, shell backticks.
- `eval`.
- Generic dynamic invocation helpers such as `call_user_func`, `call_user_func_array`, `forward_static_call`, `forward_static_call_array`.
- Variable-function invocation such as `$fn(...)`.
- blocked high-risk classes including FFI/COM/DotNet and Reflection invocation classes.
- blocked stream markers including `expect://`, `phar://`, and `php://filter`.
- symbolic links in bot projects.

Also:

- validate nested Telegram update shapes;
- allowlist callback actions;
- verify numeric `ADMIN_ID` before every admin-only action;
- prevent path traversal;
- sanitize filenames;
- use bounded input sizes and HTTP timeouts;
- use file locking and atomic replacement when JSON state integrity matters;
- escape HTML when using Telegram `parse_mode=HTML`.

## 6. Import/export contract

- Direct file import is supported.
- ZIP import/extraction is supported.
- Nested helper folders are supported.
- ZIP paths are validated; absolute paths, traversal, symlinks, encrypted entries, suspicious expansion, and unsafe executable/config extensions are blocked.
- Project export contains selected project files, not dashboard-managed Telegram credentials.
- For intended custom behavior, a ZIP should contain root `bot.php`, not only `some-folder/bot.php`.

## 7. AI output contract

When asked to build a bot for this platform:

1. First show the exact file tree.
2. Deliver root `bot.php` in full.
3. Add only genuinely needed helper files.
4. Use `BOT_TOKEN` and `BOT_USERNAME` directly.
5. Do not include their values or placeholders.
6. Do not output pseudo-code, TODOs, omitted sections, SQL, Laravel scaffolding, a bot `.env`, polling, or persistent workers.
7. Handle `/command` and `/command@BotUsername` safely.
8. End with these exact operational steps:
   - Create Bot with token + username. The current app verifies Telegram identity, creates a default `bot.php`, and attempts auto-start.
   - Save/import the intended root `bot.php`.
   - If the bot is already running, press **Restart**; if stopped, press **Start** or **Deploy**.
   - Test `/start` and inspect Logs.
   - After every later code edit: **Save → Restart** for a running bot.

## 8. Master prompt for any AI

```text
Read and follow these platform docs exactly:
Human docs: https://botbhai.top/docs/bot-development
AI-readable contract: https://botbhai.top/docs/bot-development/ai.md

Build a complete Telegram bot for this custom runtime.

Mandatory constraints:
- PHP 8.1+ plain webhook code.
- Intended custom entry is exact root bot.php.
- Read Telegram JSON from php://input.
- BOT_TOKEN and BOT_USERNAME are predefined by the platform at runtime; use them directly.
- Never hard-code, redefine, request, print, log, expose, or create placeholders for token/username values.
- Webhook only; no polling, daemon, infinite loop, Node worker, Python worker, Laravel user project, Artisan, migrations, or bot .env.
- Follow the security restrictions in the linked contract.
- First show the exact file tree, then provide every file in full with no TODOs or omissions.
- End with correct activation steps: Create Bot may auto-start the default bot; after importing/saving intended code use Restart if running, otherwise Start/Deploy; after later edits Save then Restart.

Feature requirement:
[WRITE COMPLETE BOT FEATURES HERE]
```
