# notify

> Show desktop notifications and alert dialogs from a program, on macOS, Linux and Windows.

This is the Markdown version of https://osl-lang.org/packages/notify. Every page of the OSL docs has one: add .md to its path. https://osl-lang.org/llms.txt lists them all.

```osl
import "std:notify"
```

`notify` tells the person at the computer something: a build finished, a download is done, a long job failed. It shows a desktop notification, or a dialog that waits for them.

```osl
import "std:notify"
```

Notifications need a desktop session, so the examples on this page are compiled but not run.

## Send a notification

```osl
import "std:notify"

notify.send("Build finished", "All 42 tests passed").unwrap()
```

`send(title, message)` returns a [result](/learn/errors.md). It uses `osascript` on macOS, `notify-send` on Linux and PowerShell on Windows. Try it on your own machine.

## Check first

Servers and containers have no desktop. `notify.isAvailable()` says whether `send` can work here, so a script can fall back to printing.

```osl
import "std:notify"

def tell(string title, string message) (
  if notify.isAvailable() (
    notify.send(title, message).unwrap()
  ) else (
    log title ++ ": " ++ message
  )
)

tell("Backup", "finished")
```

## Handle failure

Without a check, a failure is an error value you can look at. `UnsupportedError` means this system can't show notifications, `NotFoundError` that the helper program isn't installed (install `libnotify` for `notify-send`), and `RuntimeError` that the helper failed.

```osl
import "std:notify"

switch notify.send("Hello", "from OSL") (
  case ok(_)
    log "sent"
  case err(e)
    log "could not notify:" e.kind
)
```

## A sound on macOS

Pass `sound` with a system sound name. Only macOS supports it, and asking elsewhere is an `UnsupportedError`.

```osl
import "std:notify"

notify.send("Done", "The export is ready", {sound: "Glass"}).unwrap()
```

## Wait for an answer

`notify.alert(title, message)` shows a dialog with an OK button and waits until it is dismissed. Use it when the person must see the message before the program goes on. On Linux it needs `zenity`, and falls back to a notification without it.

```osl
import "std:notify"

notify.alert("Delete everything?", "Press OK to continue.").unwrap()
log "continuing"
```

**Quiz.** Your script runs on a server with no screen. What is the safest way to use `notify`?

- [ ] Call `send` and hope.
- [x] Check `notify.isAvailable()` and print to the console when it is false.
- [ ] Use `alert`, which always works.

Answer: `isAvailable` tells you whether a notification can be shown here at all.

### Exercise: Notify or print

Real notifications can't be recorded here, so practise the decision. Write `route(desktop, message)`: with a desktop it returns `notify: ` and the message, without one it returns `print: ` and the message. Then in your own program, pass it `notify.isAvailable()`.

Starting code:

```osl
import "std:notify"

log "todo"
```

It should print:

```text
notify: build ok
print: build ok
```

Hint 1: A function with an `if` and two `return` lines is enough.

A solution:

```osl
import "std:notify"

def route(boolean desktop, string message) string (
  if desktop return "notify: " ++ message
  return "print: " ++ message
)

log route(true, "build ok")
log route(false, "build ok")
```

## API reference

## API reference

Every member of `std:notify`, generated from the source of OSL.

### Functions

#### `notify.alert(string title, string message) result<unit, error>`

alert shows a dialog with an OK button and waits until it is dismissed,
using osascript on macOS, zenity on Linux (falling back to a
notification when zenity isn't installed) and PowerShell on Windows.
Fails like notify.send.

#### `notify.isAvailable() boolean`

isAvailable reports whether notify.send can work here: the system is
supported and its helper is installed.

#### `notify.send(string title, string message, object? options) result<unit, error>`

send shows a desktop notification, using osascript on macOS, notify-send
on Linux and PowerShell on Windows. Options: sound (string) plays a named
system sound with it, such as "Glass" or "default"; only macOS supports
sounds. Fails with UnsupportedError on other systems or when a sound is
asked for off macOS, NotFoundError when the helper isn't installed, and
RuntimeError when it fails.

#### `notify.sendWithSound(any title, any message, any sound) boolean`

**Deprecated.** Deprecated: use notify.send(title, message, {sound: name}) instead.

sendWithSound shows a notification with a sound on macOS, and without
one elsewhere, and reports whether it worked.
