Appearance
Zoom meetings for online bookings in Laravel, made by the site
A consultation is booked for Thursday at four. Wednesday evening the consultant opens Zoom, schedules a meeting, copies the link into an email, finds the client's address in the booking, and sends it. Thursday at four the client is searching their inbox for it. One of ten bookings is moved; the link in the email is now for the wrong hour. A salon that sees twenty clients online a week spends an afternoon on links, and the one it forgets is the one that calls.
Zoom's API will make a meeting; what takes the time on a Laravel site is everything around it: an app at Zoom that nobody has to sign in to, a meeting made the moment a booking is confirmed and not a second before, moved when the booking moves, deleted when it is cancelled, a link that reaches the client wherever they look and a start link that reaches only the staff member, and what to do when Zoom is down at the moment of confirmation. kitloom/ is that work done once, as a module of kitloom/bookings.
Ask the agent
With kitloom/ai connected, an agent whose user manages the meetings reads and makes them:
- "Send me the Zoom link of Ada's call on Tuesday." (
booking_— the meetings and their links, by booking code or dates)meetings_ list - "The meeting for booking 7KQ2MN failed; make it again." (
booking_)meetings_ create - "Does Zoom still take our credentials?" (
booking_)meetings_ check
Connecting Zoom and choosing the services stay in the admin, and the start link — the salon's key to the meeting — is shown to nobody without the permission to manage bookings.
Set up once at Zoom
One app for the site, made once by the owner or an admin of the Zoom account; it takes ten minutes and never expires. Nobody signs in to Zoom from the site, and no staff member needs a Zoom account: the meetings are made on the salon's.
- At marketplace.zoom.us, with the salon's account: Develop → Build App, a Server-to-Server OAuth App, a name such as Bookings.
- App Credentials shows three values: Account ID, Client ID and Client Secret.
- Scopes → Add Scopes → Meeting: the four meeting scopes, to make, read, move and delete a meeting. An app made a while ago shows the older names instead; either set does.
- Activation → Activate your app.
- In the admin, Zoom Meetings → Settings: paste the three values under Connect Zoom, save, then press Check access. Zoom takes the credentials means it is done; otherwise Zoom's own words, or the scopes the app still lacks, so a missing one is named rather than found at the first booking. The secret is kept encrypted with the application key and never shown back.
Then, under Video calls: Make a Zoom meeting for every confirmed booking on, Only for these services for a salon that also sees clients in person — Video consultation alone, and only its bookings get a meeting — and the Waiting room, on, so the client waits until the staff member lets them in.
What the client gets
A booking gets its meeting when it is confirmed: at once, when the salon confirms bookings at once, or when the staff member confirms it. From then on:
- The confirmation email and the reminder have a Join the video call button above Manage booking, and the passcode in the details. The link carries the passcode already.
- The calendar file carries the link as the event's link — the Join button of Google, Apple and Outlook calendars — and, when the salon has no address set, as the event's place too.
- The text messages of the confirmation and the reminder end with the link, with kitloom/text-messages.
- The account page, under Appointments, shows the link beside each upcoming confirmed booking, and so does the page the email's link opens.
The meeting is named after the service and the staff member — Consultation with Mira — and its description is the booking's code and the site's name: nothing of the client goes to Zoom.
The staff member gets the other link. Start the video call is in their new-booking email when the booking is confirmed already, on the page of their Confirm button once they confirm, and on their Schedule beside each confirmed booking of the day. It opens the meeting as its host, and it is never shown to the client.
When the booking changes
Moved to another time, service or staff member, the booking moves its meeting in Zoom, and the link stays the same, so what the client was sent still works. Moved to a service not held online, the meeting is deleted. Cancelled, declined or marked a no-show, it is deleted in Zoom, and Zoom sends nobody an email about it. Marked done, it is kept as history.
When Zoom does not answer
Zoom is called from the queue, three tries with a pause between. A call that still fails lands on the meeting's row in Zoom Meetings → Meetings with Zoom's words, and the booking goes on without the link: a booking is never refused because Zoom did not answer. From the row, Create again after fixing the cause, or Delete in Zoom for a meeting nobody needs. Site Health warns while the meetings are switched on without Zoom connected and while meetings of bookings still to come are failing, and the notification topic Zoom meeting failed tells a Telegram, Slack or browser channel which booking, what was asked and what Zoom said.
For a Laravel developer
Zoom is reached on Laravel's HTTP client, no SDK, with the Server-to-Server OAuth token kept in the cache for most of its hour. The meetings are a table of the module's own, booking_, one row per booking and gone with it, on an Eloquent model the application can swap through the Model. A cache lock per booking keeps the queue's job and the confirmation email from making two meetings: if the email goes out before the queue got to it, the email makes the meeting, and the queue finds it made.
The bookings module never names Zoom. The link reaches it through its Meeting contract: a module answers meeting($booking, $for with the address, a label and the passcode, or null, and the bookings put it into the emails, the calendar file, the page and the account. Google Meet or Microsoft Teams would be a module of their own on the same contract. Tests fake Zoom with Fakes. It comes with both admins, Filament and Nova.
Watch it
A short lesson from the admin, narrated:
Try it
The module comes with kitloom, for either admin. On a Filament site with bookings:
bash
composer require kitloom/booking-meetings kitloom/booking-meetings-filament
php artisan migrateOn a Nova site, the second package is kitloom/. Open a sandbox in one click, with no sign-up: Filament or Nova. Every detail — the scopes, what each email carries, the agent's tools, the settings — is in the Zoom Meetings guide; the bookings themselves, and the staff's Google Calendars, in Google Calendar sync for bookings.