Salesforce Use case · Field Service · Service Appointment

Tell the customer the technician is on the way, and let them move the slot by replying.

One record-triggered flow on the Service Appointment sends the text when the status changes. The reply comes back to the same appointment, so a rescheduling request is a field, not a voicemail.

ObjectServiceAppointment
Fires onStatus → En Route
Reply landsTask on the Contact, WhatId = the appointment
ChannelSMS or WhatsApp, same flow
01 · What quietly breaks

The customer does not know the van left, so the van comes back.

Field Service knows the technician is en route the moment the mobile app flips the status. The customer does not. They step out, the technician knocks on an empty house, and the appointment is closed as Cannot Complete. That slot is gone, a second visit is booked, and the second visit costs the same as the first.

The workaround is a phone call from dispatch, which reaches voicemail about half the time and takes two minutes of a dispatcher's morning each. In an org running 60 appointments a day that is two hours of calling to leave messages nobody hears until later.

When the customer does want to move the slot, they call the main line, and the request is written in a note that the scheduler reads after the technician has already driven there.

02 · The idea

Keep the process where the record is. The Service Appointment already knows who, when and what status. Let it send the text, and write the reply back onto itself.

03 · The pattern

Four parts, all standard Salesforce.

No new object and no external scheduler. One dynamic template, one record-triggered flow, one keyword rule and one field on the appointment. An admin who has built a flow before can put it together in an afternoon.

01

Write the template against the appointment

A dynamic template on ServiceAppointment. Merge fields pull the technician's first name from the assigned ServiceResource, the arrival window from ArrivalWindowStartTime, and the customer's first name from the parent Contact. Nobody types a name a record already holds.

The message ends with the two reply options and the opt-out line. Under 160 characters, so it is one segment.

In Salesforce ObjectServiceAppointmentTemplateSA_EnRoute (dynamic)Merge fieldsContact.FirstName, AssignedResource.ServiceResource.Name, ArrivalWindowStartTimeSegments1
02

Fire it when the status changes to En Route

A record-triggered flow on ServiceAppointment, after save, with the entry condition Status is changed and Status equals En Route. It calls the ValueText send action with the template and the appointment Id. Nothing else in the flow.

Add one decision element before the send: if the parent Contact has SMS opt-out checked, or the local time is outside the send window, exit. The consent field is Salesforce's, not ours.

In Salesforce Flow typeRecord-triggered, after saveEntryStatus ISCHANGED AND Status = 'En Route'ActionValueText: Send MessageInputsRecordId, TemplateName, Channel
03

Let a reply of 2 set a field

Inbound messages land as a Message Bucket record and a Task on the Contact. A keyword rule matches a reply of 2 within the appointment's window and sets Reschedule_Requested__c to true on the ServiceAppointment. A reply of 1 sets Customer_Confirmed__c.

That is the whole trick. The customer's intent is now a checkbox on the record that already drives the schedule, so every downstream step is ordinary Salesforce automation.

In Salesforce Inbound recordMessage Bucket → Task (WhoId = Contact)Keyword2 → Reschedule_Requested__c = trueKeyword1 → Customer_Confirmed__c = trueAnything elseTask stays open, owner = dispatcher queue
04

Route the reschedule to a person

A second flow watches Reschedule_Requested__c. When it flips, it sends the acknowledgement template, posts to the dispatch Chatter group with the appointment link, and creates a Task on the appointment owner due in one hour. The technician's mobile app shows the status change, so they turn around instead of arriving.

The dispatcher who calls back has the whole thread in the activity timeline and does not ask the customer to repeat anything.

In Salesforce TriggerReschedule_Requested__c ISCHANGED = trueSendsSA_Reschedule_AckCreatesTask, owner = SA owner, due +1hUpdatesStatus → Scheduled (hold)
Fig 01 · SA-0048213 · Priya Raman
Hi Priya, Dan from Northline is on the way and about 25 minutes out. Reply 1 to confirm someone is home, or 2 if today no longer works.
Sent 09:14 · from Flow · template SA_EnRoute
2
Received 09:16 · Task on Contact · Reschedule_Requested__c = true
Understood. Dispatch will call you within the hour to find a new slot. Nothing else needed from you.
Sent 09:16 · from Flow · template SA_Reschedule_Ack
04 · Replies and exceptions

Every reply has one destination.

The customer never sees a menu deeper than one digit. Everything that is not a 1 or a 2 goes to a human with the record open.

ReplyWhat happensWhere it lands
1 Customer_Confirmed__c is set. The technician's mobile app shows a green tick on the appointment. No further message goes out. ServiceAppointment.Customer_Confirmed__c
2 Reschedule_Requested__c is set. Acknowledgement sent, dispatcher Task created, Chatter post to the dispatch group. ServiceAppointment.Reschedule_Requested__c
Free text The Task stays open on the Contact and is assigned to the dispatch queue. The dispatcher replies from the Converse view, on the same thread. Task on Contact, owner = Dispatch queue
STOP The Contact's opt-out field is set at the record level. The flow's decision element blocks every future send for this Contact, including from other flows. Contact.SMS_Opt_Out__c
No reply Nothing happens. The technician arrives as scheduled. The send is still on the record as a Completed Task, so nobody can say the customer was not told. Task, Status = Completed
05 · Guardrails

Four rules the flow checks before it sends.

ConsentThe Contact's opt-out field is checked in the decision element before the send action. A STOP reply sets it. Imported contacts start unconsented.
Quiet hoursThe org-level time window blocks sends before 08:00 or after 20:00 in the recipient's time zone, taken from the Service Territory. An En Route status at 07:40 sends at 08:00.
One per appointmentThe flow's entry condition is Status ISCHANGED, so a status bounced back and forth in the mobile app sends once per change, and a Last_Notified__c timestamp blocks a second send within 30 minutes.
Opt-out lineThe template carries Reply STOP to opt out. It counts toward the 160 characters, and the template preview shows the segment count before you save.
06 · Reporting afterwards

A report on the appointment, not on the messages.

The two checkboxes and the Task records are all standard fields, so the report is a Service Appointments with Tasks report type and a filter. No export, no message log to join.

En route notices · this weekService Appointments with Activities
AppointmentNotifiedReplyOutcome
SA-004821309:142Rescheduled, same day
SA-004821409:311Completed
SA-004821910:02No replyCompleted
SA-004822110:401Completed
SA-004822511:15Free textCompleted, dispatcher replied
SentCount of Tasks with Subject starting SMS: SA_EnRoute, grouped by day.
Moved by replyCount of appointments where Reschedule_Requested__c is true, against total notified. This is the number that replaces the missed visit count.
Cannot CompleteAppointments closed as Cannot Complete with a notice sent, before and after. The delta is the case for the project.
07 · Implementation note

Where ValueText fits.

ValueText is the send action and the inbound handler. It installs from AppExchange as a managed package, adds the Send Message invocable action to Flow Builder, and writes every inbound message as a Message Bucket record and a Task on the related Contact. The template editor, keyword rules and the org-level time window live in ValueText Setup. The two checkboxes, the flows and the report are yours, built with standard tools, and they keep working if you swap the number or the carrier.

Professional edition or above · Field Service not required, any object with a status and a phone works the same way · 1 SMS segment per notice at the published per-country rate
AppExchange review

“Our company was looking for a text application to notify our support team on weekends and holidays. ValueText was by far the simplest and most cost effective application for our needs.”

Renee Pierce Renee PierceSalesforce Admin · AppExchange
This page sits underSMS for SalesforceThe channel page: how sending, receiving and billing work for SMS.
In the docs
01 Add the Send Message action to a record-triggered flowFlow Builder, inputs and the test run → 02 Dynamic templates: merge fields from related objectsReaching Contact and ServiceResource fields from ServiceAppointment → 03 Keyword rules that update a field on the parent recordMatching 1 and 2 inside an appointment window →

Run your messaging inside your CRM.

Rated 4.98 on Salesforce AppExchange
Salesforce Use case · Field Service · Service Appointment

Tell the customer the technician is on the way, and let them move the slot by replying.

One record-triggered flow on the Service Appointment sends the text when the status changes. The reply comes back to the same appointment, so a rescheduling request is a field, not a voicemail.

ObjectServiceAppointment
Fires onStatus → En Route
Reply landsTask on the Contact, WhatId = the appointment
ChannelSMS or WhatsApp, same flow
01 · What quietly breaks

The customer does not know the van left, so the van comes back.

Field Service knows the technician is en route the moment the mobile app flips the status. The customer does not. They step out, the technician knocks on an empty house, and the appointment is closed as Cannot Complete. That slot is gone, a second visit is booked, and the second visit costs the same as the first.

The workaround is a phone call from dispatch, which reaches voicemail about half the time and takes two minutes of a dispatcher's morning each. In an org running 60 appointments a day that is two hours of calling to leave messages nobody hears until later.

When the customer does want to move the slot, they call the main line, and the request is written in a note that the scheduler reads after the technician has already driven there.

02 · The idea

Keep the process where the record is. The Service Appointment already knows who, when and what status. Let it send the text, and write the reply back onto itself.

03 · The pattern

Four parts, all standard Salesforce.

No new object and no external scheduler. One dynamic template, one record-triggered flow, one keyword rule and one field on the appointment. An admin who has built a flow before can put it together in an afternoon.

01

Write the template against the appointment

A dynamic template on ServiceAppointment. Merge fields pull the technician's first name from the assigned ServiceResource, the arrival window from ArrivalWindowStartTime, and the customer's first name from the parent Contact. Nobody types a name a record already holds.

The message ends with the two reply options and the opt-out line. Under 160 characters, so it is one segment.

In Salesforce ObjectServiceAppointmentTemplateSA_EnRoute (dynamic)Merge fieldsContact.FirstName, AssignedResource.ServiceResource.Name, ArrivalWindowStartTimeSegments1
02

Fire it when the status changes to En Route

A record-triggered flow on ServiceAppointment, after save, with the entry condition Status is changed and Status equals En Route. It calls the ValueText send action with the template and the appointment Id. Nothing else in the flow.

Add one decision element before the send: if the parent Contact has SMS opt-out checked, or the local time is outside the send window, exit. The consent field is Salesforce's, not ours.

In Salesforce Flow typeRecord-triggered, after saveEntryStatus ISCHANGED AND Status = 'En Route'ActionValueText: Send MessageInputsRecordId, TemplateName, Channel
03

Let a reply of 2 set a field

Inbound messages land as a Message Bucket record and a Task on the Contact. A keyword rule matches a reply of 2 within the appointment's window and sets Reschedule_Requested__c to true on the ServiceAppointment. A reply of 1 sets Customer_Confirmed__c.

That is the whole trick. The customer's intent is now a checkbox on the record that already drives the schedule, so every downstream step is ordinary Salesforce automation.

In Salesforce Inbound recordMessage Bucket → Task (WhoId = Contact)Keyword2 → Reschedule_Requested__c = trueKeyword1 → Customer_Confirmed__c = trueAnything elseTask stays open, owner = dispatcher queue
04

Route the reschedule to a person

A second flow watches Reschedule_Requested__c. When it flips, it sends the acknowledgement template, posts to the dispatch Chatter group with the appointment link, and creates a Task on the appointment owner due in one hour. The technician's mobile app shows the status change, so they turn around instead of arriving.

The dispatcher who calls back has the whole thread in the activity timeline and does not ask the customer to repeat anything.

In Salesforce TriggerReschedule_Requested__c ISCHANGED = trueSendsSA_Reschedule_AckCreatesTask, owner = SA owner, due +1hUpdatesStatus → Scheduled (hold)
Fig 01 · SA-0048213 · Priya Raman
Hi Priya, Dan from Northline is on the way and about 25 minutes out. Reply 1 to confirm someone is home, or 2 if today no longer works.
Sent 09:14 · from Flow · template SA_EnRoute
2
Received 09:16 · Task on Contact · Reschedule_Requested__c = true
Understood. Dispatch will call you within the hour to find a new slot. Nothing else needed from you.
Sent 09:16 · from Flow · template SA_Reschedule_Ack
04 · Replies and exceptions

Every reply has one destination.

The customer never sees a menu deeper than one digit. Everything that is not a 1 or a 2 goes to a human with the record open.

ReplyWhat happensWhere it lands
1 Customer_Confirmed__c is set. The technician's mobile app shows a green tick on the appointment. No further message goes out. ServiceAppointment.Customer_Confirmed__c
2 Reschedule_Requested__c is set. Acknowledgement sent, dispatcher Task created, Chatter post to the dispatch group. ServiceAppointment.Reschedule_Requested__c
Free text The Task stays open on the Contact and is assigned to the dispatch queue. The dispatcher replies from the Converse view, on the same thread. Task on Contact, owner = Dispatch queue
STOP The Contact's opt-out field is set at the record level. The flow's decision element blocks every future send for this Contact, including from other flows. Contact.SMS_Opt_Out__c
No reply Nothing happens. The technician arrives as scheduled. The send is still on the record as a Completed Task, so nobody can say the customer was not told. Task, Status = Completed
05 · Guardrails

Four rules the flow checks before it sends.

ConsentThe Contact's opt-out field is checked in the decision element before the send action. A STOP reply sets it. Imported contacts start unconsented.
Quiet hoursThe org-level time window blocks sends before 08:00 or after 20:00 in the recipient's time zone, taken from the Service Territory. An En Route status at 07:40 sends at 08:00.
One per appointmentThe flow's entry condition is Status ISCHANGED, so a status bounced back and forth in the mobile app sends once per change, and a Last_Notified__c timestamp blocks a second send within 30 minutes.
Opt-out lineThe template carries Reply STOP to opt out. It counts toward the 160 characters, and the template preview shows the segment count before you save.
06 · Reporting afterwards

A report on the appointment, not on the messages.

The two checkboxes and the Task records are all standard fields, so the report is a Service Appointments with Tasks report type and a filter. No export, no message log to join.

En route notices · this weekService Appointments with Activities
AppointmentNotifiedReplyOutcome
SA-004821309:142Rescheduled, same day
SA-004821409:311Completed
SA-004821910:02No replyCompleted
SA-004822110:401Completed
SA-004822511:15Free textCompleted, dispatcher replied
SentCount of Tasks with Subject starting SMS: SA_EnRoute, grouped by day.
Moved by replyCount of appointments where Reschedule_Requested__c is true, against total notified. This is the number that replaces the missed visit count.
Cannot CompleteAppointments closed as Cannot Complete with a notice sent, before and after. The delta is the case for the project.
07 · Implementation note

Where ValueText fits.

ValueText is the send action and the inbound handler. It installs from AppExchange as a managed package, adds the Send Message invocable action to Flow Builder, and writes every inbound message as a Message Bucket record and a Task on the related Contact. The template editor, keyword rules and the org-level time window live in ValueText Setup. The two checkboxes, the flows and the report are yours, built with standard tools, and they keep working if you swap the number or the carrier.

Professional edition or above · Field Service not required, any object with a status and a phone works the same way · 1 SMS segment per notice at the published per-country rate
AppExchange review

“Our company was looking for a text application to notify our support team on weekends and holidays. ValueText was by far the simplest and most cost effective application for our needs.”

Renee Pierce Renee PierceSalesforce Admin · AppExchange
This page sits underSMS for SalesforceThe channel page: how sending, receiving and billing work for SMS.
In the docs
01 Add the Send Message action to a record-triggered flowFlow Builder, inputs and the test run → 02 Dynamic templates: merge fields from related objectsReaching Contact and ServiceResource fields from ServiceAppointment → 03 Keyword rules that update a field on the parent recordMatching 1 and 2 inside an appointment window →

Run your messaging inside your CRM.

Rated 4.98 on Salesforce AppExchange
Salesforce Use case · Field Service · Service Appointment

Tell the customer the technician is on the way, and let them move the slot by replying.

One record-triggered flow on the Service Appointment sends the text when the status changes. The reply comes back to the same appointment, so a rescheduling request is a field, not a voicemail.

ObjectServiceAppointment
Fires onStatus → En Route
Reply landsTask on the Contact, WhatId = the appointment
ChannelSMS or WhatsApp, same flow
01 · What quietly breaks

The customer does not know the van left, so the van comes back.

Field Service knows the technician is en route the moment the mobile app flips the status. The customer does not. They step out, the technician knocks on an empty house, and the appointment is closed as Cannot Complete. That slot is gone, a second visit is booked, and the second visit costs the same as the first.

The workaround is a phone call from dispatch, which reaches voicemail about half the time and takes two minutes of a dispatcher's morning each. In an org running 60 appointments a day that is two hours of calling to leave messages nobody hears until later.

When the customer does want to move the slot, they call the main line, and the request is written in a note that the scheduler reads after the technician has already driven there.

02 · The idea

Keep the process where the record is. The Service Appointment already knows who, when and what status. Let it send the text, and write the reply back onto itself.

03 · The pattern

Four parts, all standard Salesforce.

No new object and no external scheduler. One dynamic template, one record-triggered flow, one keyword rule and one field on the appointment. An admin who has built a flow before can put it together in an afternoon.

01

Write the template against the appointment

A dynamic template on ServiceAppointment. Merge fields pull the technician's first name from the assigned ServiceResource, the arrival window from ArrivalWindowStartTime, and the customer's first name from the parent Contact. Nobody types a name a record already holds.

The message ends with the two reply options and the opt-out line. Under 160 characters, so it is one segment.

In Salesforce ObjectServiceAppointmentTemplateSA_EnRoute (dynamic)Merge fieldsContact.FirstName, AssignedResource.ServiceResource.Name, ArrivalWindowStartTimeSegments1
02

Fire it when the status changes to En Route

A record-triggered flow on ServiceAppointment, after save, with the entry condition Status is changed and Status equals En Route. It calls the ValueText send action with the template and the appointment Id. Nothing else in the flow.

Add one decision element before the send: if the parent Contact has SMS opt-out checked, or the local time is outside the send window, exit. The consent field is Salesforce's, not ours.

In Salesforce Flow typeRecord-triggered, after saveEntryStatus ISCHANGED AND Status = 'En Route'ActionValueText: Send MessageInputsRecordId, TemplateName, Channel
03

Let a reply of 2 set a field

Inbound messages land as a Message Bucket record and a Task on the Contact. A keyword rule matches a reply of 2 within the appointment's window and sets Reschedule_Requested__c to true on the ServiceAppointment. A reply of 1 sets Customer_Confirmed__c.

That is the whole trick. The customer's intent is now a checkbox on the record that already drives the schedule, so every downstream step is ordinary Salesforce automation.

In Salesforce Inbound recordMessage Bucket → Task (WhoId = Contact)Keyword2 → Reschedule_Requested__c = trueKeyword1 → Customer_Confirmed__c = trueAnything elseTask stays open, owner = dispatcher queue
04

Route the reschedule to a person

A second flow watches Reschedule_Requested__c. When it flips, it sends the acknowledgement template, posts to the dispatch Chatter group with the appointment link, and creates a Task on the appointment owner due in one hour. The technician's mobile app shows the status change, so they turn around instead of arriving.

The dispatcher who calls back has the whole thread in the activity timeline and does not ask the customer to repeat anything.

In Salesforce TriggerReschedule_Requested__c ISCHANGED = trueSendsSA_Reschedule_AckCreatesTask, owner = SA owner, due +1hUpdatesStatus → Scheduled (hold)
Fig 01 · SA-0048213 · Priya Raman
Hi Priya, Dan from Northline is on the way and about 25 minutes out. Reply 1 to confirm someone is home, or 2 if today no longer works.
Sent 09:14 · from Flow · template SA_EnRoute
2
Received 09:16 · Task on Contact · Reschedule_Requested__c = true
Understood. Dispatch will call you within the hour to find a new slot. Nothing else needed from you.
Sent 09:16 · from Flow · template SA_Reschedule_Ack
04 · Replies and exceptions

Every reply has one destination.

The customer never sees a menu deeper than one digit. Everything that is not a 1 or a 2 goes to a human with the record open.

ReplyWhat happensWhere it lands
1 Customer_Confirmed__c is set. The technician's mobile app shows a green tick on the appointment. No further message goes out. ServiceAppointment.Customer_Confirmed__c
2 Reschedule_Requested__c is set. Acknowledgement sent, dispatcher Task created, Chatter post to the dispatch group. ServiceAppointment.Reschedule_Requested__c
Free text The Task stays open on the Contact and is assigned to the dispatch queue. The dispatcher replies from the Converse view, on the same thread. Task on Contact, owner = Dispatch queue
STOP The Contact's opt-out field is set at the record level. The flow's decision element blocks every future send for this Contact, including from other flows. Contact.SMS_Opt_Out__c
No reply Nothing happens. The technician arrives as scheduled. The send is still on the record as a Completed Task, so nobody can say the customer was not told. Task, Status = Completed
05 · Guardrails

Four rules the flow checks before it sends.

ConsentThe Contact's opt-out field is checked in the decision element before the send action. A STOP reply sets it. Imported contacts start unconsented.
Quiet hoursThe org-level time window blocks sends before 08:00 or after 20:00 in the recipient's time zone, taken from the Service Territory. An En Route status at 07:40 sends at 08:00.
One per appointmentThe flow's entry condition is Status ISCHANGED, so a status bounced back and forth in the mobile app sends once per change, and a Last_Notified__c timestamp blocks a second send within 30 minutes.
Opt-out lineThe template carries Reply STOP to opt out. It counts toward the 160 characters, and the template preview shows the segment count before you save.
06 · Reporting afterwards

A report on the appointment, not on the messages.

The two checkboxes and the Task records are all standard fields, so the report is a Service Appointments with Tasks report type and a filter. No export, no message log to join.

En route notices · this weekService Appointments with Activities
AppointmentNotifiedReplyOutcome
SA-004821309:142Rescheduled, same day
SA-004821409:311Completed
SA-004821910:02No replyCompleted
SA-004822110:401Completed
SA-004822511:15Free textCompleted, dispatcher replied
SentCount of Tasks with Subject starting SMS: SA_EnRoute, grouped by day.
Moved by replyCount of appointments where Reschedule_Requested__c is true, against total notified. This is the number that replaces the missed visit count.
Cannot CompleteAppointments closed as Cannot Complete with a notice sent, before and after. The delta is the case for the project.
07 · Implementation note

Where ValueText fits.

ValueText is the send action and the inbound handler. It installs from AppExchange as a managed package, adds the Send Message invocable action to Flow Builder, and writes every inbound message as a Message Bucket record and a Task on the related Contact. The template editor, keyword rules and the org-level time window live in ValueText Setup. The two checkboxes, the flows and the report are yours, built with standard tools, and they keep working if you swap the number or the carrier.

Professional edition or above · Field Service not required, any object with a status and a phone works the same way · 1 SMS segment per notice at the published per-country rate
AppExchange review

“Our company was looking for a text application to notify our support team on weekends and holidays. ValueText was by far the simplest and most cost effective application for our needs.”

Renee Pierce Renee PierceSalesforce Admin · AppExchange
This page sits underSMS for SalesforceThe channel page: how sending, receiving and billing work for SMS.
In the docs
01 Add the Send Message action to a record-triggered flowFlow Builder, inputs and the test run → 02 Dynamic templates: merge fields from related objectsReaching Contact and ServiceResource fields from ServiceAppointment → 03 Keyword rules that update a field on the parent recordMatching 1 and 2 inside an appointment window →

Run your messaging inside your CRM.

Rated 4.98 on Salesforce AppExchange
Salesforce Use case · Field Service · Service Appointment

Tell the customer the technician is on the way, and let them move the slot by replying.

One record-triggered flow on the Service Appointment sends the text when the status changes. The reply comes back to the same appointment, so a rescheduling request is a field, not a voicemail.

ObjectServiceAppointment
Fires onStatus → En Route
Reply landsTask on the Contact, WhatId = the appointment
ChannelSMS or WhatsApp, same flow
01 · What quietly breaks

The customer does not know the van left, so the van comes back.

Field Service knows the technician is en route the moment the mobile app flips the status. The customer does not. They step out, the technician knocks on an empty house, and the appointment is closed as Cannot Complete. That slot is gone, a second visit is booked, and the second visit costs the same as the first.

The workaround is a phone call from dispatch, which reaches voicemail about half the time and takes two minutes of a dispatcher's morning each. In an org running 60 appointments a day that is two hours of calling to leave messages nobody hears until later.

When the customer does want to move the slot, they call the main line, and the request is written in a note that the scheduler reads after the technician has already driven there.

02 · The idea

Keep the process where the record is. The Service Appointment already knows who, when and what status. Let it send the text, and write the reply back onto itself.

03 · The pattern

Four parts, all standard Salesforce.

No new object and no external scheduler. One dynamic template, one record-triggered flow, one keyword rule and one field on the appointment. An admin who has built a flow before can put it together in an afternoon.

01

Write the template against the appointment

A dynamic template on ServiceAppointment. Merge fields pull the technician's first name from the assigned ServiceResource, the arrival window from ArrivalWindowStartTime, and the customer's first name from the parent Contact. Nobody types a name a record already holds.

The message ends with the two reply options and the opt-out line. Under 160 characters, so it is one segment.

In Salesforce ObjectServiceAppointmentTemplateSA_EnRoute (dynamic)Merge fieldsContact.FirstName, AssignedResource.ServiceResource.Name, ArrivalWindowStartTimeSegments1
02

Fire it when the status changes to En Route

A record-triggered flow on ServiceAppointment, after save, with the entry condition Status is changed and Status equals En Route. It calls the ValueText send action with the template and the appointment Id. Nothing else in the flow.

Add one decision element before the send: if the parent Contact has SMS opt-out checked, or the local time is outside the send window, exit. The consent field is Salesforce's, not ours.

In Salesforce Flow typeRecord-triggered, after saveEntryStatus ISCHANGED AND Status = 'En Route'ActionValueText: Send MessageInputsRecordId, TemplateName, Channel
03

Let a reply of 2 set a field

Inbound messages land as a Message Bucket record and a Task on the Contact. A keyword rule matches a reply of 2 within the appointment's window and sets Reschedule_Requested__c to true on the ServiceAppointment. A reply of 1 sets Customer_Confirmed__c.

That is the whole trick. The customer's intent is now a checkbox on the record that already drives the schedule, so every downstream step is ordinary Salesforce automation.

In Salesforce Inbound recordMessage Bucket → Task (WhoId = Contact)Keyword2 → Reschedule_Requested__c = trueKeyword1 → Customer_Confirmed__c = trueAnything elseTask stays open, owner = dispatcher queue
04

Route the reschedule to a person

A second flow watches Reschedule_Requested__c. When it flips, it sends the acknowledgement template, posts to the dispatch Chatter group with the appointment link, and creates a Task on the appointment owner due in one hour. The technician's mobile app shows the status change, so they turn around instead of arriving.

The dispatcher who calls back has the whole thread in the activity timeline and does not ask the customer to repeat anything.

In Salesforce TriggerReschedule_Requested__c ISCHANGED = trueSendsSA_Reschedule_AckCreatesTask, owner = SA owner, due +1hUpdatesStatus → Scheduled (hold)
Fig 01 · SA-0048213 · Priya Raman
Hi Priya, Dan from Northline is on the way and about 25 minutes out. Reply 1 to confirm someone is home, or 2 if today no longer works.
Sent 09:14 · from Flow · template SA_EnRoute
2
Received 09:16 · Task on Contact · Reschedule_Requested__c = true
Understood. Dispatch will call you within the hour to find a new slot. Nothing else needed from you.
Sent 09:16 · from Flow · template SA_Reschedule_Ack
04 · Replies and exceptions

Every reply has one destination.

The customer never sees a menu deeper than one digit. Everything that is not a 1 or a 2 goes to a human with the record open.

ReplyWhat happensWhere it lands
1 Customer_Confirmed__c is set. The technician's mobile app shows a green tick on the appointment. No further message goes out. ServiceAppointment.Customer_Confirmed__c
2 Reschedule_Requested__c is set. Acknowledgement sent, dispatcher Task created, Chatter post to the dispatch group. ServiceAppointment.Reschedule_Requested__c
Free text The Task stays open on the Contact and is assigned to the dispatch queue. The dispatcher replies from the Converse view, on the same thread. Task on Contact, owner = Dispatch queue
STOP The Contact's opt-out field is set at the record level. The flow's decision element blocks every future send for this Contact, including from other flows. Contact.SMS_Opt_Out__c
No reply Nothing happens. The technician arrives as scheduled. The send is still on the record as a Completed Task, so nobody can say the customer was not told. Task, Status = Completed
05 · Guardrails

Four rules the flow checks before it sends.

ConsentThe Contact's opt-out field is checked in the decision element before the send action. A STOP reply sets it. Imported contacts start unconsented.
Quiet hoursThe org-level time window blocks sends before 08:00 or after 20:00 in the recipient's time zone, taken from the Service Territory. An En Route status at 07:40 sends at 08:00.
One per appointmentThe flow's entry condition is Status ISCHANGED, so a status bounced back and forth in the mobile app sends once per change, and a Last_Notified__c timestamp blocks a second send within 30 minutes.
Opt-out lineThe template carries Reply STOP to opt out. It counts toward the 160 characters, and the template preview shows the segment count before you save.
06 · Reporting afterwards

A report on the appointment, not on the messages.

The two checkboxes and the Task records are all standard fields, so the report is a Service Appointments with Tasks report type and a filter. No export, no message log to join.

En route notices · this weekService Appointments with Activities
AppointmentNotifiedReplyOutcome
SA-004821309:142Rescheduled, same day
SA-004821409:311Completed
SA-004821910:02No replyCompleted
SA-004822110:401Completed
SA-004822511:15Free textCompleted, dispatcher replied
SentCount of Tasks with Subject starting SMS: SA_EnRoute, grouped by day.
Moved by replyCount of appointments where Reschedule_Requested__c is true, against total notified. This is the number that replaces the missed visit count.
Cannot CompleteAppointments closed as Cannot Complete with a notice sent, before and after. The delta is the case for the project.
07 · Implementation note

Where ValueText fits.

ValueText is the send action and the inbound handler. It installs from AppExchange as a managed package, adds the Send Message invocable action to Flow Builder, and writes every inbound message as a Message Bucket record and a Task on the related Contact. The template editor, keyword rules and the org-level time window live in ValueText Setup. The two checkboxes, the flows and the report are yours, built with standard tools, and they keep working if you swap the number or the carrier.

Professional edition or above · Field Service not required, any object with a status and a phone works the same way · 1 SMS segment per notice at the published per-country rate
AppExchange review

“Our company was looking for a text application to notify our support team on weekends and holidays. ValueText was by far the simplest and most cost effective application for our needs.”

Renee Pierce Renee PierceSalesforce Admin · AppExchange
This page sits underSMS for SalesforceThe channel page: how sending, receiving and billing work for SMS.
In the docs
01 Add the Send Message action to a record-triggered flowFlow Builder, inputs and the test run → 02 Dynamic templates: merge fields from related objectsReaching Contact and ServiceResource fields from ServiceAppointment → 03 Keyword rules that update a field on the parent recordMatching 1 and 2 inside an appointment window →

Run your messaging inside your CRM.

Rated 4.98 on Salesforce AppExchange