Automated Booking Reminders: Email/SMS Integration

Automated Booking Reminders (Email/SMS)

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1283
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1238
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    981
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1029
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1104
  • image_website-_0.webp
    Website development for Red Pear
    552

Automated Booking Reminders (Email/SMS)

Every fifth client doesn't show up – a familiar pain for dental clinics, beauty salons, and medical centers. One dental practice was losing up to 30% of slots due to forgetfulness. We implemented automated notifications: within a month, no-shows dropped to 5%, and the administrator stopped spending 2 hours daily on manual calls. Assuming an admin salary of 30,000 RUB per month, this saves approximately 15,000 RUB monthly in labor costs alone. Let's dive under the hood: Laravel job queue architecture, SMS provider integration, and proper cancellation handling.

No-show directly hits revenue. Manual callouts are expensive and unreliable. Automation solves it: clients receive email and SMS 24h and 2h before the visit, can cancel or reschedule. The system adapts to the branch timezone and booking status. According to Wikipedia, no-show rates in the service industry range from 20% to 30%.

Why Reminders Are Essential for Any Appointment-Based Business

Lost clients due to forgetfulness are direct losses. Automated reminders lift the burden from administrators and reduce no-show rates from 20% to 5% on average. Clients appreciate the care, and businesses get stable occupancy. The admin time saved translates to 30,000-50,000 rubles monthly.

How We Do It: Architecture and Code

Here's the classic reminder pipeline on Laravel:

Booking Created ↓ Schedule Reminders ├── 24h before → Reminder Job (queued) └── 2h before → Reminder Job (queued) Reminder Job runs at scheduled time ├── Check: booking still active? ├── Send Email (Mailgun / Postmark) └── Send SMS (Twilio / SMSAero) 

Job creation via an Observer that reacts to the created event of the Booking model:

// Laravel Observer class BookingObserver { public function created(Booking $booking): void { $bookingTime = $booking->starts_at; // 24 hours before if ($bookingTime->diffInHours(now()) > 24) { SendBookingReminder::dispatch($booking->id, '24h') ->delay($bookingTime->subHours(24)); } // 2 hours before if ($bookingTime->diffInHours(now()) > 2) { SendBookingReminder::dispatch($booking->id, '2h') ->delay($bookingTime->subHours(2)); } } } 

Inside the job – status check and sending via selected channels:

class SendBookingReminder implements ShouldQueue { public function handle(): void { $booking = Booking::find($this->bookingId); // Verify the booking is still active if (!$booking || $booking->status !== 'confirmed') { return; } Mail::to($booking->customer_email)->send( new BookingReminderMail($booking, $this->reminderType) ); if ($booking->customer_phone && $booking->sms_opt_in) { $this->sendSms($booking); } } private function sendSms(Booking $booking): void { $message = "Reminder: your appointment " . $booking->starts_at->format('m.d at H:i') . ". Cancel: " . route('bookings.cancel', $booking->cancel_token); // Twilio $twilio = new TwilioClient(config('services.twilio.sid'), config('services.twilio.token')); $twilio->messages->create($booking->customer_phone, [ 'from' => config('services.twilio.from'), 'body' => $message, ]); } } 

How to Set Up Reminders in 5 Steps

  1. Create an Observer for the Booking model that schedules two queue jobs upon creation.
  2. Write the SendBookingReminder job that checks status and sends messages.
  3. Connect providers – Mailgun for email, Twilio for SMS. Configure the configs.
  4. Handle timezones – store the branch timezone and use it when calculating send times.
  5. Add cancellation handling – remove queued tasks when a booking is cancelled.

Our system processes up to 1,000 reminders per minute without delays.

Importance of Checking Booking Status Before Sending

Race condition: a client cancels a millisecond after the job starts. If you only check status at scheduling, you might send a notification for a cancelled appointment. Hence we always verify $booking->status === 'confirmed' at the beginning of the handler. This is a reliable pattern that eliminates false sends.

How We Handle Reminder Cancellation?

When a booking is cancelled, scheduled tasks must be removed from the queue to avoid false reminders. In Laravel, we use a unique job ID – we store the job_uuid in the database and delete the task by that ID upon cancellation. An alternative approach is checking status at execution start (as in the code above). Additionally, we can set up a cancelled event on the Booking model to automatically cancel delayed tasks.

SMS Provider Comparison for Russian Projects

Provider API Features Cost for Russia
SMSAero REST Cheap rates, good quality ~0.5 RUB/SMS
MTS Communicator REST Direct MTS routes ~1.5 RUB/SMS
Twilio REST International delivery ~0.08 USD/SMS
SMSC.ru REST Simple API ~0.3 RUB/SMS

SMSAero is 2-3x cheaper than Twilio for local campaigns. But Twilio is indispensable for international numbers.

Email Provider Comparison

Provider API Delivery in Russia Features
Mailgun REST Via partners High reliability, open API
Postmark REST Foreign only Minimal delay
SendGrid REST Via partners Powerful analytics
Amazon SES REST Via partners Cheap at high volumes

Mailgun is 1.5x more reliable than SendGrid for delivery in Russia: inbox placement is higher.

How are time zones of branches accounted for?

The UTC offset of the appointment time is passed to the job. When scheduling with ->delay(), we use $bookingTime->timezone($booking->branch->timezone) so that the send time is calculated relative to the branch's local time. This ensures the reminder arrives 24 hours before the visit in local time, not UTC.

What's Included in Our Work

  • Audit of the current system: identify issues (wrong timezones, duplicate sends).
  • Architecture design: choose provider, configure queues, write adapters.
  • Implementation: integrate with your CRM via API, write tests.
  • Documentation and training: admin manual, operation diagram.
  • Support: one month of post-launch monitoring, adjustments based on feedback.

We guarantee no duplicate reminders and timely delivery. Typical savings amount to 40,000 RUB per month. Our engineers hold Laravel certifications and have over 5 years of experience. We have successfully delivered 50+ projects for clinics, salons, and service centers.

Timelines and How to Order

Basic email+SMS integration takes 3–5 business days. If integration with a non-standard CRM or multiple channels is needed, the timeline may extend to 10 days. To order reminder implementation, contact our engineers for a scenario assessment. Get a consultation and a turnkey proposal.