Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.leaf7.fun/llms.txt

Use this file to discover all available pages before exploring further.

L7_SEND_WEBHOOK

The L7_SEND_WEBHOOK macro lets you fire Discord webhooks directly from your Lua scripts — without ever exposing your webhook URL to the client. The URL and payload template are stored securely on the server; only the evaluated variables are sent by the client.
Webhook URLs never leave the server. The client only sends variable values — the server assembles and fires the real webhook.

How it works

Defining a webhook in your source

The macro takes exactly two arguments:
  1. The webhook URL (must be a string literal).
  2. The Discord JSON payload (as a Lua table).
You can use standard Lua string concatenation (..) or direct variable references inside the table. Leaf7’s preprocessor automatically detects these variables, stores the template with placeholders on the server, and sets up the client to only send the variable values.
local player = game.Players.LocalPlayer
local kills = 15

L7_SEND_WEBHOOK(
    "https://discord.com/api/webhooks/1234567890/abcdefg",
    {
        content = "Webhook triggered!",
        embeds = {
            {
                title = "Player Activity",
                description = "Player " .. player.Name .. " just loaded the script.",
                color = 0x22C55E,
                fields = {
                    { name = "Kills", value = tostring(kills), inline = true },
                    { name = "JobId", value = game.JobId, inline = false }
                }
            }
        }
    }
)
Behind the scenes, Leaf7 strips the URL and the table structure out of your script entirely. It replaces the block with a secure stub that only transmits { "player.Name": "...", "kills": "15", "game.JobId": "..." } to the server.

Server-Side Variables

You can inject trusted data directly on the server by using %VARIABLE% strings in your template. The client cannot spoof these values:
VariableDescription
%CLIENT_IP%The client’s IP address
%USER_KEY%The script key used for authentication
%DISCORD_ID%The Discord ID linked to the key
%USER_NOTE%The note set on the buyer key
Example:
L7_SEND_WEBHOOK(
    "https://discord.com/api/webhooks/...",
    {
        content = "Script executed by Discord ID: %DISCORD_ID%"
    }
)

Input Sanitization (L7_SANITIZE)

To prevent users from injecting malicious content (like @everyone pings or malicious links) into your webhooks via variable manipulation, use the inline L7_SANITIZE(expression, "regex") macro. If a variable fails to match the provided regex, the server blocks the webhook entirely.
L7_SEND_WEBHOOK(
    "https://discord.com/api/webhooks/...",
    {
        embeds = {
            {
                title = "Item Dropped",
                -- Only allow alphanumeric characters and underscores in the player name
                description = "Dropped by: " .. L7_SANITIZE(player.Name, "^[%w_]+$"),
                
                -- Only allow digits for the score
                footer = { text = "Score: " .. L7_SANITIZE(tostring(score), "^%d+$") }
            }
        }
    }
)

Multiple webhooks

Each project supports up to 6 webhook slots (0-5). You can just call L7_SEND_WEBHOOK multiple times in your script; Leaf7 automatically assigns a slot ID to each call.
-- Slot 0: Execution notification
L7_SEND_WEBHOOK("https://discord.com/api/webhooks/channel1/...", {
    embeds = {{ title = "Script Loaded", color = 0x22C55E }}
})

-- Slot 1: Kill feed
L7_SEND_WEBHOOK("https://discord.com/api/webhooks/channel2/...", {
    embeds = {{ title = "Player Killed: " .. target.Name, color = 0xFF0000 }}
})

Rate limits

The webhook relay enforces a rate limit (typically 30 requests per minute per IP). Exceeding this returns 429 Too Many Requests.
Debounce your webhook calls in Lua if they’re triggered by frequent events (like kills or item pickups) to avoid hitting the rate limit.