1. Objective
Build three connected, platform-agnostic workflows:
- Service Appointment Confirmation
- Missed Appointment Rescheduling
- Daily Operations Task Digest
The system manages the full meeting lifecycle:
Meeting Scheduled → Confirmation → Meeting Time → Outcome Verification
→ Reschedule / Completed / No-Show → Follow-Up
The CRM remains the authoritative record for:
- lead status;
- meeting status;
- sales owner;
- appointment time;
- client contact information;
- final meeting outcome;
- follow-up state.
Calendar and email systems provide evidence, but all confirmed outcomes should ultimately be written back into the CRM.
2. Core architecture
CRM
|
| Lead Status = Meeting Scheduled
|
v
[TRIGGER] Appointment Created / Status Changed
|
v
[VALIDATE] Required Contact + Meeting Data
|
v
[CONFIRM] Calendar + Contact Details
|
v
[SCHEDULE] Pre-Meeting Reminder
|
v
MEETING TIME
|
v
[WAIT] Grace Period
|
v
[VERIFY OUTCOME]
├── Calendar
├── Email
├── CRM Status
├── Sales Rep Notes
└── Attendance Data if available
|
v
[ROUTER]
├── Completed
├── Cancelled
├── Reschedule Requested
├── No-Show
└── Manual Review
|
v
[ACTION] Update CRM
|
v
[FOLLOW-UP] Reschedule / Tasks / Digest
|
v
[AUDIT]
3. CRM as the source of truth
The CRM should contain the canonical appointment record.
| Field | Purpose |
|---|---|
lead_id | Lead reference |
contact_id | Contact reference |
company_id | Company reference |
sales_owner_id | Assigned sales owner |
sales_owner_name | Display name of the owner |
meeting_id | Stable meeting identifier |
meeting_title | Meeting subject |
meeting_status | Lifecycle state (see below) |
meeting_start | Meeting start timestamp |
meeting_end | Meeting end timestamp |
meeting_timezone | Timezone attached to the booking |
meeting_calendar_event_id | External calendar event reference |
meeting_confirmed_at | Confirmation timestamp |
meeting_completed_at | Completion timestamp |
meeting_cancelled_at | Cancellation timestamp |
reschedule_requested_at | When a reschedule was requested |
rescheduled_from | Original meeting reference |
rescheduled_to | Replacement meeting reference |
no_show_detected_at | When the no-show candidate was detected |
no_show_verified_at | When the no-show was verified |
last_customer_email_at | Most recent customer email |
last_sales_activity_at | Most recent sales activity |
meeting_verification_status | Outcome of the verification pass |
meeting_verification_reason | Why that outcome was chosen |
follow_up_status | State of the follow-up sequence |
workflow_version | Automation version that last touched the record |
updated_at | Last metadata update |
External systems should ideally reference the CRM record ID.
4. Recommended meeting states
Use standardized states regardless of CRM platform:
MEETING_SCHEDULED
CONFIRMATION_PENDING
CONFIRMED
RESCHEDULE_REQUESTED
RESCHEDULE_PENDING
RESCHEDULED
CANCELLED
MEETING_DUE
OUTCOME_VERIFICATION
COMPLETED
NO_SHOW_CANDIDATE
NO_SHOW_VERIFIED
MANUAL_REVIEW
The distinction between NO_SHOW_CANDIDATE and NO_SHOW_VERIFIED is especially important. A candidate is a suspicion; a verified no-show is a decision backed by evidence.
5. Core rule
Do not use:
Meeting time passed
|
v
No Show
Use:
Meeting time passed
|
v
Wait Grace Period
|
v
Check Calendar
|
v
Check Email
|
v
Check CRM
|
v
Check Rep Activity
|
v
Determine Outcome
That drastically reduces false no-show classifications.
BLUEPRINT 1 — SERVICE APPOINTMENT CONFIRMATION
6. Trigger
Primary trigger:
[TRIGGER] CRM Lead Status Changed
Condition: lead_status = MEETING_SCHEDULED
Alternative trigger:
[TRIGGER] Meeting Record Created
7. Fetch complete CRM context
[FETCH] Lead + Appointment
Retrieve:
- lead;
- contact;
- company;
- meeting;
- sales owner;
- email;
- phone;
- appointment time;
- appointment timezone;
- calendar event;
- previous meeting history.
8. Validate required fields
[FILTER] Appointment Data Complete?
Required:
- Contact Name
- Contact Email
- Meeting Start
- Meeting End
- Timezone
- Sales Owner
- Calendar Event ID
Optional:
- Phone
- Company
- Meeting Notes
- Meeting Type
If required data is missing:
APPOINTMENT_SETUP_INCOMPLETE
Notify the sales owner. Do not send the customer confirmation until the data is corrected.
9. Timezone validation
Timezone problems are one of the easiest ways to produce bad reminders.
Store both:
meeting_timezonecustomer_timezone
Normalize internally using UTC.
Example:
CRM:
2026-10-02 15:00 Europe/Tbilisi
Normalized:
2026-10-02T11:00:00Z
Notifications should then be rendered in the recipient's appropriate timezone.
If the customer timezone is unknown, use the timezone explicitly attached to the booked appointment.
10. Calendar verification
[LOOKUP] Calendar Event
Confirm:
- event exists;
- event start matches CRM;
- event end matches CRM;
- organizer matches expected owner;
- customer is invited.
Possible results:
CALENDAR_VERIFIED
CALENDAR_MISSING
CALENDAR_TIME_MISMATCH
ATTENDEE_MISSING
If calendar data conflicts with CRM, do not silently choose one. Route to MANUAL_REVIEW or configured reconciliation logic.
Remember: the CRM remains the canonical record.
11. Contact validation
Before reminders:
[FILTER] Valid Customer Contact?
Check:
- email exists;
- email syntax valid;
- contact not opted out.
If SMS confirmation is enabled, also verify phone availability and consent requirements where applicable.
12. Confirmation message
Once validated:
[ACTION] Send Appointment Confirmation
Example:
Hi [Name], your meeting with [Sales Rep] is scheduled for [Date] at [Time + Timezone]. If you need to change the time, you can reply to this message or use the rescheduling link.
Include:
- date;
- local time;
- timezone;
- meeting link;
- owner;
- reschedule option.
13. Update CRM
After successful confirmation:
meeting_status = CONFIRMED
meeting_confirmed_at = timestamp
Do not mark confirmed if delivery fails. Possible state: CONFIRMATION_FAILED.
14. Reminder schedule
Recommended configurable schedule:
| Timing | Action |
|---|---|
| 24 hours before | Reminder |
| 1–2 hours before | Final Reminder |
Avoid hard-coding. Store:
reminder_1_offsetreminder_2_offset
15. Duplicate reminder protection
Before sending:
[LOOKUP] Reminder History
Check:
meeting_idreminder_typesent_at
Then:
[FILTER] Reminder Already Sent?
If yes:
STOP
This prevents duplicate reminders when:
- workflow retries;
- calendar updates;
- CRM status updates;
- multiple triggers fire.
16. Re-verify before reminder
Immediately before sending:
[FETCH] Latest CRM Meeting
Then:
[FILTER] Status Still Scheduled?
If CANCELLED, RESCHEDULED, or COMPLETED, cancel the reminder. This is critical.
BLUEPRINT 2 — MISSED APPOINTMENT RESCHEDULING
This is the most important part of the architecture.
17. Meeting due trigger
At:
meeting_end + grace_period
trigger:
[SCHEDULE] Meeting Outcome Verification
Recommended grace period: 15–30 minutes, configurable by organization.
18. First check — CRM
Start with the source of truth.
[FETCH] Latest CRM Meeting
If CRM now says COMPLETED, stop.
If CANCELLED or RESCHEDULED, stop or continue into the relevant workflow.
If still MEETING_SCHEDULED, begin verification.
19. Second check — calendar
[LOOKUP] Calendar Event Status
Look for:
- event cancelled;
- attendee declined;
- attendee accepted;
- tentative;
- organizer cancelled;
- event moved;
- new calendar event created;
- attendance metadata if available.
Important: Attendee Accepted does not prove the meeting happened. It only provides supporting evidence.
20. Calendar decision logic
Example:
Customer Declined
|
v
CANCELLED / RESCHEDULE REVIEW
Event Was Moved
|
v
Look for Replacement Event
Event Still Exists
|
v
Continue Verification
If another appointment exists for the same CRM lead: RESCHEDULE_CANDIDATE.
21. Third check — email
[LOOKUP] Customer Email Thread
Search the relevant conversation window. Example:
meeting_start - 48 hours
through
current time
Look for replies suggesting:
- reschedule;
- move meeting;
- different time;
- can't make it;
- running late;
- tomorrow instead;
- next week;
- cancel.
A structured AI classifier may help here. Example output:
{
"intent": "RESCHEDULE_REQUEST",
"confidence": 0.94,
"suggested_time_found": true,
"suggested_time": "Thursday afternoon"
}
Possible intents:
NO_RELEVANT_REPLY
CONFIRMATION
RESCHEDULE_REQUEST
CANCELLATION
LATE_ARRIVAL
MEETING_OCCURRED
AMBIGUOUS
22. Email confidence rule
Do not automatically change meeting time based on low-confidence language.
Example:
Confidence >= threshold
→ Continue
Confidence < threshold
→ MANUAL_REVIEW
Especially for messages such as "Maybe another day would work better." That is different from "Can we move this to Friday at 2 PM?"
23. Fourth check — CRM activity
Now inspect sales activity.
[LOOKUP] CRM Timeline
Check:
- lead status changes;
- meeting outcome;
- notes;
- comments;
- tasks;
- call logs;
- activity timestamp;
- sales rep updates.
Examples:
- "Meeting went well, sending proposal" strongly indicates
COMPLETED. - "Client didn't join" indicates
NO_SHOW_CANDIDATE. - "Client emailed asking for next Tuesday" indicates
RESCHEDULE_REQUESTED.
24. Rep activity hierarchy
Define a hierarchy of evidence.
| Strength | Evidence |
|---|---|
| Strong | CRM meeting explicitly marked Completed; sales rep explicitly recorded Meeting Held; replacement appointment exists; calendar event explicitly cancelled; customer explicitly requested reschedule |
| Medium | CRM note describing meeting; customer declined invitation; new meeting appears shortly afterward |
| Weak | Calendar remained scheduled; no email received; no CRM activity |
Do not classify a no-show using weak evidence alone until the configured verification period is complete.
25. Outcome router
[ROUTER] Meeting Outcome
Possible routes:
COMPLETED
CANCELLED
RESCHEDULE_REQUESTED
RESCHEDULED
NO_SHOW
MANUAL_REVIEW
26. Completed meeting
If evidence confirms the meeting happened:
meeting_status = COMPLETED
meeting_completed_at = timestamp
Stop the rescheduling workflow. Optionally create a post-meeting sales task.
27. Cancellation
If the customer cancelled:
meeting_status = CANCELLED
Depending on policy:
[ACTION] Create Follow-Up Task
or:
[ACTION] Offer Rescheduling
28. Reschedule requested
If the customer requested another time:
meeting_status = RESCHEDULE_REQUESTED
Then:
[LOOKUP] Available Slots
Retrieve availability from the assigned rep's calendar.
29. Unavailable slot edge case
If the customer asks for Friday 14:00 but the slot is unavailable, do not automatically create a conflicting meeting.
Instead:
Requested Slot
|
v
Availability Check
|
v
Unavailable
|
v
Generate Alternatives
Example alternatives:
Friday 15:00
Monday 11:00
Monday 14:30
Then send those alternatives.
30. Rescheduling message
Example:
Hi [Name], no problem. [Requested time] isn't currently available, but these times are open:
- [Option 1]
- [Option 2]
- [Option 3]
Let me know what works best.
Alternatively, send a rescheduling link.
31. Confirm new appointment
Once a new slot is selected:
[ACTION] Create / Update Calendar Event
Then:
[ACTION] Update CRM
Store:
rescheduled_fromrescheduled_toprevious_meeting_idnew_meeting_id
Status: RESCHEDULED.
32. Verified no-show logic
Only classify as no-show after all checks. Example:
CRM still Scheduled
+ No completed-meeting evidence
+ No reschedule email
+ No cancellation
+ No replacement event
+ No rep note indicating meeting happened
+ Grace period elapsed
|
v
NO_SHOW_VERIFIED
33. No-show follow-up
[ACTION] Send Reschedule Message
Example:
Hi [Name], looks like we missed each other today. If you'd still like to connect, you can choose another time here: [Reschedule Link]
Keep it neutral. Avoid accusatory language.
34. CRM update
After verified no-show:
meeting_status = NO_SHOW_VERIFIED
no_show_verified_at = timestamp
follow_up_status = RESCHEDULE_SENT
35. Sales owner notification
Notify the rep:
Meeting #[ID] Customer did not attend.
No cancellation or reschedule request was detected.
Rescheduling follow-up has been sent.
Include:
- CRM link;
- meeting;
- customer;
- evidence summary.
36. Conflicting evidence
Example:
Calendar = Declined
CRM Note = "Meeting completed"
Do not auto-decide. Set MANUAL_REVIEW and notify the owner.
37. Evidence summary
Store why the system reached the decision. Example:
{
"calendar": "EVENT_ACTIVE",
"email": "NO_RELEVANT_REPLY",
"crm_status": "MEETING_SCHEDULED",
"rep_activity": "NONE",
"replacement_event": false,
"final_outcome": "NO_SHOW_VERIFIED"
}
This makes the automation explainable.
BLUEPRINT 3 — DAILY OPERATIONS TASK DIGEST
38. Objective
Give sales and operations a daily summary of appointment-related work requiring attention.
This should not simply list every meeting. It should surface:
- Meetings Today
- Unconfirmed Meetings
- No-Shows
- Reschedule Requests
- Missing Data
- Manual Reviews
- Overdue Follow-Ups
39. Trigger
[TRIGGER] Daily Scheduled Time
Example: every business day at 08:00 local operations timezone.
40. Fetch operational records
[FETCH] CRM Appointment Records
Retrieve:
- Today's Meetings;
- Tomorrow's Meetings;
- Unconfirmed Meetings;
- No-Show Verified;
- Reschedule Requested;
- Manual Review;
- Incomplete Appointment Records;
- Overdue Follow-Ups.
41. Digest recipients
Store configurable recipients:
sales_ownersales_managersales_operationscustomer_success
Different recipients can receive different views.
42. Sales rep digest
Rep receives only their records. Example:
YOUR APPOINTMENT SUMMARY
Today
- 4 scheduled
- 3 confirmed
- 1 awaiting confirmation
Action Required
- 1 reschedule request
- 1 no-show follow-up
- 1 missing meeting outcome
Tomorrow
- 3 meetings
43. Manager digest
Manager receives the aggregated operational view:
MEETING OPERATIONS
Today
Scheduled: 24
Confirmed: 21
Unconfirmed: 3
Yesterday
Completed: 14
No-Shows: 3
Rescheduled: 5
Outcome Missing: 2
Exceptions
Manual Review: 2
Missing Owner: 1
Overdue Follow-Up: 4
44. Priority ordering
The digest should order items:
- Manual Review
- Overdue Follow-Up
- No-Show
- Reschedule Request
- Unconfirmed Meeting
- Upcoming Meeting
This keeps attention on operational exceptions.
45. Missing sales owner
If an appointment has no owner:
OWNER_MISSING
Place it in the operations/manager digest. Do not silently ignore it.
46. Digest deduplication
Store:
digest_daterecipientrecord_iddigest_type
Prevent repeated delivery for the same run.
47. Master outcome verification architecture
The most important workflow can be represented as:
[SCHEDULE] Meeting End + Grace Period
|
v
[FETCH] CRM Meeting
|
v
[FILTER] Already Completed / Cancelled?
|
+── YES → STOP
|
+── NO
|
v
[LOOKUP] Calendar
|
v
[LOOKUP] Customer Email
|
v
[LOOKUP] CRM Timeline
|
v
[LOOKUP] Sales Rep Notes
|
v
[LOOKUP] Replacement Meeting
|
v
[TRANSFORM] Normalize Evidence
|
v
[ROUTER] Meeting Outcome
+------+----------+------------+---------+
| | | | |
v v v v v
Held Cancelled Reschedule No Show Review
| | | | |
v v v v v
CRM CRM Find Slots Follow-Up Rep Task
48. Recommended evidence resolution logic
Use something like:
IF CRM = Completed
→ COMPLETED
ELSE IF replacement appointment exists
→ RESCHEDULED
ELSE IF customer email = confirmed reschedule
→ RESCHEDULE_REQUESTED
ELSE IF calendar explicitly cancelled
→ CANCELLED
ELSE IF sales rep note confirms meeting held
→ COMPLETED
ELSE IF sales rep note confirms no-show
→ NO_SHOW_VERIFIED
ELSE IF meeting time + grace period elapsed
AND no contradictory evidence
→ NO_SHOW_VERIFIED
ELSE
→ MANUAL_REVIEW
49. Duplicate reminder safeguard
Every outbound action should use an idempotency key. Example:
meeting_id + notification_type + scheduled_window
Such as:
MEETING123_24H_REMINDER_20261002
If already present: SKIP.
50. Rescheduling safeguard
Before sending available times:
[FETCH] Current Calendar Availability
Do not rely on cached availability older than the configured threshold. For example:
availability_cache_max_age = 5 minutes
51. Email reschedule detection
Recommended structured output:
{
"intent": "RESCHEDULE_REQUEST",
"confidence": 0.93,
"requested_date": "2026-10-05",
"requested_time": "14:00",
"timezone": "Europe/Tbilisi",
"reason": "Customer explicitly asked to move the meeting"
}
If no exact date is provided:
{
"intent": "RESCHEDULE_REQUEST",
"confidence": 0.95,
"requested_date": null,
"requested_time": null
}
Then send available options.
52. Vault architecture
Credentials stay outside workflow logic.
Workflow
|
v
[VAULT]
|
+── CRM
+── Calendar
+── Email
+── Messaging
+── AI Provider
Never store OAuth tokens, API keys, passwords, or mailbox credentials inside workflow code.
53. Audit record
Recommended schema:
| Field | Purpose |
|---|---|
event_id | Unique audit event identifier |
meeting_id | Meeting reference |
lead_id | Lead reference |
event_type | What happened (see below) |
crm_status_before | CRM state before the decision |
crm_status_after | CRM state after the decision |
calendar_evidence | Calendar evidence collected |
email_evidence | Email evidence collected |
crm_evidence | CRM evidence collected |
rep_activity_evidence | Rep activity evidence collected |
decision | Final routed outcome |
decision_confidence | Confidence attached to the decision |
notification_type | Outbound notification triggered |
notification_result | Delivery result |
workflow_run_id | Execution reference |
workflow_version | Automation version |
created_at | Audit timestamp |
54. Useful audit events
APPOINTMENT_CREATED
APPOINTMENT_CONFIRMED
REMINDER_SENT
REMINDER_SKIPPED_DUPLICATE
MEETING_VERIFICATION_STARTED
CALENDAR_DECLINED
RESCHEDULE_EMAIL_DETECTED
CRM_OUTCOME_UPDATED
REP_NOTE_DETECTED
MEETING_COMPLETED
NO_SHOW_CANDIDATE
NO_SHOW_VERIFIED
RESCHEDULE_REQUESTED
RESCHEDULE_OPTIONS_SENT
MEETING_RESCHEDULED
MANUAL_REVIEW_REQUIRED
55. Important edge cases
- Timezone mismatch: compare CRM, calendar and customer timezone. Do not automatically modify conflicting times.
- Unavailable requested slot: fetch fresh calendar availability and provide alternatives.
- Duplicate reminder: use the reminder log / idempotency key.
- Calendar event missing: do not automatically classify no-show; continue checking CRM/email.
- Email connector unavailable: flag verification as incomplete and use the remaining sources.
- Sales rep updated CRM late: always re-fetch CRM immediately before sending a no-show message.
- Meeting occurred but rep forgot to update CRM: rep notes, activity and optional attendance data may prevent false no-show.
- Customer replied immediately before meeting: email lookup should include messages through the verification time.
- Multiple future meetings exist: identify which appointment supersedes the original one.
- Lead has no valid email: create a rep follow-up task rather than attempting automatic rescheduling.
- Meeting cancelled after reminder queued: refresh CRM state before delivery.
56. Daily exception dashboard
The same data can drive a simple operations dashboard:
TODAY'S MEETINGS
CONFIRMED
UNCONFIRMED
OUTCOMES MISSING
RESCHEDULE REQUESTED
NO-SHOWS
MANUAL REVIEW
FOLLOW-UP OVERDUE
This makes the system useful beyond notifications.
57. Final architecture
CRM
|
MEETING SCHEDULED
|
v
[VALIDATE]
|
v
[CALENDAR]
|
v
CONFIRMATION
|
v
REMINDERS
|
v
MEETING TIME
|
v
GRACE PERIOD
|
v
OUTCOME RECONCILIATION
|
+─────────────┼───────────────+
| | |
v v v
CALENDAR EMAIL CRM
|
REP ACTIVITY
+─────────────┬───────────────+
|
v
[ROUTER]
+────────┬──────────┬─────────┬─────────+
| | | | |
v v v v v
HELD CANCELLED RESCHEDULE NO SHOW REVIEW
| | | | |
+────────┴──────────┴─────────┴─────────+
|
CRM SOURCE OF TRUTH
|
v
FOLLOW-UP ACTION
|
v
AUDIT
The core principle:
The CRM decides the final state. Calendar, email, and rep activity provide the evidence needed to update it accurately.
That gives you a much stronger system than a basic "meeting missed → send reschedule email" automation, because you're reconciling what actually happened before taking action.