uvdesk/api-bundle
REST API bundle for the UVdesk helpdesk, exposing token-authenticated JSON endpoints for tickets, threads, agents, customers, and related resources so external apps and integrations can read and manage helpdesk data programmatically.
The package is a helpdesk API layer (tickets, threads, agents, customers, groups, teams) that your Laravel app talks to over HTTP. Treat it as an external service: one configured client, one thin service class per resource.
Minimal setup:
composer require uvdesk/api-bundle (or point your composer.json at the v1.1.4 tag if you vendor it)..env: base URL, API token/keys, and timeout.HelpdeskClient in a service provider that wraps Laravel's Http client with baseUrl(), withToken(), acceptJson(), and retry().CHANGELOG-1.1.md, since v1.1.4 includes a refactor pass.First use case: create a ticket from a contact form and store the returned ticket payload.
$response = $this->helpdesk->post('/api/tickets', [
'subject' => $request->subject,
'message' => $request->message,
'customer' => ['email' => $request->email, 'name' => $request->name],
'customFields'=> ['priority_level' => 'high'], // new in 1.1.4
]);
$ticket = $response->json('data'); // now populated in 1.1.4
TicketMirror::updateOrCreate(['remote_id' => $ticket['id']], $ticket);
One client, many resources. Build TicketService, AgentService, CustomerService, GroupService, TeamService on top of a shared client. Keep endpoints and payload keys in config so instance-specific custom fields do not leak into controllers.
Create-and-use-the-response. v1.1.4 returns the created/updated entity payload for tickets, agents, customers, groups, and teams. Stop doing POST then GET:
$ticket = $tickets->create($payload); // returns ticket data
$thread = $tickets->reply($ticketId, $body); // returns thread details
Persist the returned object directly into a local mirror table. This halves your request count and removes the race where a follow-up GET fires before the write is visible.
Mirror tables + upsert. Keep local Eloquent models (ticket_mirrors, agent_mirrors, …) keyed by the remote ID. Use updateOrCreate on every create/update response so the mirror stays warm for dashboards and search without hammering the API.
Custom fields: schema-first. Custom fields are per-instance. Fetch and cache the field definitions (config or a scheduled job), then validate user input against that schema before submitting. Send them as a keyed array; never hardcode field names in Blade or controllers.
$schema = Cache::remember('helpdesk.custom_fields', 3600, fn () => $client->get('/api/custom-fields')->json('data'));
$validated = validator($input, $this->rulesFromSchema($schema))->validate();
Agent creation event. 1.1.4 adds an agent-creation event and returns the agent ID. Register a listener that fires onboarding (welcome mail, local role assignment, team membership). Persist the local mirror record before dispatching dependent jobs so downstream workers can resolve the ID.
Queue everything that writes. Wrap create/reply/sync calls in jobs with $tries = 3, exponential backoff, and RateLimited middleware. Reads can be synchronous; writes should not block a web request.
Testing. Use Http::fake() with fixtures that match the 1.1.4 envelope (data populated). Add one test per resource asserting your service returns a hydrated DTO rather than an ID — that is where the behaviour actually changed.
Webhook/listener idempotency. If you consume agent-created or ticket-created events, dedupe on the remote ID with a unique index. Events can be delivered more than once.
$response->json('id') will now miss — the payload lives under data. Audit every ->json('id') call before upgrading; this is the most likely upgrade break in 1.1.4 despite being labelled an improvement.CHANGELOG-1.1.md and diff the classes you touch before bumping the constraint.data_get($payload, 'customer.email') rather than array access. Refactors in this release may omit nested relations you previously assumed were always present.tap on the client to log method, path, status, and a redacted body. The bundle's own logs plus your request log will pinpoint whether a mismatch is payload or routing."~1.1.4" and upgrade deliberately rather than floating on ^1.0.How can I help you explore Laravel packages today?