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

# LB-Scripts

> Configure LB-Phone or LB-Tablet to upload media through FiveMesh CDN.

Use FiveMesh CDN with [LB-Phone](https://lbscripts.com/phone) or [LB-Tablet](https://lbscripts.com/tablet) by configuring a custom upload method.

Use presigned uploads so the script can upload phone or tablet media without exposing your FiveMesh service key to clients.

<Tip>
  If you use both LB-Phone and LB-Tablet, give each script its own CDN path
  prefix such as `/phone` and `/tablet`. You can restrict service keys to those
  prefixes from the FiveMesh dashboard.
</Tip>

## Prerequisites

Before you begin, confirm:

* FiveMesh CDN is set up for the active workspace.
* You have a service key with CDN write access.
* The service key is scoped to the path prefixes the script should manage.
* You can edit the LB-Phone or LB-Tablet server files.

Use these values while configuring the integration:

| Value                           | Description                                                                                    |
| ------------------------------- | ---------------------------------------------------------------------------------------------- |
| `FIVEMESH_PRESIGNED_UPLOAD_URL` | The presigned upload endpoint provided for your FiveMesh workspace or integration environment. |
| `YOUR_API_KEY`                  | A scoped FiveMesh service key.                                                                 |
| `YOUR_CDN_WORKSPACE`            | The CDN workspace name you configured during setup.                                            |
| `file`                          | The upload field name used by LB-Scripts.                                                      |

<Warning>
  Do not configure direct uploads with a permanent API key in client-visible
  files. Keep the service key in server-side LB-Scripts files and return
  presigned upload URLs to the client.
</Warning>

## LB-Phone configuration

To use presigned uploads with LB-Phone, update the server and upload configuration.

<Steps>
  <Step title="Configure server credentials">
    Open `lb-phone/server/apiKeys.lua` and configure the API keys and target path prefixes.

    ```lua theme={null}
    API_KEYS = {
        Video = "YOUR_API_KEY",
        Image = "YOUR_API_KEY",
        Audio = "YOUR_API_KEY",
    }

    UPLOAD_PATHS = {
        Video = "phone/video",
        Image = "phone/images",
        Audio = "phone/audio",
    }
    ```
  </Step>

  <Step title="Request a presigned upload URL">
    Update `lb-phone/server/custom/functions/functions.lua` to implement `GetPresignedUrl`.

    ```lua theme={null}
    function GetPresignedUrl(source, uploadType)
        local apiKey = API_KEYS[uploadType]
        local uploadPath = UPLOAD_PATHS[uploadType]

        if not apiKey then
            infoprint("error", ("[GetPresignedUrl] Invalid uploadType '%s' (missing API key or bucket")):format(uploadType))
            return false
        end

        local p = promise.new()

        PerformHttpRequest(
            ("https://api.fivemesh.io/v1/presigned-url?allowCustomMetadata=true&randomizeName=true&path=%s"):format(uploadPath),
            function(status, body, headers, error)
                if status ~= 201 then
                    infoprint("error", ("[GetPresignedUrl] Request failed for '%s', status: %s"):format(uploadType, status))
                    if error then
                      infoprint("error", "Error: " .. error)
                    end
                    p:resolve(false)
                    return
                end

                local ok, data = pcall(json.decode, body)
                if not ok or not data or not data.success or not data.uploadUrl then
                    infoprint("error", ("[GetPresignedUrl] Invalid response for '%s'"):format(uploadType))
                    p:resolve(false)
                    return
                end

                p:resolve(data.uploadUrl)
            end,
            "GET",
            nil,
            { ["Authorization"] = ("Bearer %s"):format(apiKey) }
        )

        return Citizen.Await(p)
    end
    ```
  </Step>

  <Step title="Use presigned URLs in upload settings">
    In `lb-phone/shared/upload.lua`, set `url` to `"PRESIGNED_URL"` for custom methods.

    ```lua theme={null}
    UploadMethods = {
        Custom = {
            Video = {
                url = "PRESIGNED_URL",
                field = "file",
            },
            Image = {
                url = "PRESIGNED_URL",
                field = "file",
            },
            Audio = {
                url = "PRESIGNED_URL",
                field = "file",
            },
        }
    }
    ```
  </Step>

  <Step title="Return the custom method">
    Confirm `CustomGetUploadMethod` exists in `lb-phone/client/custom/functions/functions.lua`.

    ```lua theme={null}
    ---@param uploadType "Video" | "Image" | "Audio"
    ---@return UploadMethod?
    function CustomGetUploadMethod(uploadType)
        local methods = UploadMethods[Config.UploadMethod[uploadType]]
        if not methods then
            infoprint("error", "Upload methods not found for ", uploadType)
            return
        end

        ---@type UploadMethod?
        local method = methods[uploadType] or methods.Default
        if not method then
            infoprint("error", "Upload method not found for ", uploadType)
            return
        end

        return method
    end
    ```
  </Step>
</Steps>

## LB-Tablet configuration

LB-Tablet uses the same presigned upload pattern.

<Steps>
  <Step title="Configure server credentials">
    Open `lb-tablet/server/apiKeys.lua` and add the same `API_KEYS` and `UPLOAD_PATHS ` values.
  </Step>

  <Step title="Request a presigned upload URL">
    Update `lb-tablet/server/custom/functions/functions.lua` with the same
    `GetPresignedUrl` function used for LB-Phone.
  </Step>

  <Step title="Use presigned URLs in upload settings">
    In `lb-tablet/config/upload.lua`, set `url = "PRESIGNED_URL"` for each custom
    media type.
  </Step>

  <Step title="Return the custom method">
    Confirm `CustomGetUploadMethod` is implemented in `lb-tablet/client/custom/functions/functions.lua`.
  </Step>
</Steps>

## Related pages

* [Set up FiveMesh CDN](/cdn/setup)
* [API keys](/account/api-keys)
* [FiveMesh CDN API](/api-reference/cdn)
