> For the complete documentation index, see [llms.txt](https://docs.agilecase.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.agilecase.com/developer-documentation/case-scripting/on-save-scripts/examples/sending-an-sms-with-an-email-fallback.md).

# Sending an SMS With an Email Fallback

A text message is often the fastest way to reach somebody, but only if you hold a mobile number that works. A script that texts blindly will appear to succeed while reaching nobody. Checking the number first, and emailing the office when it fails, turns a silent miss into something a person can act on.

## The scenario

A school records an unexplained absence. If a usable mobile number is held for the first contact, the parent is texted. If not, the office is emailed so somebody can chase the number.

| Setting        | Value                                                |
| -------------- | ---------------------------------------------------- |
| Trigger field  | `5204` Unexplained absence (date)                    |
| Read           | `5205` Sessions missed today, `5206` Parent 1 mobile |
| SMS template   | `Absence-Parent`                                     |
| Email fallback | `NoParentMobile`                                     |

## The script

```javascript
[Changed.CustomField(5204).Changed]

function after_save() {
    var absenceDate = Changed.CustomField("5204").NewValueAsText;
    var sessionsMissed = parseFloat(Service.CustomField("5205").ValueAsText);
    var mobile = Service.CustomField("5206").ValueAsText;

    if (absenceDate === "") {
        Service.AddMessage("The absence date was cleared, so no message was sent.", "notify-info");
        return true;
    }

    if (isNaN(sessionsMissed) || sessionsMissed <= 0) {
        Service.AddMessage("No sessions were missed, so no absence message was sent.", "notify-info");
        return true;
    }

    var mobileLooksUsable = mobile.substring(0, 2) == "07" && mobile.length == 11;

    if (mobileLooksUsable) {
        Service.SendSMS("Absence-Parent");
        Service.AddMessage("An absence text has been sent to the parent.", "notify-success");
    } else {
        Service.SendEmail("NoParentMobile");
        Service.AddMessage("No usable mobile number is held, so the office has been emailed instead.", "warn");
    }

    return true;
}
```

## Ruling out the cases that need nothing

The two checks at the top handle the saves that should produce no message at all. Clearing the absence date still counts as a change and still triggers the script, so without the first check a correction would text the parent about an absence that had just been removed. The second check covers an absence recorded with no sessions actually missed.

Both return early with a brief notification rather than in silence. The person saving the case gets told why nothing happened, which saves them wondering whether the script ran.

## Checking the number

```javascript
var mobileLooksUsable = mobile.substring(0, 2) == "07" && mobile.length == 11;
```

This is a deliberately narrow test for a UK mobile written as eleven digits beginning `07`. It is enough to catch the common problems, which are an empty field, a landline, and a number somebody has half-typed.

It will reject numbers that would in fact work, such as one stored in `+447` form or written with spaces. If your numbers are not entered consistently, strip the spaces before testing, and decide whether to accept the international form as well:

```javascript
var digits = mobile.replace(/\s/g, "");
var mobileLooksUsable = (digits.substring(0, 2) == "07" && digits.length == 11)
    || (digits.substring(0, 5) == "+4470" && digits.length == 13);
```

## Why the failure is a dialog

The success path uses `notify-success`, which appears briefly in the corner and fades. The failure path uses `warn`, which opens a dialog the user has to dismiss.

That difference is the point. A text that went out needs no acknowledgement, but a missing mobile number is a gap in the record that somebody should notice now rather than find later. Reserve dialogs for the cases that genuinely need a person to stop, and use notifications for everything else, or users will start dismissing dialogs without reading them.

{% hint style="info" %}
SMS templates hold their own recipient, so the script names the template and the template decides which number to use. The check in the script has to read the same field the template sends to, which is worth confirming when you set this up. See the [Script API Reference](/developer-documentation/case-scripting/on-save-scripts/script-api-reference.md) for `SendSMS`.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.agilecase.com/developer-documentation/case-scripting/on-save-scripts/examples/sending-an-sms-with-an-email-fallback.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
