Compare commits

...

2 commits

Author SHA1 Message Date
Christopher Cookman ca51e58108
Bwuh 2024-09-05 11:25:00 -06:00
Christopher Cookman d7fa61679e
Add asset type limit
Add basic logging
2024-09-05 11:20:45 -06:00
2 changed files with 51 additions and 40 deletions

View file

@ -6,6 +6,11 @@ const port = process.env.SERVER_PORT || 3000;
app.use(express.json()); app.use(express.json());
app.set("trust proxy", 1); app.set("trust proxy", 1);
app.use((req, res, next) => {
console.log(`[${new Date().toLocaleString()}] ${req.ip} ${req.method} ${req.url}`);
next();
})
var rateLimits = {}; var rateLimits = {};
@ -14,6 +19,7 @@ app.get("/", (req, res) => {
res.sendFile(__dirname + "/static/index.html") res.sendFile(__dirname + "/static/index.html")
}); });
app.post("/", async (req, res) => { app.post("/", async (req, res) => {
// Impliment a rate limit of 25 requests per minute // Impliment a rate limit of 25 requests per minute
const ip = req.ip; const ip = req.ip;
@ -108,6 +114,7 @@ app.post("/", async (req, res) => {
try { try {
let response = await fetch("https://assetdelivery.roblox.com/v1/assets/batch", options); let response = await fetch("https://assetdelivery.roblox.com/v1/assets/batch", options);
let json = await response.json(); let json = await response.json();
//console.log(JSON.stringify(json, null, 2));
// Build the response object // Build the response object
const responses = req.body.data.reduce((acc, item, index) => { const responses = req.body.data.reduce((acc, item, index) => {
const assetId = item; const assetId = item;
@ -119,6 +126,14 @@ app.post("/", async (req, res) => {
message: codes[errorCode].message, message: codes[errorCode].message,
additional: codes[errorCode].description additional: codes[errorCode].description
}; };
} else if (json[index].assetTypeId !== 3) {
// Return 415, the asset isnt audio
acc[assetId] = {
status: "failure",
code: 415,
message: codes[415].message,
additional: codes[415].description
};
} else { } else {
acc[assetId] = { acc[assetId] = {
status: "success", status: "success",

View file

@ -45,15 +45,11 @@
<body> <body>
<div class="container"> <h1>Roblox Audio Asset API Documentation</h1>
<h1>Roblox Audio Asset API Documentation</h1>
<h2>Endpoint</h2> <h2>Request Format</h2>
<p><strong>URL:</strong> <code>POST /</code></p> <p>The request must be sent as JSON with the following format:</p>
<pre>
<h2>Request Format</h2>
<p>The request must be sent as JSON with the following format:</p>
<pre>
{ {
"type": "batching", "type": "batching",
"data": [ "data": [
@ -65,21 +61,21 @@
} }
</pre> </pre>
<p><strong>Parameters:</strong></p> <p><strong>Parameters:</strong></p>
<ul> <ul>
<li><code>type</code>: The type of the request. Must be <code>"batching"</code>.</li> <li><code>type</code>: The type of the request. Must be <code>"batching"</code>.</li>
<li><code>data</code>: An array of asset IDs that you want to request.</li> <li><code>data</code>: An array of asset IDs that you want to request.</li>
<li><code>cookie</code>: Optional. A <code>.ROBLOSECURITY</code> cookie. If not provided, you will only be <li><code>cookie</code>: Optional. A <code>.ROBLOSECURITY</code> cookie. If not provided, you will only be
able to access public assets. The cookie is used once to make the request to Roblox servers and is then able to access public assets. The cookie is used once to make the request to Roblox servers and is then
discarded permanently. discarded permanently.
You can find more information on obtaining your cookie <a You can find more information on obtaining your cookie <a
href="https://noblox.js.org/tutorial-VPS%20Authentication.html">here!</a></li> href="https://noblox.js.org/tutorial-VPS%20Authentication.html">here!</a></li>
</ul> </ul>
<h2>Rate Limit</h2> <h2>Rate Limit</h2>
<p>There is a limit of 25 requests per minute. If this limit is exceeded, the following error will be returned: <p>There is a limit of 25 requests per minute. If this limit is exceeded, the following error will be returned:
</p> </p>
<pre> <pre>
{ {
"code": 429, "code": 429,
"error": "Rate limit exceeded", "error": "Rate limit exceeded",
@ -87,9 +83,9 @@
} }
</pre> </pre>
<h2>Response Format</h2> <h2>Response Format</h2>
<p>The response will be in JSON format:</p> <p>The response will be in JSON format:</p>
<pre> <pre>
<pre> <pre>
{ {
"type": "batching-response", "type": "batching-response",
@ -107,21 +103,21 @@
} }
} }
</pre> </pre>
</pre> </pre>
<p><strong>Fields:</strong></p> <p><strong>Fields:</strong></p>
<ul> <ul>
<li><code>type</code>: Always <code>"batching-response"</code>.</li> <li><code>type</code>: Always <code>"batching-response"</code>.</li>
<li><code>data</code>: An object where each key is an asset ID and the value contains the result of the <li><code>data</code>: An object where each key is an asset ID and the value contains the result of the
request.</li> request.</li>
<li><code>status</code>: Either <code>"success"</code> or <code>"failure"</code>.</li> <li><code>status</code>: Either <code>"success"</code> or <code>"failure"</code>.</li>
<li><code>url</code>: The location of the asset if the request was successful, or an empty string if it <li><code>url</code>: The location of the asset if the request was successful, or an empty string if it
failed.</li> failed.</li>
<li><code>additional</code>: Any additional information, such as error messages.</li> <li><code>additional</code>: Any additional information, such as error messages.</li>
</ul> </ul>
<h2>Example Request</h2> <h2>Example Request</h2>
<pre> <pre>
POST / POST /
Content-Type: application/json Content-Type: application/json
@ -137,8 +133,8 @@ Content-Type: application/json
} }
</pre> </pre>
<h2>Example Response</h2> <h2>Example Response</h2>
<pre> <pre>
{ {
"type": "batching-response", "type": "batching-response",
"data": { "data": {