getsno/relesys-users
Laravel 10 (PHP 8.1+) client for the Relesys User Management API. Access endpoints for users, departments, user groups, custom fields and communication with support for filtering, sorting and pagination, plus create/update users and status changes.
composer require getsno/relesys-users
.env with Relesys credentials:
RELESYS_CLIENT_ID=your_client_id
RELESYS_CLIENT_SECRET=your_client_secret
use Getsno\Relesys\Facades\Relesys;
$user = Relesys::users()->getUser('user-uuid-here');
use Getsno\Relesys\Facades\Relesys;
use Getsno\Relesys\Api\UserManagement\Entities\User;
$user = User::fromArray([
'name' => 'John Doe',
'email' => 'john@example.com',
'primaryDepartmentId' => 'dept-uuid-here',
]);
$createdUser = Relesys::users()->createUser($user);
Getsno\Relesys\Facades\Relesys (entry point for all endpoints).Getsno\Relesys\Api\UserManagement\Entities (e.g., User, UserPatch).Getsno\Relesys\Api\UserManagement\Enums (e.g., UserStatus)./tests directory for real-world examples (run with composer test).$user = User::fromArray([...]);
Relesys::users()->createUser($user);
$queryParams = (new ApiQueryParams())
->addFilter('status', UserStatus::Activated->value)
->sortBy('name')
->limit(10);
$users = Relesys::users()->getUsers($queryParams, page: 1);
$patch = (new UserPatch())
->title('Senior Developer')
->birthDate(Carbon::today()->subYears(30));
Relesys::users()->updateUser('user-uuid', $patch);
Relesys::users()->changeUserStatus('user-uuid', UserStatus::Disabled);
user.created, user.updated (if Relesys supports webhooks).getUsers) with Laravel’s cache:
$users = Cache::remember("relesys_users_{$page}", now()->addHours(1), fn() =>
Relesys::users()->getUsers($queryParams, $page)
);
try-catch with Getsno\Relesys\Exceptions\RelesysHttpClientException:
try {
Relesys::users()->getUser('invalid-uuid');
} catch (RelesysHttpClientException $e) {
report($e->failedRequest->toPsrResponse());
}
$page = 1;
do {
$users = Relesys::users()->getUsers($queryParams, $page);
foreach ($users as $user) { /* ... */ }
$page++;
} while ($users->hasMorePages());
$user = Relesys::users()->getUser('user-uuid');
$customFieldValue = $user->customFields?->get('department_role');
$departments = Relesys::departments()->getDepartments();
$userGroups = Relesys::userGroups()->getUserGroups();
$template = Relesys::communication()->getTemplate('welcome-email');
Relesys::communication()->sendMessage($template, ['user-uuid']);
Empty Arrays in Custom Fields:
customFields. Use null instead:
$user = User::fromArray([
'customFields' => null, // Not []
]);
tests/Feature/UserTest.php for edge-case handling.UUID Validation:
if (!Str::isUuid($userId)) {
throw new \InvalidArgumentException('Invalid UUID format');
}
Pagination Quirks:
hasMorePages() may return true even if the next page is empty. Always check count():
if ($users->count() === 0) break;
Phone Number Formatting:
countryCode is numeric (not string):
$phone = [
'countryCode' => 47, // Not '47'
'number' => '12345678',
];
Enum Case Sensitivity:
camelCase (e.g., UserStatus::Activated), not snake_case:
// Wrong:
UserStatus::activated
// Correct:
UserStatus::Activated
Enable API Logging:
Add to .env:
RELESYS_LOG_REQUESTS=true
Logs appear in storage/logs/laravel.log.
Mock API Calls in Tests: Use the testbench isolation mode (default):
// tests/Feature/UserTest.php
public function test_user_creation()
{
$this->fake(); // Mocks all API calls
// ...
}
Inspect Raw Responses: Access the underlying HTTP client:
$response = Relesys::users()->getUser('user-uuid');
$rawBody = $response->getBody()->getContents();
Custom API Clients:
Override the default HTTP client by binding a custom Getsno\Relesys\Http\Client in AppServiceProvider:
$this->app->bind(Getsno\Relesys\Http\Client::class, function ($app) {
return new CustomHttpClient(
$app['config']['services.relesys.client_id'],
$app['config']['services.relesys.client_secret']
);
});
Entity Extensions:
Extend User or UserPatch for domain-specific logic:
class ExtendedUser extends \Getsno\Relesys\Api\UserManagement\Entities\User
{
public function isActiveDeveloper()
{
return $this->status === UserStatus::Activated
&& $this->customFields?->get('role') === 'developer';
}
}
Query Builder Hooks:
Intercept ApiQueryParams before API calls:
$queryParams = (new ApiQueryParams())
->addFilter('status', UserStatus::Activated->value)
->addCustomFilter('custom', 'value'); // Extend as needed
Rate Limiting: Relesys may throttle requests. Implement exponential backoff:
use Symfony\Component\HttpClient\Retry\RetryStrategy;
$client = HttpClient::create([
'base_uri' => 'https://api.relesysapp.net',
'auth_bearer' => $token,
'retry' => [
'max_retries' => 3,
'delay' => 1000, // ms
'multiplier' => 2,
'max_delay' => 5000,
],
]);
Timezone Handling:
Ensure Carbon instances match Relesys’s expected timezone (default: UTC):
$patch = (new UserPatch())
->birthDate(Carbon::parse('1990-01-01')->setTimezone('UTC'));
Environment Variables:
Use config('services.relesys') for credentials (not .env directly):
config([
'services.relesys' => [
'client_id' => env('RELESYS_CLIENT_ID'),
'client_secret' => env('RELESYS_CLIENT_SECRET'),
],
]);
How can I help you explore Laravel packages today?