I think you mean, calendly?
Jan 30, 2023
8
Level 3
Booking System
Hello guys, Has any of you ever used calendily with laravel? If yes, do you have any resources I could use, the calendily documentation is pretty hard to read and understand!
Level 51
fyi, unless you use the paid version there are limitations. Like web hooks are not available when you are using the free version. So when the user tries to rescheduled (via the email they got from calendly) capturing the changes is problematic. But other wise...
I built a solution like this...
- show calendly iframe to schedule. once they make a selection capture the callback for the event, and save the response
- bill the client via PayPal
- capture additional details for the appointment
- show a confirmation page with all their details
Here is the schedule controller and view for step 1 (that handles the calendly portion)
using livewire
class Schedule extends Component
{
public function scheduled($url)
{
\DB::transaction( function () use ($url) {
$calendlyId = request()->getCalendlyId($url);
$responses = (new Calendly())->getEventAndInvitees($calendlyId);
$event = $responses[0]->collect()['resource'];
$invitee = $responses[1]->collect()['collection'][0];
$dog = Dog::firstOrCreate([ 'email' => $invitee['email'] ], [
'owner_first_name' => $invitee['first_name'],
'owner_last_name' => $invitee['last_name'],
'timezone' => $invitee['timezone'],
]);
Reading::firstOrCreate([ 'calendly_id' => $calendlyId ], [
'reschedule_id' => request()->getCalendlyId($invitee['reschedule_url']),
'start_at' => $event['start_time'],
'end_at' => $event['end_time'],
'status' => $event['status'],
'dog_id' => $dog->id
]);
return redirect()->route('payment', ['reading' => $calendlyId]);
});
}
public function render()
{
return view('schedule')->layout('layouts.app', [
'title' => 'Schedule | ' . config('app.name'),
'ogTitle' => 'Schedule a reading for your dog.',
]);
}
}
and the view...
<div class="flex min-h-screen bg-base-300">
<div class="container mx-auto sm:pt-10">
<div class="max-w-sm md:max-w-4xl mx-auto px-4">
<div id="calendly" class="mt-8 md:mt-0 transition duration-500 ease-in-out h-[700px] rounded-md overflow-hidden" wire:ignore>
<div class="calendly-inline-widget" data-url="https://calendly.com/YOURACCOUNT/YOUAPPOINTMENTTYPE?hide_event_type_details=1&embed_type=Inline" style="height: 100%; width: 100%;" ></div>
<script type="text/javascript" src="https://assets.calendly.com/assets/external/widget.js" async></script>
</div>
@include('_loading-payment') // this is just a loading skeleton for will the page loads
</div>
</div>
@push('scripts')
<script>
function isCalendlyEvent(e) {
return e.data.event && e.data.event.indexOf('calendly') === 0;
};
window.addEventListener( 'message', function(e) {
if (isCalendlyEvent(e)) {
if (e.data.event === 'calendly.event_scheduled') {
document.getElementById("calendly").remove();
@this.scheduled(e.data.payload.event.uri);
}
}
});
</script>
@endpush
</div>
and here is my Client method
public function getEventAndInvitees(string $calendlyId)
{
$responses = Http::pool(fn (Pool $pool) => [
$pool->withToken(config('services.calendly.token'))
->get("https://api.calendly.com/scheduled_events/{$calendlyId}"),
$pool->withToken(config('services.calendly.token'))
->get("https://api.calendly.com/scheduled_events/{$calendlyId}/invitees?status=active")
]);
if ( ! $responses[0]->ok() || ! $responses[1]->ok() ) {
Abort('503', 'Houston we have a problem');
}
return $responses;
}
so basically
Please or to participate in this conversation.