amaizing-company / laravel-zava-video-call-client
Zava videocall api client package for laravel.
Fund package maintenance!
Amaizing Company
Requires
- php: ^8.3
- illuminate/contracts: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9||^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
This package is auto-updated.
Last update: 2025-08-09 01:12:40 UTC
README
A Laravel package that provides a convenient and robust client for integrating with the Zava Videocall API. This package allows you to easily manage users, appointments, and attendees for video consultations in your Laravel application.
Features
- User management (create, update, delete, list)
- Appointment management (create, update, delete, get, list)
- Attendee management for appointments
- Meeting URL generation for both users and attendees
- Event system for appointment lifecycle
- Optimized token caching with automatic refresh
- Configurable retry mechanism for failed API requests
- Rate limiting support
Installation
You can install the package via composer:
composer require amaizing-company/zava-video-call-client
Configuration
You can publish the config file with:
php artisan vendor:publish --tag="zava-video-call-client-config"
This is the contents of the published config file:
return [ 'client_id' => env('ZAVA_CLIENT_ID'), 'client_secret' => env('ZAVA_CLIENT_SECRET'), 'owner_id' => env('ZAVA_OWNER_ID'), 'organisation_id' => env('ZAVA_ORGANISATION_ID'), 'urls' => [ 'auth' => env('ZAVA_AUTH_URL', 'https://identity.sandbox.sprechstunde.online'), 'base' => env('ZAVA_BASE_URL', 'https://app.sandbox.sprechstunde.online/api/v2'), 'user_video_service' => env('ZAVA_USER_VIDEO_SERVICE_URL', 'https://app.sprechstunde.online/video-service'), 'attendee_video_service' => env('ZAVA_ATTENDEE_VIDEO_SERVICE_URL', 'https://app.sprechstunde.online/attendee/session'), ], // Token management configuration 'token' => [ 'refresh_threshold' => env('ZAVA_TOKEN_REFRESH_THRESHOLD', 0.8), ], // Retry configuration for failed API requests 'retry' => [ 'max_attempts' => env('ZAVA_RETRY_MAX_ATTEMPTS', 3), 'base_delay' => env('ZAVA_RETRY_BASE_DELAY', 100), // in milliseconds 'max_delay' => env('ZAVA_RETRY_MAX_DELAY', 1000), // in milliseconds 'retryable_status_codes' => [408, 429, 500, 502, 503, 504], 'retryable_exceptions' => [ \Illuminate\Http\Client\ConnectionException::class, \AmaizingCompany\ZavaVideoCallClient\Exceptions\NetworkException::class, \AmaizingCompany\ZavaVideoCallClient\Exceptions\ServerException::class, \AmaizingCompany\ZavaVideoCallClient\Exceptions\RateLimitException::class, ], ], // Rate limiting configuration 'rate_limiting' => [ 'enabled' => env('ZAVA_RATE_LIMITING_ENABLED', true), 'max_requests' => env('ZAVA_RATE_LIMITING_MAX_REQUESTS', 60), 'window' => env('ZAVA_RATE_LIMITING_WINDOW', 60), // in seconds ], ];
Environment Variables
Add the following environment variables to your .env
file:
ZAVA_CLIENT_ID=your-client-id
ZAVA_CLIENT_SECRET=your-client-secret
ZAVA_OWNER_ID=your-owner-id
ZAVA_ORGANISATION_ID=your-organisation-id
# Optional: Override default URLs if needed
ZAVA_AUTH_URL=https://identity.sandbox.sprechstunde.online
ZAVA_BASE_URL=https://app.sandbox.sprechstunde.online/api/v2
ZAVA_USER_VIDEO_SERVICE_URL=https://app.sprechstunde.online/video-service
ZAVA_ATTENDEE_VIDEO_SERVICE_URL=https://app.sprechstunde.online/attendee/session
# Optional: Configure token refresh behavior
ZAVA_TOKEN_REFRESH_THRESHOLD=0.8
# Optional: Configure retry behavior
ZAVA_RETRY_MAX_ATTEMPTS=3
ZAVA_RETRY_BASE_DELAY=100
ZAVA_RETRY_MAX_DELAY=1000
# Optional: Configure rate limiting
ZAVA_RATE_LIMITING_ENABLED=true
ZAVA_RATE_LIMITING_MAX_REQUESTS=60
ZAVA_RATE_LIMITING_WINDOW=60
Usage
Basic Usage
use AmaizingCompany\ZavaVideoCallClient\ZavaVideoCallClient; // The client is automatically registered in the service container $client = app(ZavaVideoCallClient::class); // Or you can use the facade use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; $appointments = ZavaVideoCallClient::listAppointments();
User Management
Creating a User
use AmaizingCompany\ZavaVideoCallClient\DataObjects\User; use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Create a user object $user = new User( email: 'doctor@example.com', title: 'Dr.', firstName: 'John', lastName: 'Doe', occupation: 'General Practitioner' ); // Optionally add a profile image $profileImageContents = file_get_contents('path/to/profile-image.jpg'); $user->profileImage($profileImageContents); // Create the user in Zava $response = ZavaVideoCallClient::createUser($user); // Get the user ID from the response $userId = $response->getUserId();
Updating a User
use AmaizingCompany\ZavaVideoCallClient\DataObjects\User; use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Create a user object with updated information $user = new User( email: 'doctor@example.com', title: 'Dr.', firstName: 'John', lastName: 'Smith', // Updated last name occupation: 'Cardiologist' // Updated occupation ); // Update the user in Zava $response = ZavaVideoCallClient::updateUser('user-id', $user);
Deleting a User
use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Delete the user from Zava $response = ZavaVideoCallClient::deleteUser('user-id');
Listing All Users
use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Get all users $response = ZavaVideoCallClient::listUsers(); $users = $response->getUsers(); foreach ($users as $user) { echo $user->getId() . ': ' . $user->getFirstName() . ' ' . $user->getLastName(); }
Appointment Management
Creating an Appointment
use AmaizingCompany\ZavaVideoCallClient\DataObjects\Appointment; use AmaizingCompany\ZavaVideoCallClient\DataObjects\Attendee; use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; use Illuminate\Support\Carbon; // Create an appointment $appointment = new Appointment( startDate: Carbon::now()->addHour(), endDate: Carbon::now()->addHour()->addMinutes(30), subject: 'Medical Consultation' ); // Add a description $appointment->description('Regular check-up appointment'); // Add metadata if needed $appointment->metadata([ 'reference_id' => '12345', 'department' => 'Cardiology', ]); // Add an attendee (patient) $attendee = new Attendee(name: 'Jane Smith'); $attendee->email('patient@example.com'); $attendee->mobile('+1234567890'); $attendee->metadata(['patient_id' => '98765']); $appointment->addAttendee($attendee); // Create the appointment for a specific user $response = ZavaVideoCallClient::createAppointment('user-id', $appointment); // Get the appointment ID from the response $appointmentId = $response->getAppointment()->getId();
Getting an Appointment
use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Get a specific appointment $response = ZavaVideoCallClient::getAppointment('user-id', 'appointment-id'); $appointment = $response->getAppointment(); echo "Appointment: " . $appointment->getSubject(); echo "Start: " . $appointment->getStartDate()->format('Y-m-d H:i:s'); echo "End: " . $appointment->getEndDate()->format('Y-m-d H:i:s'); // Get attendees $attendees = $appointment->getAttendees(); foreach ($attendees as $attendee) { echo "Attendee: " . $attendee->getName() . " (" . $attendee->getEmail() . ")"; }
Updating an Appointment
use AmaizingCompany\ZavaVideoCallClient\DataObjects\Appointment; use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; use Illuminate\Support\Carbon; // Create an appointment object with updated information $appointment = new Appointment( startDate: Carbon::now()->addHours(2), // Updated start time endDate: Carbon::now()->addHours(2)->addMinutes(45), // Updated end time subject: 'Follow-up Consultation' // Updated subject ); // Update the appointment $response = ZavaVideoCallClient::updateAppointment('user-id', 'appointment-id', $appointment);
Deleting an Appointment
use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Delete an appointment $response = ZavaVideoCallClient::deleteAppointment('user-id', 'appointment-id');
Listing All Appointments
use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Get all appointments $response = ZavaVideoCallClient::listAppointments(); $appointments = $response->getAppointments(); foreach ($appointments as $appointment) { echo $appointment->getId() . ': ' . $appointment->getSubject(); echo " (" . $appointment->getStartDate()->format('Y-m-d H:i:s') . ")"; }
Meeting URLs
Getting User Meeting URL
use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Get the meeting URL for the healthcare provider $userMeetingUrl = ZavaVideoCallClient::getUserMeetingUrl('meeting-token'); // Redirect the user to the meeting return redirect()->away($userMeetingUrl);
Getting Attendee Meeting URL
use AmaizingCompany\ZavaVideoCallClient\Facades\ZavaVideoCallClient; // Get the meeting URL for the patient $attendeeMeetingUrl = ZavaVideoCallClient::getAttendeeMeetingUrl('meeting-token'); // Send the URL to the patient Mail::to('patient@example.com')->send(new MeetingInvitation($attendeeMeetingUrl));
Token Management
This package implements an optimized token caching strategy that automatically refreshes access tokens before they expire. This helps prevent API request failures due to expired tokens and ensures a smoother user experience.
How It Works
- When an access token is first obtained, it is stored in the cache along with its expiration time.
- The package uses a configurable refresh threshold to determine when to proactively refresh the token.
- When a request is made and the token is close to expiration (based on the refresh threshold), the package automatically refreshes the token before proceeding with the request.
- Thread safety is ensured through the use of a lock mechanism, preventing multiple processes from refreshing the token simultaneously.
Configuration
You can configure the token refresh behavior using the token.refresh_threshold
option in the config file:
'token' => [ // Percentage of token lifetime after which to refresh (0.8 = 80%) // For example, if a token is valid for 3600 seconds (1 hour) and the threshold is 0.8, // the token will be refreshed after 2880 seconds (48 minutes). 'refresh_threshold' => env('ZAVA_TOKEN_REFRESH_THRESHOLD', 0.8), ],
You can adjust the refresh threshold by setting the ZAVA_TOKEN_REFRESH_THRESHOLD
environment variable. A higher value (closer to 1.0) will refresh the token later, while a lower value will refresh it earlier.
Retry Mechanism
The package includes a configurable retry mechanism for handling transient API failures. This helps improve the reliability of your application by automatically retrying failed requests.
Configuration
You can configure the retry behavior using the retry
section in the config file:
'retry' => [ 'max_attempts' => env('ZAVA_RETRY_MAX_ATTEMPTS', 3), 'base_delay' => env('ZAVA_RETRY_BASE_DELAY', 100), // in milliseconds 'max_delay' => env('ZAVA_RETRY_MAX_DELAY', 1000), // in milliseconds 'retryable_status_codes' => [408, 429, 500, 502, 503, 504], 'retryable_exceptions' => [ \Illuminate\Http\Client\ConnectionException::class, \AmaizingCompany\ZavaVideoCallClient\Exceptions\NetworkException::class, \AmaizingCompany\ZavaVideoCallClient\Exceptions\ServerException::class, \AmaizingCompany\ZavaVideoCallClient\Exceptions\RateLimitException::class, ], ],
Rate Limiting
The package includes support for client-side rate limiting to help you stay within the API's rate limits.
Configuration
You can configure the rate limiting behavior using the rate_limiting
section in the config file:
'rate_limiting' => [ 'enabled' => env('ZAVA_RATE_LIMITING_ENABLED', true), 'max_requests' => env('ZAVA_RATE_LIMITING_MAX_REQUESTS', 60), 'window' => env('ZAVA_RATE_LIMITING_WINDOW', 60), // in seconds ],
Events
This package dispatches events for various appointment actions, allowing you to hook into the lifecycle of appointments and perform additional actions when these events occur.
Available Events
AppointmentCreated
: Dispatched when a new appointment is createdAppointmentUpdated
: Dispatched when an existing appointment is updatedAppointmentDeleted
: Dispatched when an appointment is deletedAppointmentRetrieved
: Dispatched when an appointment is retrievedAppointmentsListed
: Dispatched when all appointments are listedUserCreated
: Dispatched when a new user is created
Listening for Events
You can listen for these events in your Laravel application by registering event listeners in your EventServiceProvider
:
use AmaizingCompany\ZavaVideoCallClient\Events\AppointmentCreated; use AmaizingCompany\ZavaVideoCallClient\Events\AppointmentUpdated; use AmaizingCompany\ZavaVideoCallClient\Events\AppointmentDeleted; use App\Listeners\HandleAppointmentCreated; use App\Listeners\HandleAppointmentUpdated; use App\Listeners\HandleAppointmentDeleted; protected $listen = [ AppointmentCreated::class => [ HandleAppointmentCreated::class, ], AppointmentUpdated::class => [ HandleAppointmentUpdated::class, ], AppointmentDeleted::class => [ HandleAppointmentDeleted::class, ], ];
Example Listener
Here's an example of a listener that sends a notification when an appointment is created:
namespace App\Listeners; use AmaizingCompany\ZavaVideoCallClient\Events\AppointmentCreated; use App\Notifications\AppointmentCreatedNotification; use Illuminate\Support\Facades\Notification; class HandleAppointmentCreated { public function handle(AppointmentCreated $event) { // Access appointment data $userId = $event->userId; $appointmentId = $event->appointmentId; $appointment = $event->appointment; // Get the appointment from the response $responseAppointment = $event->response->getAppointment(); // Perform additional actions, such as sending notifications Notification::route('mail', 'admin@example.com') ->notify(new AppointmentCreatedNotification($appointment)); } }
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.