Troubleshooting Telegraph onboarding
Use this page when the first bot tutorial stops before the bot can answer /start or send the first message. The checks below use placeholder values only; do not publish real bot tokens, webhook secret tokens, Telegram headers or full user payloads in issues, logs or screenshots.
Bot token is rejected
Symptoms
telegraph:new-botdoes not create a bot.- Telegram API returns an unauthorized or invalid token response.
- A bot record was created with a copied token, but API calls fail.
Likely cause
The token copied from BotFather is incomplete, has extra spaces or quotes, or was revoked.
Check or fix
Copy the token from @BotFather again and paste it without surrounding quotes. If the token was revoked, create a new token in BotFather and update the stored TelegraphBot record or rerun:
php artisan telegraph:new-bot
For programmatic setup, keep the token in .env and expose it through application config:
TELEGRAPH_BOT_TOKEN=123456:ABC-replace-with-your-bot-token
'telegram' => [ 'bot_token' => env('TELEGRAPH_BOT_TOKEN'), ],
Webhook is not receiving updates
Symptoms
/startor/chatidproduces no response.telegraph:debug-webhookshows an empty, old or unexpected URL.- Telegram reports delivery errors or keeps increasing
pending_update_count. - Your tunnel inspector does not show incoming
POSTrequests.
Likely cause
Telegram cannot reach the current public HTTPS URL, or the webhook was not registered again after the local tunnel URL changed.
Check or fix
Start the Laravel app and tunnel to the same port:
php artisan serve
ngrok http 8000
Set the public HTTPS URL in .env:
APP_URL=https://example.ngrok-free.app TELEGRAM_WEBHOOK_DOMAIN=https://example.ngrok-free.app
Clear cached config, register the webhook again, then inspect Telegram's current webhook state:
php artisan config:clear
php artisan telegraph:set-webhook {bot_id}
php artisan telegraph:debug-webhook {bot_id}
For local-only diagnostics you can temporarily enable webhook payload logging:
TELEGRAPH_WEBHOOK_DEBUG=true
Disable it outside local troubleshooting because webhook payloads can contain user data.
If stale updates are not useful during setup, drop them on the next registration:
php artisan telegraph:set-webhook {bot_id} --drop-pending-updates
Webhook secret or middleware rejects requests
Symptoms
- The tunnel inspector shows incoming
POSTrequests, but Laravel returns401or403. - The bot works without custom middleware but fails after adding secret validation.
- Telegram keeps retrying the same update.
Likely cause
The secret passed to Telegram with --secret does not match the value expected by your middleware, or a reverse proxy / CSRF rule blocks the webhook route.
Check or fix
Store the expected secret and register the webhook with the same value:
TELEGRAPH_WEBHOOK_SECRET=your-secret-token
export TELEGRAPH_WEBHOOK_SECRET="your-secret-token"
php artisan telegraph:set-webhook {bot_id} --secret="${TELEGRAPH_WEBHOOK_SECRET}"
Laravel .env does not export variables into the shell automatically. If you use ${TELEGRAPH_WEBHOOK_SECRET} in a CLI command, run export in the current shell session first or pass a placeholder value explicitly.
If you validate X-Telegram-Bot-Api-Secret-Token, keep that logic in middleware configured through telegraph.webhook.middleware or in your own request handling layer. Do not log the header value in shared environments.
Chat registration fails or /chatid does not answer
Symptoms
/chatiddoes not return the chat ID./startdoes not reach your handler in a new chat.telegraph:new-chatcreates no usable chat because thechat_idis unknown.
Likely cause
By default, Telegraph rejects messages and commands from chats that are not already stored as TelegraphChat models. Group privacy mode or missing group permissions can also hide messages from the bot.
Check or fix
If you already know the numeric Telegram chat_id, register it directly:
php artisan telegraph:new-chat {bot_id}
If you do not know the chat_id, temporarily allow unknown messages while onboarding:
'security' => [ 'allow_messages_from_unknown_chats' => true, ],
Then clear config cache, send /chatid, register the returned ID, and restore the safer default:
php artisan config:clear
php artisan telegraph:new-chat {bot_id}
'security' => [ 'allow_messages_from_unknown_chats' => false, ],
For groups, check BotFather privacy mode and join permissions before debugging the application handler.
Config cache is stale
Symptoms
.envcontains the new tunnel URL or secret, butdebug-webhookstill shows old values.- Changing
TELEGRAM_WEBHOOK_DOMAIN,TELEGRAPH_WEBHOOK_URLorTELEGRAPH_WEBHOOK_SECRETappears to have no effect. - The app works locally in one process but not through the webhook route.
Likely cause
Laravel is using cached config from before the .env change.
Check or fix
Clear config cache before registering the webhook again:
php artisan config:clear
php artisan telegraph:set-webhook {bot_id} --secret=your-secret-token
php artisan telegraph:debug-webhook {bot_id}
If the webhook path itself changed through TELEGRAPH_WEBHOOK_URL, also verify the route exists:
php artisan route:list
Local tunnel or dev server is down
Symptoms
- The tunnel URL opens an error page.
- Telegram reports connection refused, timeout or bad gateway.
- The tunnel inspector shows requests to the wrong local port.
Likely cause
The Laravel dev server is not running, the tunnel points to the wrong port, the URL is not HTTPS, or the free tunnel URL changed after restart.
Check or fix
Start the app and tunnel again, then copy the fresh HTTPS URL:
php artisan serve
ngrok http 8000
Update APP_URL or TELEGRAM_WEBHOOK_DOMAIN, clear config cache and register the webhook again:
php artisan config:clear
php artisan telegraph:set-webhook {bot_id}
php artisan telegraph:debug-webhook {bot_id}
For route-level failures, compare the registered URL with the default path:
/telegraph/{token}/webhook
If you changed TELEGRAPH_WEBHOOK_URL, the same path must be reachable from the public tunnel URL and registered again in Telegram.