Download the PHP package afaztech/reactor without Composer

On this page you can find all versions of the php package afaztech/reactor. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package reactor

Reactor Application Skeleton

A production-ready starter project for building high-performance, asynchronous Telegram bots with the Reactor PHP framework.

PHP Version Powered by Amp Powered by Neili Latest Version


Overview

This repository is the official application skeleton for Reactor, a modern, asynchronous PHP framework purpose-built for creating robust Telegram bots.

Under the hood, this skeleton is powered by three complementary technologies:

Together these three layers give you a bot that is fast, memory-efficient, and easy to reason about – while still feeling like a familiar, Laravel-inspired PHP application.

The skeleton ships with a fully configured project layout, working example handlers, middleware, migrations, localisation files, and CLI commands, so you can go from composer create-project to a running bot in under five minutes.


Table of Contents

  1. Features
  2. Architecture Overview
  3. Requirements
  4. Quick Start
  5. Configuration
  6. Project Structure
  7. The Update Lifecycle
  8. Writing Handlers
  9. Writing Middleware
  10. Keyboard Builder
  11. Working with the Database
  12. Queue System
  13. Localisation
  14. Webhook Mode
  15. CLI Commands
  16. Multi-Process Mode
  17. Production Checklist
  18. Contributing
  19. License

Features


Architecture Overview

Understanding how the three layers fit together is the key to getting the most out of this skeleton.

When an update arrives:

  1. Neili receives and decodes it.
  2. Amp schedules the processing fiber on the event loop.
  3. Reactor resolves a handler, runs the middleware pipeline, invokes the handler, and lets the handler send a reply (again via Neili, again async).
  4. The whole thing happens without blocking, so other updates can be processed concurrently.

This is what makes Reactor well suited for bots that talk to external APIs, do database work, or send many messages in a short time.


Requirements


Quick Start

1. Create the project

2. Configure your environment

Open .env and set your bot token. The bare minimum:

3. Run migrations

This creates the users, jobs, and posts tables.

4. Start the bot

You should see output like:

5. Test it

Open Telegram, find your bot, and send /start. You should receive a welcome message with the main menu keyboard.


Configuration

All configuration lives in config/ and reads from .env via the env() helper. The skeleton ships with four config files.

config/app.php

Key Env variable Default Description
name APP_NAME Reactor Application name
env APP_ENV production Environment identifier
debug DEBUG_MODE true Enable verbose logging
default_language DEFAULT_LANGUAGE en Fallback language

config/bot.php

Key Env variable Default Description
token TOKEN — Telegram bot token (required)
api_url API_URL https://api.telegram.org/bot Telegram API base URL
mode BOT_MODE polling polling or webhook
multi_process MULTI_PROCESS false Enable multi-process handling
webhook_secret WEBHOOK_SECRET — Secret token for webhook verification
php_binary PHP_BINARY /usr/bin/php PHP binary for multi-process
verify_ssl TELEGRAM_VERIFY_SSL true Verify TLS certificates (keep true in production)

config/database.php

Key Env variable Default Description
default DB_CONNECTION sqlite Default connection name
migrations.namespace MIGRATIONS_NAMESPACE App\Migrations Namespace for migration classes
connections.sqlite.database DB_DATABASE database/test.sqlite SQLite file path

MySQL and other drivers are supported through illuminate/database. Just add a connection entry and change DB_CONNECTION.

config/cache.php

Key Env variable Default Description
default CACHE_DRIVER file array, file, redis, or memcached

Project Structure


The Update Lifecycle

Every incoming Telegram update passes through the same pipeline. Understanding it is essential before writing handlers.

Key points:


Writing Handlers

Handlers are plain PHP classes that extend App\Handlers\BaseHandler and use attributes to declare how they should be matched.

The Base Class

BaseHandler (in app/Handlers/BaseHandler.php) provides:

Member Description
$this->client The Neili\Client instance
$this->language The LanguageInterface service
$this->logger The LoggerInterface service
$this->userRepository The application's user repository
$this->update The raw update array
handle(array $params = []) Abstract method where your logic goes
reply(string $message, ?array $keyboard = null, array $extra = [], bool $asReply = true) Send a message replying to the original
send(string $message, ?array $keyboard = null, array $extra = []) Send a standalone message
getUserLanguage(): string Resolve the current user's language
getUserId(): ?int Extract the Telegram user ID

Available Attributes

Attribute Purpose Applies to
#[Text] Match a command or a translated text key Handler class
#[Callback] Match callback query data (exact or regex) Handler class
#[Step] Register a step in a conversation flow Handler class
#[Fallback] Catch-all when no other handler matched Handler class
#[OnUpdate] Restrict to one or more update types Handler class
#[Group] Assign the handler to middleware groups Handler class
#[UseMiddleware] Attach local middleware Handler class

Example 1 — A Command Handler

Notes:

Example 2 — A Text/Button Handler

The name: 'about' refers to a translation key. The router compares the incoming message text against the translated value of that key in the user's language. This means the same handler responds to "ℹ️ About" in English and "ℹ️ درباره" in Persian – no extra code required.

Example 3 — A Callback Handler

Callback handlers can also use a regex pattern:

When a regex matches, the captured groups are passed to handle() as $params:

Example 4 — A Step Handler

Steps are used for multi-step conversations. When the user's step column matches a registered step name, that step's handler runs.

Generate step handlers with:

Example 5 — A Fallback Handler

The fallback runs when no other handler matches. Only one fallback is used — the one with the highest priority.

If you delete this file, Reactor will fall back to its built-in UnknownCommandHandler, which sends the same unknown_command translation. The application-level fallback exists so you can customise the response.

Nested Handlers

Handlers are discovered recursively. Any PHP file under app/Handlers/ (including subdirectories) is scanned. Subdirectory names become part of the class namespace.

For example, app/Handlers/Admin/PingHandler.php:

No additional registration is required — the router picks it up automatically.

Generating a Handler

This creates app/Handlers/EchoHandler.php with a starter template.


Writing Middleware

Middleware runs before the handler and can inspect, modify, or abort the update. Middleware is executed in three phases, in this order:

  1. Global — runs for every update.
  2. Group — runs when the handler's #[Group] matches.
  3. Local — runs when the handler lists the middleware via #[UseMiddleware].

Within each phase, middleware is sorted by descending priority (higher runs first).

The Interface

Return true to stop processing. Return false to continue.

Example — Logging Middleware

Middleware is auto-discovered from app/Middleware/, so no registration is required.

Middleware Modes

Restricting by Update Type

Generating a Middleware

Dependency Injection in Middleware

Middleware is resolved from the container, so you can type-hint any service in the constructor:

The container resolves all dependencies automatically.


Keyboard Builder

App\Keyboard is a small helper that wraps Neili's KeyboardBuilder and translates button labels automatically.

Main Menu

Back Button

Custom Menu

Pass a flat array of translation keys or an array of ['label' => 'key'] entries; buttons are laid out two per row.

Usage

Inline Keyboards

For inline keyboards (callback buttons), build the array manually and pass it to reply():

Handlers decorated with #[Callback(data: 'confirm')] will receive the callback.


Working with the Database

The skeleton uses illuminate/database (Eloquent) via the EloquentManager class, which implements the framework's DatabaseManagerInterface. Migrations are run through the CLI, and models are standard Eloquent models.

Models

Two models ship with the skeleton:

App\Models\User — stores Telegram users, language preference, current step, and temporary data.

App\Models\Job — represents a queued job record.

Repository Pattern

User persistence is abstracted behind UserRepositoryInterface (app/Contracts/Repository/UserRepositoryInterface.php). The concrete implementation is EloquentUserRepository.

The repository is registered in AppServiceProvider and both the framework-level UserProviderInterface and the application-level UserRepositoryInterface alias the same singleton, so consumers get a consistent instance.

Available methods:

Method Description
syncUser(int $userId, ?string $username, ?string $firstName, ?string $lastName) Upsert a user
getLanguage(int $userId): string Get the user's preferred language
getUser(int $userId): ?array Fetch the user as an array
getStep(int $userId): ?string Get the user's current step
setStep(int $userId, ?string $step) Set or clear the step
getTemp(int $userId): ?array Get temporary data
setTemp(int $userId, array $data) Store temporary data
clearTemp(int $userId) Clear temporary data

Migrations

Migrations extend Reactor\Database\Migrations\Migration:

Generate a new migration:

Migration files are named YYYY_MM_DD_HHMMSS_snake_case_name.php. The class name is derived by CamelCasing the portion after the timestamp.

Seeding

Run with:

You can run a specific seeder class:

Using the Database Directly

Resolve the manager from the container:

Or just use Eloquent models directly:


Queue System

Reactor ships with a database-backed queue. Jobs are dispatched through the QueueManager and processed by a worker command.

Writing a Job

Extend Reactor\Queue\BaseJob and implement JobInterface:

BaseJob provides:

Dispatching a Job

Processing Jobs

The worker:

  1. Pops a job inside a transaction.
  2. Resolves the job class from the container (so constructor DI works).
  3. Calls handle($payload['data']).
  4. On success, deletes the job.
  5. On failure, releases the job back onto the queue with a 60-second delay.

For production, run the worker under a supervisor (systemd, supervisord, etc.) so it restarts on crash.


Localisation

Translations are stored as flat JSON files under lang/, keyed by language code.

Adding Strings

lang/en.json:

lang/fa.json:

Using Translations

If a key is missing in the requested language, the default language's value is used. If it's missing there too, the key itself is returned.

Managing the User's Language

The SyncUserMiddleware sets the language automatically from Telegram's language_code the first time a user is seen. To update a user's language:

Adding a New Language

  1. Create lang/<code>.json (e.g. lang/ar.json).
  2. Add the translated keys.
  3. Optionally add the language name to app.language_names in config/app.php.

No code changes are needed — the Language service loads all JSON files at boot.


Webhook Mode

Webhook mode is faster and cheaper than polling because Telegram pushes updates directly to your server instead of your bot repeatedly asking for them. Use it in production.

Enabling Webhook Mode

In .env:

public_html/webhook.php is the entry point:

Registering the Webhook

Point Telegram at your public URL and pass the same secret:

Important Notes

Nginx Example


CLI Commands

The reactor.php script at the project root bootstraps Reactor and exposes a Symfony Console application.

Migration Commands

Command Description
migrate Run all pending migrations
migrate:rollback [--step=N] Roll back the last N batches (default 1)
migrate:reset Roll back all migrations
migrate:refresh Reset and re-run all migrations
migrate:status Show each migration's status (ran / pending)
migrate:make <name> Create a new migration file
migrate:make --create=posts Shortcut for create_posts_table
migrate:make --table=users Shortcut for update_users_table

Database Seeding

Command Description
seed Run the default seeder
seed --class="App\Seeders\CustomSeeder" Run a specific seeder class

Code Generation

Command Description
make:handler <name> Create a new handler class
make:middleware <name> Create a new middleware class
make:step <name> Create a new step handler class

Queue & Scheduling

Command Description
queue:work [--queue=name] [--max=N] Process queued jobs
schedule:run Run due scheduled tasks

Packages

Command Description
package:discover Rebuild the cached package manifest
vendor:publish <provider> Publish a package's assets
vendor:publish --all [--force] Publish every package's assets

Scheduling

Run schedule:run every minute via cron:

Define scheduled tasks in a ScheduleKernel subclass (see config/app.php → schedule_kernel).


Multi-Process Mode

Reactor can process updates using multiple concurrent worker processes. Enable it in .env:

When enabled, TelegramBootstrapper configures Neili's Settings with setMultiProcess(true) and passes the PHP binary path. Neili then forks worker processes to handle updates in parallel.

Choose multi-process mode when:

Leave it disabled when:


Production Checklist

Before deploying your bot, make sure you have:

Example: systemd Unit for the Polling Process

Example: systemd Unit for the Queue Worker


Contributing

Contributions to the skeleton are welcome. Please:

  1. Fork the repository.
  2. Create a feature branch: git checkout -b feature/amazing-feature.
  3. Commit your changes: git commit -m 'Add some amazing feature'.
  4. Push the branch: git push origin feature/amazing-feature.
  5. Open a Pull Request.

Please keep your code consistent with the existing style and ensure existing tests still pass. If you add functionality, add a corresponding test where practical.


License

This project is licensed under the MIT License. See the LICENSE file for details.


All versions of reactor with dependencies

PHP Build Version
Package Version
Requires afaztech/reactor-framework Version ^0.9.0
afaztech/neili Version ^4.0.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package afaztech/reactor contains the following files

Loading the files please wait ...