Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nutgram Laravel Package

sergix44/nutgram

Nutgram is a modern PHP Telegram bot framework with a Laravel-style API and first-class Laravel integration. Build bots with handlers, middleware, conversations, webhooks, and testable code without boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Nutgram is a Telegram Bot API framework with first-class Laravel integration. A typical install looks like:

composer require nutgram/nutgram
php artisan nutgram:install        # publishes config/nutgram.php and scaffolding

Then set TELEGRAM_TOKEN in .env. The first place to look is config/nutgram.php — it controls the token, the run mode (polling vs webhook), webhook URL/secret, and the handler/middleware loading paths. Second place is routes/telegram.php, where handlers are registered:

use App\Telegram\Handlers\StartHandler;

$bot->onCommand('start', StartHandler::class);
$bot->onText('hello', fn (Nutgram $bot) => $bot->sendMessage('Hi!'));

A first use case: create a handler with php artisan nutgram:make:handler StartHandler, register it on /start, then run php artisan nutgram:run locally (long polling, no public URL needed). Once deployed behind HTTPS, switch to webhook mode with php artisan nutgram:hook:set.

Note on 4.50.3: this is a patch release fixing Bot API type mismatches around media, ephemeral edits, entities and rich text. There are no migration steps, but if you rely on the generated IDE/type helpers (see below), regenerate them after upgrading.

Implementation Patterns

  • Handler classes over closures. Put handlers in app/Telegram/Handlers, keep routes/telegram.php as a thin routing table, and inject Nutgram into __invoke(Nutgram $bot, ...). This keeps handlers testable and queueable.
  • Commands and conversations. Register commands (php artisan nutgram:make:command, nutgram:make:conversation) and use $bot->onCommand('start', ...). Conversations are the idiomatic way to model multi-step forms instead of stashing state in the cache yourself.
  • Middleware for cross-cutting concerns. Attach $bot->middleware(EnsureUserIsKnown::class) for user lookup/registration, rate limiting, or logging. Middleware runs per-update, which is the right granularity for idempotency keys.
  • Facade vs. injection. Nutgram\Laravel\Facades\Nutgram::sendMessage(...) is convenient for sending from anywhere (controllers, jobs, console commands); prefer constructor injection of the client in services you unit test.
  • Push slow work to queues. Do the minimum in the handler (validate, acknowledge, dispatch a job). Sending media or hitting external APIs inside a handler blocks the update loop under polling and risks webhook timeouts in production.
  • Testing with fakes. Use Nutgram::fake() in feature tests, register the same routes file, ->hearText('/start')->reply() and assert outgoing calls. This is the fastest way to keep handler coverage without a live bot.
  • Deployment modes. Local/dev: nutgram:run under a process supervisor. Production: nutgram:hook:set (and nutgram:hook:remove for rollbacks), keeping mode consistent in config per environment.
  • Type helpers for IDE/static analysis. Generate the typed helpers with php artisan nutgram:ide:generate so $bot->sendMessage() arguments and update payloads autocomplete. Treat the generated directory as build output: regenerate after every composer update.
  • Integration points. Pair handlers with Laravel events/listeners for domain side effects, and keep a TelegramUser model keyed by from.id for anything stateful.

Gotchas and Tips

  • Regenerate types after this release. 4.50.3 changes type definitions for media, ephemeral edits, entities and rich text. Run composer update nutgram/nutgram, then php artisan nutgram:ide:generate (and clear bootstrap/cache / opcache). If you had written manual @param docblocks or subclasses mirroring the old shapes, re-check them — the types moved, not the wire format.
  • Handler/middleware caching. If you enable handler caching, php artisan nutgram:cache:clear after adding or renaming handlers — otherwise new routes silently don't fire. This is the most common "my handler isn't called" cause after a deploy.
  • Entity offsets are UTF-16 code units. When slicing message.text using MessageEntity offsets/lengths, don't use plain substr on multibyte strings. The rich-text/entity fixes in this release are a good reminder to centralize that logic in one helper.
  • Media and media groups. sendMediaGroup returns an array of messages, not one; InputMedia captions are limited and cannot be set on every item. Validate file sizes and MIME types locally before uploading, or you'll burn rate limit on guaranteed failures.
  • Ephemeral edits. Ephemeral message APIs are Bot API–version sensitive: if you set a custom api_url or a proxy, it may not implement the newer endpoints. Mismatched types here typically surface as "unknown method" or malformed payload errors rather than PHP exceptions.
  • Rate limits. Catch/handle 429s respecting retry_after; for bulk sends, stagger via queued jobs with a small delay rather than looping synchronously.
  • File IDs are reusable, uploads are not cheap. Cache file_ids per (chat, purpose) instead of re-uploading the same asset.
  • Webhook vs. polling confusion. Running nutgram:run against a bot that still has a webhook set yields no updates. Clear it with nutgram:hook:remove before polling locally.
  • Secret token. If you configure webhook.secret_token, verify the X-Telegram-Bot-Api-Secret-Token header; also exclude the webhook route from CSRF and session middleware, or updates will 419.
  • Debugging. Log raw updates behind a debug middleware gated on APP_DEBUG; most "type mismatch"/"wrong payload" issues are visible immediately in the raw update JSON.
  • Extension points. Custom api_url for local Bot API servers, additional middleware for cross-cutting auth, and Laravel events fired from handlers for domain decoupling are the safe seams — avoid patching vendor classes for type issues, since patch releases like this one will move them.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons