> ## Documentation Index
> Fetch the complete documentation index at: https://docs.roadshop.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Client Exports

> Client-side exports for external resource integration

# Client Exports

RoadPhone Pro provides several client-side exports that allow other resources to interact with the phone system.

## Phone State

### isPhoneOpen

Check if the phone UI is currently open.

```lua theme={null}
local isOpen = exports['roadphone']:isPhoneOpen()
```

<ResponseField name="returns" type="boolean">
  `true` if the phone is currently open, `false` otherwise.
</ResponseField>

***

### isBlocked

Check if the phone is currently blocked (e.g., during certain activities).

```lua theme={null}
local blocked = exports['roadphone']:isBlocked()
```

<ResponseField name="returns" type="boolean">
  `true` if the phone is blocked, `false` otherwise.
</ResponseField>

***

### blockPhone

Block the phone from being used. Useful for situations where phone usage should be disabled.

```lua theme={null}
exports['roadphone']:blockPhone()
```

<ResponseField name="returns" type="boolean">
  Always returns `true`.
</ResponseField>

***

### unblockPhone

Unblock the phone to allow normal usage again.

```lua theme={null}
exports['roadphone']:unblockPhone()
```

<ResponseField name="returns" type="boolean">
  Always returns `false`.
</ResponseField>

***

### togglePhone

Open or close the phone programmatically.

```lua theme={null}
exports['roadphone']:togglePhone()
```

<Note>
  This toggles the phone state - if open it will close, if closed it will open.
</Note>

***

## Phone Information

### getPhoneNumber

Get the phone number of the current player.

```lua theme={null}
local phoneNumber = exports['roadphone']:getPhoneNumber()
```

<ResponseField name="returns" type="string | nil">
  The player's phone number, or `nil` if not available.
</ResponseField>

***

### isFlightmode

Check if flight mode is enabled on the phone.

```lua theme={null}
local flightMode = exports['roadphone']:isFlightmode()
```

<ResponseField name="returns" type="boolean">
  `true` if flight mode is enabled, `false` otherwise.
</ResponseField>

***

### isFlashlight

Check if the phone flashlight is currently active.

```lua theme={null}
local flashlightOn = exports['roadphone']:isFlashlight()
```

<ResponseField name="returns" type="boolean">
  `true` if the flashlight is on, `false` otherwise.
</ResponseField>

***

### isPlayerMuted

Check if the player is currently muted (e.g., in a call).

```lua theme={null}
local muted = exports['roadphone']:isPlayerMuted()
```

<ResponseField name="returns" type="boolean">
  `true` if the player is muted, `false` otherwise.
</ResponseField>

***

## Communication

### sendMessage

Send an SMS message to a phone number.

```lua theme={null}
exports['roadphone']:sendMessage(phoneNumber, message)
```

<ParamField path="phoneNumber" type="string" required>
  The recipient's phone number.
</ParamField>

<ParamField path="message" type="string" required>
  The message content to send.
</ParamField>

<CodeGroup>
  ```lua Example theme={null}
  -- Send a message to a specific number
  exports['roadphone']:sendMessage("1234567", "Hello from my script!")
  ```
</CodeGroup>

***

### startCall

Initiate a phone call to a specific number.

```lua theme={null}
exports['roadphone']:startCall(number, anonym)
```

<ParamField path="number" type="string" required>
  The phone number to call.
</ParamField>

<ParamField path="anonym" type="boolean">
  Whether to make an anonymous call (optional).
</ParamField>

<CodeGroup>
  ```lua Example theme={null}
  -- Start a normal call
  exports['roadphone']:startCall("1234567")

  -- Start an anonymous call
  exports['roadphone']:startCall("1234567", true)
  ```
</CodeGroup>

<Note>
  This export will automatically open the phone if it's not already open.
</Note>

***

### sendMail

Send an email to the current player.

```lua theme={null}
exports['roadphone']:sendMail(mailData)
```

<ParamField path="mailData" type="table" required>
  The email data object.
</ParamField>

<Expandable title="mailData structure">
  <ParamField path="senderMail" type="string" required>
    The sender's email address.
  </ParamField>

  <ParamField path="subject" type="string" required>
    The email subject line.
  </ParamField>

  <ParamField path="message" type="string" required>
    The email body content.
  </ParamField>

  <ParamField path="button" type="table">
    Optional action button.
  </ParamField>
</Expandable>

<CodeGroup>
  ```lua Example theme={null}
  exports['roadphone']:sendMail({
      senderMail = "admin@server.com",
      subject = "Welcome!",
      message = "Welcome to our server. Enjoy your stay!"
  })

  -- With action button
  exports['roadphone']:sendMail({
      senderMail = "mechanic@server.com",
      subject = "Vehicle Ready",
      message = "Your vehicle repairs are complete.",
      button = {
          text = "Claim Vehicle",
          event = "mechanic:claimVehicle",
          data = { vehicleId = 123 }
      }
  })
  ```
</CodeGroup>

***

### sendMailOffline

Send an email to a player by their identifier (works even if offline).

```lua theme={null}
exports['roadphone']:sendMailOffline(identifier, mailData)
```

<ParamField path="identifier" type="string" required>
  The player's identifier (e.g., license or citizenid).
</ParamField>

<ParamField path="mailData" type="table" required>
  The email data object (same structure as `sendMail`).
</ParamField>

<CodeGroup>
  ```lua Example theme={null}
  exports['roadphone']:sendMailOffline("license:abc123", {
      senderMail = "admin@server.com",
      subject = "Important Notice",
      message = "This message will be delivered when you log in."
  })
  ```
</CodeGroup>

***

## Notifications & Dispatches

### sendNotification

Send a notification to the player's phone.

```lua theme={null}
exports['roadphone']:sendNotification(notifydata)
```

<ParamField path="notifydata" type="table" required>
  The notification data object.
</ParamField>

<Expandable title="notifydata structure">
  <ParamField path="apptitle" type="string" required>
    The app name shown in the notification header.
  </ParamField>

  <ParamField path="title" type="string" required>
    The notification title.
  </ParamField>

  <ParamField path="message" type="string" required>
    The notification message content.
  </ParamField>

  <ParamField path="img" type="string">
    Optional image URL for the notification icon.
  </ParamField>
</Expandable>

<CodeGroup>
  ```lua Example theme={null}
  exports['roadphone']:sendNotification({
      apptitle = "My Script",
      title = "Success!",
      message = "Your action was completed successfully.",
      img = "/public/img/Apps/light_mode/settings.webp"
  })
  ```
</CodeGroup>

***

### sendDispatch

Send a dispatch notification to job members.

```lua theme={null}
exports['roadphone']:sendDispatch(message, job, image)
```

<ParamField path="message" type="string" required>
  The dispatch message content.
</ParamField>

<ParamField path="job" type="string" required>
  The job name to send the dispatch to (e.g., "police", "ambulance").
</ParamField>

<ParamField path="image" type="string">
  Optional image URL for the dispatch.
</ParamField>

<CodeGroup>
  ```lua Example theme={null}
  -- Send a police dispatch
  exports['roadphone']:sendDispatch("10-71 Shots Fired at Legion Square", "police")

  -- With image
  exports['roadphone']:sendDispatch("Medical emergency", "ambulance", "https://example.com/image.jpg")
  ```
</CodeGroup>

***

## UI Control

### setHeaderBlack

Set the phone header (status bar) to black or white mode.

```lua theme={null}
exports['roadphone']:setHeaderBlack(boolean)
```

<ParamField path="boolean" type="boolean" required>
  `true` for black header, `false` for white header.
</ParamField>

<Note>
  Useful for apps with light backgrounds that need a dark header for visibility.
</Note>

***

### inputFocus

Control whether keyboard input is captured by NUI or passed to the game.

```lua theme={null}
exports['roadphone']:inputFocus(boolean)
```

<ParamField path="boolean" type="boolean" required>
  `true` to capture input in NUI, `false` to allow game input.
</ParamField>

<Warning>
  Use this carefully - setting to `true` will prevent the player from using game controls.
</Warning>

***

### SendMessageNUI

Send a raw message directly to the phone NUI.

```lua theme={null}
exports['roadphone']:SendMessageNUI(data)
```

<ParamField path="data" type="table" required>
  The data object to send to NUI. Must include an `event` key.
</ParamField>

<CodeGroup>
  ```lua Example theme={null}
  exports['roadphone']:SendMessageNUI({
      event = "customEvent",
      someData = "value"
  })
  ```
</CodeGroup>

<Warning>
  This is an advanced export. Only use if you understand the phone's NUI event system.
</Warning>

***

## Call Management

### acceptCall

Accept the current incoming call. Useful for smartwatch or external call control.

```lua theme={null}
local accepted = exports['roadphone']:acceptCall()
```

<ResponseField name="returns" type="boolean">
  `true` if an incoming call was accepted, `false` if no incoming call exists.
</ResponseField>

***

### declineCall

Decline the current incoming call.

```lua theme={null}
local declined = exports['roadphone']:declineCall()
```

<ResponseField name="returns" type="boolean">
  `true` if an incoming call was declined, `false` if no incoming call exists.
</ResponseField>

***

### endCall

End the current active, incoming, or outgoing call.

```lua theme={null}
local ended = exports['roadphone']:endCall()
```

<ResponseField name="returns" type="boolean">
  `true` if a call was ended, `false` if no call exists.
</ResponseField>

***

### getCallState

Get the current call state including direction, number, mute status, and contact name.

```lua theme={null}
local callState = exports['roadphone']:getCallState()
```

<ResponseField name="returns" type="table">
  `{ state = "idle"|"active"|"incoming"|"outgoing", number = string|nil, isMuted = boolean, contactName = string|nil }`
</ResponseField>

<CodeGroup>
  ```lua Example theme={null}
  local state = exports['roadphone']:getCallState()
  if state.state == "active" then
      print("In call with: " .. (state.contactName or state.number))
      print("Muted: " .. tostring(state.isMuted))
  end
  ```
</CodeGroup>

***

## Phone Data Access

### getContacts

Get all contacts cached on the client.

```lua theme={null}
local contacts = exports['roadphone']:getContacts()
```

<ResponseField name="returns" type="table">
  Array of contact objects.
</ResponseField>

***

### getMessages

Get all messages cached on the client.

```lua theme={null}
local messages = exports['roadphone']:getMessages()
```

<ResponseField name="returns" type="table">
  Array of message objects.
</ResponseField>

***

### getUnreadMessages

Get all unread received messages.

```lua theme={null}
local unread = exports['roadphone']:getUnreadMessages()
```

<ResponseField name="returns" type="table">
  Array of unread message objects (only received messages, not sent).
</ResponseField>

***

### getRecentCalls

Get the recent call history.

```lua theme={null}
local calls = exports['roadphone']:getRecentCalls()
```

<ResponseField name="returns" type="table">
  Array of recent call objects.
</ResponseField>

***

### getFavouriteContacts

Get all contacts marked as favourites.

```lua theme={null}
local favourites = exports['roadphone']:getFavouriteContacts()
```

<ResponseField name="returns" type="table">
  Array of contact objects where `favourite == 1`.
</ResponseField>

***

### getNotes

Get the player's notes (requires RoadWatch).

```lua theme={null}
local notes = exports['roadphone']:getNotes()
```

<ResponseField name="returns" type="table | nil">
  Array of note objects, or `nil` if RoadWatch is disabled.
</ResponseField>

***

### getBankTransactions

Get the bank transaction history cached on the client.

```lua theme={null}
local transactions = exports['roadphone']:getBankTransactions()
```

<ResponseField name="returns" type="table">
  Array of bank transaction objects.
</ResponseField>

***

### getBankIban

Get the player's bank IBAN.

```lua theme={null}
local iban = exports['roadphone']:getBankIban()
```

<ResponseField name="returns" type="string">
  The player's bank IBAN string.
</ResponseField>

***

### getWeather

Get the most recent weather data.

```lua theme={null}
local weather = exports['roadphone']:getWeather()
```

<ResponseField name="returns" type="table | nil">
  The last weather data object, or `nil` if not yet received.
</ResponseField>

***

## Music Control

<Note>
  These exports are designed for RoadWatch (smartwatch) integration but can be used by any external resource.
</Note>

### getMusicState

Get the current music playback state.

```lua theme={null}
local state = exports['roadphone']:getMusicState()
```

<ResponseField name="returns" type="table">
  `{ isPlaying = bool, isPaused = bool, title = string|nil, artist = string|nil, image = string|nil, length = number, current = number, lengthFormatted = string, currentFormatted = string, volume = number, isRadio = bool }`
</ResponseField>

<CodeGroup>
  ```lua Example theme={null}
  local music = exports['roadphone']:getMusicState()
  if music.isPlaying then
      print("Now playing: " .. (music.title or "Unknown") .. " by " .. (music.artist or "Unknown"))
      print("Volume: " .. music.volume .. "%")
  end
  ```
</CodeGroup>

***

### watchPauseMusic

Pause the currently playing music.

```lua theme={null}
local paused = exports['roadphone']:watchPauseMusic()
```

<ResponseField name="returns" type="boolean">
  `true` if pause command was sent, `false` if no music playing or already paused.
</ResponseField>

***

### watchResumeMusic

Resume paused music.

```lua theme={null}
local resumed = exports['roadphone']:watchResumeMusic()
```

<ResponseField name="returns" type="boolean">
  `true` if resume command was sent, `false` if not playing or not paused.
</ResponseField>

***

### watchNextSong

Skip to the next song (disabled for radio).

```lua theme={null}
local skipped = exports['roadphone']:watchNextSong()
```

<ResponseField name="returns" type="boolean">
  `true` if next command was sent, `false` if not playing or is radio.
</ResponseField>

***

### watchPreviousSong

Go to the previous song (disabled for radio).

```lua theme={null}
local skipped = exports['roadphone']:watchPreviousSong()
```

<ResponseField name="returns" type="boolean">
  `true` if previous command was sent, `false` if not playing or is radio.
</ResponseField>

***

### watchSetVolume

Set the music playback volume.

```lua theme={null}
local success = exports['roadphone']:watchSetVolume(volume)
```

<ParamField path="volume" type="number" required>
  Volume level between 0 and 100.
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if volume was set, `false` if invalid volume.
</ResponseField>

***

### watchPlaySong

Play a specific song by its metadata.

```lua theme={null}
local success = exports['roadphone']:watchPlaySong(song)
```

<ParamField path="song" type="table" required>
  Song data object.
</ParamField>

<Expandable title="song structure">
  <ParamField path="id" type="string" required>
    The song ID.
  </ParamField>

  <ParamField path="url_type" type="string">
    The URL type (e.g., `'youtube'`).
  </ParamField>

  <ParamField path="title" type="string">
    The song title.
  </ParamField>

  <ParamField path="artist" type="string">
    The artist name.
  </ParamField>

  <ParamField path="thumbnail" type="string">
    Thumbnail image URL.
  </ParamField>

  <ParamField path="length" type="string">
    Song duration.
  </ParamField>
</Expandable>

<ResponseField name="returns" type="boolean">
  `true` if play command was sent, `false` if song data is invalid or missing `id`.
</ResponseField>

***

## Health Tracking

<Note>
  These exports return client-side simulated health data. The health system must be enabled in the config.
</Note>

### getClientHealthData

Get all current client-side health data.

```lua theme={null}
local health = exports['roadphone']:getClientHealthData()
```

<ResponseField name="returns" type="table">
  `{ steps = number, distance = number, calories = number, activeMinutes = number, heartRate = number, stress = number, bloodPressure = { systolic = number, diastolic = number }, spo2 = number, isSleeping = boolean }`
</ResponseField>

<CodeGroup>
  ```lua Example theme={null}
  local health = exports['roadphone']:getClientHealthData()
  print("Steps: " .. health.steps)
  print("Heart Rate: " .. health.heartRate .. " bpm")
  print("Stress: " .. health.stress .. "%")
  print("SpO2: " .. health.spo2 .. "%")
  ```
</CodeGroup>

***

### getClientHeartRate

Get the player's current simulated heart rate.

```lua theme={null}
local heartRate = exports['roadphone']:getClientHeartRate()
```

<ResponseField name="returns" type="number">
  Current heart rate in bpm (range: 50-200).
</ResponseField>

***

### getClientStress

Get the player's current simulated stress level.

```lua theme={null}
local stress = exports['roadphone']:getClientStress()
```

<ResponseField name="returns" type="number">
  Current stress level (0-100).
</ResponseField>

***

### getClientSteps

Get the player's accumulated step count for this session.

```lua theme={null}
local steps = exports['roadphone']:getClientSteps()
```

<ResponseField name="returns" type="number">
  Total steps walked/run this session.
</ResponseField>
