jeffersongoncalves/laravel-help-desk
Composer 安装命令:
composer require jeffersongoncalves/laravel-help-desk
包简介
A comprehensive help desk and ticket management system for Laravel applications with email integration.
README 文档
README
Laravel Help Desk
A comprehensive help desk and ticket management system for Laravel applications with email integration.
Requirements
- PHP 8.2+
- Laravel 11, 12, or 13
Installation
composer require jeffersongoncalves/laravel-help-desk
The package uses Laravel's auto-discovery, so the service provider and facade are registered automatically.
Publish Configuration
php artisan vendor:publish --tag=help-desk-config
Publish Migrations
php artisan vendor:publish --tag=help-desk-migrations
Run Migrations
php artisan migrate
Publish Translations (optional)
php artisan vendor:publish --tag=help-desk-translations
Configuration
The configuration file is located at config/help-desk.php. Key options:
return [ // Models used by the help desk 'models' => [ 'user' => \App\Models\User::class, // Model that creates tickets 'operator' => \App\Models\User::class, // Model that manages tickets ], // Ticket settings 'ticket' => [ 'reference_prefix' => 'HD', // Ticket reference format: HD-00001 'default_status' => 'open', 'default_priority' => 'medium', 'attachment_disk' => 'local', // Storage disk for attachments 'auto_close_days' => null, // Auto-close resolved tickets (null = disabled) 'allow_reopen' => true, ], // Email integration 'email' => [ 'enabled' => true, 'inbound' => [ 'driver' => null, // 'imap', 'mailgun', 'sendgrid', 'resend', or 'postmark' ], ], // Notification settings 'notifications' => [ 'channels' => ['mail'], 'queue' => 'default', ], ];
Setup
1. Add Traits to Your User Model
For regular users (ticket creators):
use JeffersonGoncalves\HelpDesk\Concerns\HasTickets; class User extends Authenticatable { use HasTickets; }
For operators/agents (ticket managers):
use JeffersonGoncalves\HelpDesk\Concerns\IsOperator; class User extends Authenticatable { use IsOperator; // Includes HasTickets }
2. Create Departments
use JeffersonGoncalves\HelpDesk\Facades\HelpDesk; $department = HelpDesk::createDepartment([ 'name' => 'Technical Support', 'slug' => 'technical-support', 'email' => 'support@example.com', 'is_active' => true, ]);
3. Assign Operators to Departments
HelpDesk::addOperator($department, $user, 'operator'); // 'operator', 'manager', or 'admin'
Usage
Creating Tickets
use JeffersonGoncalves\HelpDesk\Facades\HelpDesk; $ticket = HelpDesk::createTicket([ 'title' => 'Cannot access my account', 'description' => 'I get an error when trying to log in...', 'department_id' => $department->id, 'priority' => 'high', ], $user); // $ticket->reference_number => "HD-00001" // $ticket->uuid => "550e8400-e29b-41d4-a716-446655440000"
Managing Tickets
// Find tickets $ticket = HelpDesk::findTicketByReference('HD-00001'); $ticket = HelpDesk::findTicketByUuid('550e8400-...'); // Assign to operator HelpDesk::assignTicket($ticket, $operator); HelpDesk::unassignTicket($ticket); // Change status use JeffersonGoncalves\HelpDesk\Enums\TicketStatus; HelpDesk::changeStatus($ticket, TicketStatus::InProgress); HelpDesk::closeTicket($ticket); HelpDesk::reopenTicket($ticket); // Update ticket HelpDesk::updateTicket($ticket, [ 'priority' => 'urgent', 'category_id' => $category->id, ]); // Delete ticket (soft delete) HelpDesk::deleteTicket($ticket);
Comments
// Add a public reply $comment = HelpDesk::addComment($ticket, $user, 'Thank you for contacting us.'); // Add an internal note (not visible to end user) $note = HelpDesk::addNote($ticket, $operator, 'Escalating to senior engineer.'); // Add comment with attachments $comment = HelpDesk::addComment($ticket, $user, 'See attached screenshot.', [ 'attachments' => [$uploadedFile], ]);
Watchers
HelpDesk::addWatcher($ticket, $anotherUser); HelpDesk::removeWatcher($ticket, $anotherUser);
Querying Tickets
use JeffersonGoncalves\HelpDesk\Models\Ticket; use JeffersonGoncalves\HelpDesk\Enums\TicketStatus; use JeffersonGoncalves\HelpDesk\Enums\TicketPriority; // Open tickets $open = Ticket::open()->get(); // Closed tickets $closed = Ticket::closed()->get(); // By status $inProgress = Ticket::byStatus(TicketStatus::InProgress)->get(); // By priority $urgent = Ticket::byPriority(TicketPriority::Urgent)->get(); // Overdue tickets $overdue = Ticket::overdue()->get(); // Unassigned tickets $unassigned = Ticket::unassigned()->get(); // User's tickets (via trait) $user->helpDeskTickets; // Operator's assigned tickets (via trait) $operator->helpDeskAssignedTickets;
Canned Responses
use JeffersonGoncalves\HelpDesk\Models\CannedResponse; CannedResponse::create([ 'title' => 'Greeting', 'body' => 'Thank you for contacting our support team...', 'department_id' => $department->id, 'is_active' => true, ]); // Get canned responses for a department $responses = CannedResponse::active() ->forDepartment($department->id) ->ordered() ->get();
Categories
use JeffersonGoncalves\HelpDesk\Models\Category; $category = Category::create([ 'department_id' => $department->id, 'name' => 'Billing', 'slug' => 'billing', 'is_active' => true, ]); // Subcategories $sub = Category::create([ 'department_id' => $department->id, 'parent_id' => $category->id, 'name' => 'Refunds', 'slug' => 'refunds', ]);
Ticket Statuses
| Status | Description |
|---|---|
open |
New ticket, awaiting response |
pending |
Awaiting user response |
in_progress |
Being worked on by an operator |
on_hold |
Temporarily on hold |
resolved |
Issue has been resolved |
closed |
Ticket is closed |
Status transitions are validated automatically. For example, a closed ticket can only transition to open (reopen).
Ticket Priorities
| Priority | Numeric Value |
|---|---|
low |
1 |
medium |
2 |
high |
3 |
urgent |
4 |
Events
The package dispatches events that you can listen to in your application:
| Event | Description |
|---|---|
TicketCreated |
A new ticket was created |
TicketUpdated |
A ticket was updated |
TicketStatusChanged |
Ticket status changed |
TicketPriorityChanged |
Ticket priority changed |
TicketAssigned |
Ticket was assigned to an operator |
TicketClosed |
Ticket was closed |
TicketReopened |
Ticket was reopened |
TicketDeleted |
Ticket was deleted |
CommentAdded |
A comment was added to a ticket |
AttachmentAdded |
An attachment was added |
AttachmentRemoved |
An attachment was removed |
InboundEmailReceived |
An inbound email was received |
InboundEmailProcessed |
An inbound email was processed |
Disabling Default Listeners
If you want to handle events yourself:
// config/help-desk.php 'register_default_listeners' => false,
Email Integration
Outbound Notifications
Notifications are sent automatically when events occur (configurable via notifications.notify_on). Email threading is supported via Message-ID, In-Reply-To, and References headers.
Inbound Email
The package supports receiving emails via 5 drivers:
Security: webhook secrets are mandatory. The HTTP webhook drivers (Mailgun, SendGrid, Resend, and Postmark) verify every request against a configured secret/credential and fail closed: if the corresponding secret is not set, the request is rejected with
403 Forbiddenand a warning is logged. You must configure the secrets below for each driver you enable, otherwise the endpoint will reject all traffic. The webhook routes are also rate limited by default (throttle:60,1, configurable viahelp-desk.webhooks.middleware).
Driver Required configuration Mailgun HELPDESK_MAILGUN_SIGNING_KEYSendGrid HELPDESK_SENDGRID_WEBHOOK_USERNAME+HELPDESK_SENDGRID_WEBHOOK_PASSWORDResend HELPDESK_RESEND_WEBHOOK_SECRET(andHELPDESK_RESEND_API_KEYto fetch bodies)Postmark HELPDESK_POSTMARK_WEBHOOK_USERNAME+HELPDESK_POSTMARK_WEBHOOK_PASSWORD
IMAP
HELPDESK_INBOUND_DRIVER=imap HELPDESK_IMAP_HOST=imap.example.com HELPDESK_IMAP_PORT=993 HELPDESK_IMAP_ENCRYPTION=ssl HELPDESK_IMAP_USERNAME=support@example.com HELPDESK_IMAP_PASSWORD=your-password HELPDESK_IMAP_FOLDER=INBOX
Requires the webklex/php-imap package:
composer require webklex/php-imap
Schedule the polling command in your app/Console/Kernel.php or routes/console.php:
$schedule->command('help-desk:poll-imap')->everyFiveMinutes();
Mailgun
HELPDESK_INBOUND_DRIVER=mailgun HELPDESK_MAILGUN_SIGNING_KEY=your-signing-key
Configure your Mailgun route to forward to:
POST https://your-app.com/help-desk/webhooks/mailgun
SendGrid
HELPDESK_INBOUND_DRIVER=sendgrid HELPDESK_SENDGRID_WEBHOOK_USERNAME=your-username HELPDESK_SENDGRID_WEBHOOK_PASSWORD=your-password
Configure your SendGrid Inbound Parse to forward to:
POST https://your-app.com/help-desk/webhooks/sendgrid
Resend
HELPDESK_INBOUND_DRIVER=resend HELPDESK_RESEND_API_KEY=re_your-api-key HELPDESK_RESEND_WEBHOOK_SECRET=whsec_your-webhook-secret
Configure your Resend receiving domain webhook to forward to:
POST https://your-app.com/help-desk/webhooks/resend
Select the email.received event type in your Resend webhook configuration.
Postmark
HELPDESK_INBOUND_DRIVER=postmark HELPDESK_POSTMARK_WEBHOOK_USERNAME=your-username HELPDESK_POSTMARK_WEBHOOK_PASSWORD=your-password
In your Postmark server, go to the Inbound Message Stream settings and set the webhook URL to:
POST https://your-username:your-password@your-app.com/help-desk/webhooks/postmark
Postmark sends the full email content (body, headers, attachments) directly in the webhook payload. The package also uses Postmark's StrippedTextReply field for cleaner reply parsing.
Email Channels
You can configure multiple email channels, each mapped to a department:
use JeffersonGoncalves\HelpDesk\Models\EmailChannel; EmailChannel::create([ 'department_id' => $department->id, 'name' => 'Support Inbox', 'driver' => 'mailgun', 'email_address' => 'support@example.com', 'settings' => [], // Driver-specific settings (encrypted) 'is_active' => true, ]);
Email Threading
When an inbound email is received, the package resolves it to an existing ticket using:
In-Reply-ToheaderReferencesheader- Subject line reference number (e.g.,
HD-00001)
If no match is found, a new ticket is created.
Artisan Commands
# Poll IMAP mailboxes for new emails php artisan help-desk:poll-imap # Clean old processed inbound emails php artisan help-desk:clean-emails --days=30 # Auto-close stale tickets php artisan help-desk:close-stale --days=14 --status=resolved # Dry run (see what would be closed) php artisan help-desk:close-stale --days=14 --dry-run
Using the Services Directly
For more control, you can inject the service classes directly:
use JeffersonGoncalves\HelpDesk\Services\TicketService; use JeffersonGoncalves\HelpDesk\Services\CommentService; use JeffersonGoncalves\HelpDesk\Services\DepartmentService; use JeffersonGoncalves\HelpDesk\Services\AttachmentService; class MyController { public function __construct( private TicketService $tickets, private CommentService $comments, ) {} public function store(Request $request) { $ticket = $this->tickets->create([ 'title' => $request->title, 'description' => $request->description, 'department_id' => $request->department_id, ], $request->user()); return $ticket; } }
Translation
The package ships with English and Brazilian Portuguese translations. To customize:
php artisan vendor:publish --tag=help-desk-translations
This publishes translation files to lang/vendor/help-desk/. You can modify them or add new locales.
// Using translations in your code __('help-desk::tickets.messages.created') // "Ticket created successfully." __('help-desk::statuses.open') // "Open" __('help-desk::priorities.urgent') // "Urgent"
Testing
composer test
Static Analysis
composer analyse
Code Formatting
composer format
License
The MIT License (MIT). Please see License File for more information.
jeffersongoncalves/laravel-help-desk 适用场景与选型建议
jeffersongoncalves/laravel-help-desk 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 813 次下载、GitHub Stars 达 3, 最近一次更新时间为 2026 年 02 月 04 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「support」 「laravel」 「ticket」 「help-desk」 「customer-support」 「email-integration」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 jeffersongoncalves/laravel-help-desk 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 jeffersongoncalves/laravel-help-desk 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 jeffersongoncalves/laravel-help-desk 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
统计信息
- 总下载量: 813
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 4
- 点击次数: 28
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-02-04
