mpclarkson/freshdesk-php-sdk
PHP 5.5+ SDK for Freshdesk API v2. Simple, resource-based client: $api->tickets->all/create/update/view/delete, plus contacts, agents, companies, groups and more. Returns plain arrays. Composer install and easy Symfony/Laravel integration.
Installation:
composer require mpclarkson/freshdesk-php-sdk
For Laravel/Lumen, use the Laravel Service Provider for dependency injection.
First API Call:
use Freshdesk\Api;
$api = new Api(config('freshdesk.api_key'), config('freshdesk.domain'));
$tickets = $api->tickets->all(['page' => 1, 'per_page' => 10]);
Laravel Configuration (if using the service provider):
Add to config/services.php:
'freshdesk' => [
'api_key' => env('FRESHDESK_API_KEY'),
'domain' => env('FRESHDESK_DOMAIN'),
],
Then bind in AppServiceProvider:
$this->app->singleton('freshdesk', function ($app) {
return new Api(config('freshdesk.api_key'), config('freshdesk.domain'));
});
// Fetch tickets for a specific company
$tickets = $api->tickets->all(['company_id' => 123]);
// Create a new ticket
$newTicket = $api->tickets->create([
'subject' => 'API Test Ticket',
'description' => 'Created via PHP SDK',
'priority' => 2,
'requester_id' => 456,
]);
$tickets = $api->tickets->all(['status' => 2, 'page' => 1, 'per_page' => 20]);
$ticketData = ['subject' => 'Update', 'description' => 'Updated via API'];
$updated = $api->tickets->update(123, $ticketData);
$api->conversations->note(123, ['body' => 'Follow-up note']);
$contacts = $api->contacts->all(['email' => 'user@example.com']);
$company = $api->companies->create([
'name' => 'Acme Corp',
'domain_names' => ['acme.com'],
]);
$currentAgent = $api->agents->current();
$api->contacts->makeAgent(789, ['role_id' => 1]);
$api->topics->monitor(456, $agentId);
$monitored = $api->topics->all(['monitored_by' => $agentId]);
Map Freshdesk resources to Eloquent models for seamless ORM usage:
// Example: Ticket Model
class Ticket extends Model
{
protected $fillable = ['subject', 'description', 'priority'];
public static function fetchFromFreshdesk($api, $id)
{
$data = $api->tickets->view($id);
return new static($data);
}
}
Use Laravel's Http facade to standardize responses:
use Illuminate\Support\Facades\Http;
try {
$response = $api->tickets->all();
return Http::response($response, 200);
} catch (\Freshdesk\Exceptions\ApiException $e) {
return Http::response(['error' => $e->getMessage()], 500);
}
Process large datasets efficiently with pagination:
$page = 1;
$perPage = 100;
$allTickets = [];
do {
$tickets = $api->tickets->all(['page' => $page, 'per_page' => $perPage]);
$allTickets = array_merge($allTickets, $tickets);
$page++;
} while (!empty($tickets));
Trigger Laravel events on Freshdesk API responses:
event(new TicketCreated($newTicket));
API Credits:
include in a view() call consumes additional credits. Example:
// Avoid if not needed
$ticket = $api->tickets->view(123, ['include' => 'requester,company']);
Rate Limiting:
use Illuminate\Support\Facades\Queue;
Queue::later(now()->addSeconds(5), function () use ($api) {
$api->tickets->all();
});
Unsupported Content Types:
UnsupportedContentTypeException if Freshdesk returns XML.Missing Resources:
Solutions and Surveys are not implemented in this SDK.$client = $api->getClient();
$response = $client->get("/api/v2/solutions");
ID Types:
delete()), while others use objects.$api->companies->delete((int) $companyId);
Enable Guzzle Middleware: Add a logging middleware to inspect requests/responses:
$api = new Api($key, $domain);
$api->getClient()->getEmitter()->attach(
new \GuzzleHttp\Middleware::tap(function ($request, $options) {
\Log::debug('Request:', [$request->getUri(), $options]);
})
);
Handle Exceptions: Catch specific exceptions for granular error handling:
try {
$api->tickets->view(999);
} catch (\Freshdesk\Exceptions\NotFoundException $e) {
\Log::warning("Ticket not found: {$e->getMessage()}");
}
Validate Input Data:
Use Laravel's Validator to ensure data matches Freshdesk's API schema:
$validator = Validator::make($data, [
'subject' => 'required|string|max:255',
'description' => 'required|string',
]);
Custom Resources:
Extend AbstractResource to add unsupported endpoints:
namespace App\Freshdesk;
use Freshdesk\Resources\AbstractResource;
class Solution extends AbstractResource
{
protected $resource = 'solutions';
public function all(array $query = null)
{
return $this->get($query);
}
}
Mocking for Testing:
Use Laravel's MockHttp to test API interactions:
$this->mock(Http::class, function ($mock) {
$mock->shouldReceive('get')
->withArgs(['/api/v2/tickets/123'], ['headers' => ['Authorization' => 'Bearer ...']])
->andReturn(['id' => 123, 'subject' => 'Test']);
});
Caching Responses: Cache frequent API calls using Laravel's cache:
$cacheKey = "freshdesk_tickets_{$companyId}";
$tickets = Cache::remember($cacheKey, now()->addHours(1), function () use ($api, $companyId) {
return $api->tickets->all(['company_id' => $companyId]);
});
Webhook Verification: Verify Freshdesk webhook signatures:
use Illuminate\Http\Request;
public function handleWebhook(Request $request)
{
$signature = $request->header('X-Freshdesk-Signature');
$payload = $request->getContent();
if (!hash_equals($signature, hash_hmac('sha256', $payload, config('freshdesk.webhook_secret')))) {
abort(401
How can I help you explore Laravel packages today?