# Webhook Protection

Luarmor now offers an advanced webhook protection macro that you can use inside your script to prevent people from deleting, spamming or nuking your webhooks.

{% hint style="info" %}
This feature is available in V4 loader scripts only. So make sure you enable the **"Prefer V4 loader"** option on dashboard while editing / creating a script.

<img src="https://3136584356-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwOpQH2LpMjsOwgeFM5gE%2Fuploads%2FYSdQ4dqYWrDObZa8DDLi%2Fimage.png?alt=media&#x26;token=d8d59a63-7a19-49b2-80bc-935b796414fc" alt="" data-size="original">
{% endhint %}

{% hint style="warning" %}
Executions must be made with a valid **script\_key** in order to use this macro, if the execution is made without a key, (*e.g FFA script*), webhook message will not be delivered.
{% endhint %}

## How to implement it in your script:

It is a macro, it means that you must include it in your script when you want to make a secure webhook request. \
\
Syntax: **`LRM_SEND_WEBHOOK(<url constant>, <webhook template>)`**

It takes 2 arguments, first argument is a constant string literal that contains the webhook URL. Second argument is a constant table literal, containing the JSON payload of your webhook message.\
**Do not** pass variables as arguments, it won't work. They must be constant.\
\
There is also a sanitization macro, so people don't spoof the values coming from their client. \
Syntax: `LRM_SANITIZE(<any>, <regex string literal>)`

Sanitize macro takes 2 arguments too. First one could be anything, variable, function call etc. Second argument must be a regex string **without** the / symbols at the start & end, and **without** anchors (^ / $).\
E.g `LRM_SANITIZE(plrname, "[a-zA-Z0-9_]{3, 40}")`

### Example usage:

{% code overflow="wrap" %}

```lua
if bounty > 45000 then
    -- Send high bounty player to webhook.
    LRM_SEND_WEBHOOK( "https://discord.com/api/webhooks/......", {
        username = "Cat Delivery",
        embeds = {
            { 
              title = "High bounty user detected!",
              description = "Bounty: " .. LRM_SANITIZE(bounty, "[0-9]{1,6}"),
              color = 16711680, -- red
              
              fields = {
                  {
                      name = "Player Name:",
                      value = LRM_SANITIZE(plrName, "[a-zA-Z0-9_]{3,40}"),
                      inline = true
                  },
                  {
                      name = "Caught by:",
                      value = "<@%DISCORD_ID%>", -- Server-side variable, see below
                      inline = true
                  }
              }
            }
        }
    });
    
    print("Webhook sent!")
end
```

{% endcode %}

This code will safely send high-bounty players in some game and their names, with server-side regex sanitizations & server sided template rendering.\
\
Client only provides the "bounty" and "plrName" variables. Everything else happens on the server, client never knows.&#x20;

{% hint style="info" %}
However, there is no guarantee that the webhook messages will be 100% delivered, webhook could get ratelimited, user could get ratelimited, user might use a script to prevent these requests.
{% endhint %}

{% hint style="danger" %}
It is recommended that you always use LRM\_SANITIZE inside a webhook template, and wrap user-specified values in them. Otherwise, user can change their values with no server sided validation. \
\
**What to avoid:**

```lua
LRM_SEND_WEBHOOK("https....", {
    content = "Rank is " .. userRank -- userRank is not validated.
});
```

\
This is technically valid, and Luarmor supports it. However, it is discouraged due to the fact that user can change the value with enough effort, and server will not validate it.\
\
✅ **Instead, use this:**

```lua
LRM_SEND_WEBHOOK("https....", {
    content = "Rank is " .. LRM_SANITIZE(userRank, "(Gold|Silver|Dog)") 
});
```

{% endhint %}

## Server-side Variables:

You can also use certain server-side variables, wrapped between % % in your template strings. They will get replaced at the server, and **can not be** spoofed / changed by user.<br>

Here is a list:&#x20;

| Variable        | What is it?                                                   | Example value               |
| --------------- | ------------------------------------------------------------- | --------------------------- |
| %DISCORD\_ID%   | Discord ID of the user sending the webhook request.           | 11024175100150935723        |
| %COUNTRY\_CODE% | 2 letter country code of the user IP at the time of execution | gb                          |
| %USER\_KEY%     | script\_key value                                             | SjZvGboZMJt .... (32 chars) |
| %CLIENT\_IP%    | IP v4/v6 of the user at the time of execution                 | 48.72.104.256               |
| %USER\_NOTE%    | Note, if the key has any.                                     | Not Specified               |

You include them in the constant strings in the template, like:

```lua
LRM_SEND_WEBHOOK("https....", {
    content = "User ran!\nDetails: \nIP: `%CLIENT_IP%` :flag_%COUNTRY_CODE%:"
});
```

{% hint style="warning" %}
While there is no strict rule about IP logging, **you must inform your users** if you are logging any sensitive information including IP.
{% endhint %}

## Restrictions:

{% hint style="info" %}
Requires a script\_key'ed execution, FFA scripts without a script\_key will not have their webhooks sent.
{% endhint %}

{% hint style="info" %}
IP based 30 req/min ratelimit. Only send webhooks when needed.
{% endhint %}

{% hint style="info" %}
Max 3 embeds per message, and max 6 protected webhooks in 1 script. If you are re-using the same template, just create a function instead.
{% endhint %}

{% hint style="info" %}
JSON Serialized payload must not exceed 7000 characters, don't send too large payloads.
{% endhint %}

{% hint style="success" %}
**Need help with regex filters? Use** [**https://regex101.com/**](https://regex101.com/) **to test it, or ask ChatGPT with this prompt:**

{% code overflow="wrap" %}

```
I am using a Lua function macro that takes 2 arguments, 1 variable and 2 regex.
Regex must be a JS regex, without the / at the start & end, and without the anchors (^ and $).
The service I'm using already adds those for me. Assume the flag is only 's'.
Here is an example: LRM_SANITIZE(varExpr, "[a-zA-Z0-9_]{2,30}") 
Follow this syntax, and give me a regex based on my requirements which I will tell you now.
```

{% endcode %}
{% endhint %}

<figure><img src="https://3136584356-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwOpQH2LpMjsOwgeFM5gE%2Fuploads%2Fm9FonljEyHW8uHAmYc53%2Fimage.png?alt=media&#x26;token=2bc1e47a-327a-49b7-8de8-f6263cefa827" alt=""><figcaption></figcaption></figure>
