dantepiazza / laravel-chatwoot
Laravel integration for Chatwoot – webhook routing, bot workflow engine and Chatwoot API helpers.
Requires
- php: ^8.1
- dantepiazza/laravel-api-response: ^1.0.0
- guzzlehttp/guzzle: ^7.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
README
Laravel integration for Chatwoot — webhook routing, a step-based bot workflow engine and Chatwoot API helpers.
Requirements
- PHP 8.1+
- Laravel 10 / 11 / 12
dantepiazza/laravel-api-response
Installation
composer require dantepiazza/laravel-chatwoot
Publish the config file:
php artisan vendor:publish --tag=chatwoot-config
Publish the example workflow:
php artisan vendor:publish --tag=chatwoot-workflow
Environment variables
Add these to your .env:
CHATWOOT_URL=https://app.chatwoot.com CHATWOOT_BOT_TOKEN= CHATWOOT_AGENT_TOKEN= CHATWOOT_ACCOUNT_ID= CHATWOOT_WEBHOOK_SECRET=
How it works
1. Webhook route
The package registers the following route automatically:
POST /v1/chatwoot/{flow}?token={CHATWOOT_WEBHOOK_SECRET}
The {flow} segment is resolved to a class:
bot → App\Services\Chatwoot\BotWorkflow
orders → App\Services\Chatwoot\OrdersWorkflow
You can have multiple workflows for different inboxes.
2. Creating a workflow
A workflow is a class that extends ChatwootProvider and lives in app/Services/Chatwoot/.
The published stub (BotWorkflow.php) is a ready-to-run example. Here is the minimal structure:
namespace App\Services\Chatwoot; use Dantepiazza\LaravelChatwoot\Services\ChatwootProvider; class BotWorkflow extends ChatwootProvider { public function __construct(array $payload) { $this->default_steps = ['welcome.start', 'finish']; $this->default_attributes = ['step' => 'welcome.start']; parent::__construct($payload); } public function run(): void { $method = 'step_' . str_replace('.', '_', $this->step); if (method_exists($this, $method)) { $this->$method(); } } protected function step_welcome_start(): void { $this->send('Hello! How can I help you?')->stop(); } protected function step_finish(): void { $this->send('Thanks! Goodbye 👋')->nextStep('welcome.start')->stop(); } }
3. Steps
Every step is a method named step_{name} where dots in the step name become underscores:
| Step name | Method |
|---|---|
welcome.start |
step_welcome_start() |
docs.start |
step_docs_start() |
affiliate.menu |
step_affiliate_menu() |
4. Navigating between steps
$this->nextStep('some.step'); // saves the step to Chatwoot custom attributes $this->stop(); // halts execution (always call at the end of a step)
5. Sending messages
// Plain text $this->send('Hello!'); // Interactive button list $this->send('Choose an option:', [ 'Option A' => 'step.a', 'Option B' => 'step.b', ]);
6. Actions
A step can have a sub-state called an action, encoded as step.name[action].
$this->step; // "welcome.menu" $this->action; // "confirm"
This is useful to handle confirmation flows or multi-stage interactions within the same logical step.
7. Built-in helpers (via HasCommonFlows trait)
attach(string $message, string $cancelStep)
Manages a multi-message file-upload flow. Returns true once the user confirms they have finished sending files.
if ($this->attach('Please send your documents.', 'previous.step')) { // Files received $this->open(tags: ['support']); }
open(array $tags, int $team, string $message, string $nextStep)
Adds tags, assigns a team, opens the conversation and notifies the user.
$this->open(tags: ['billing'], team: 2, message: 'An agent will contact you shortly.');
goodbye(string $message, array $buttons)
Sends a closing message and asks if the user needs anything else.
$this->goodbye('Here is your info: ...', $this->buildGoodbyeButtons('welcome.menu'));
8. Other API methods
| Method | Description |
|---|---|
$this->status('open') |
Toggle conversation status |
$this->tag(['label']) |
Add labels to the conversation |
$this->team(1) |
Assign to a team |
$this->attribute('key', val) |
Set a custom attribute |
$this->wait(2) |
Sleep N seconds (useful between messages) |
Development mode
Set $this->development = true in your workflow constructor to allow the bot to respond even when a conversation is open. Useful when testing in Chatwoot directly. Remove before deploying to production.
Contributing
- Fork the repository from the
masterbranch. - Create a branch for your feature or fix.
- Follow PSR-12 coding standards.
- Submit a pull request describing your changes.
License
MIT