Initial commit

This commit is contained in:
Walter 2025-03-09 21:50:50 +01:00
commit 0a2c48424e
7 changed files with 123 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
config.json
.venv
venv
.idea

11
app.py Normal file
View File

@ -0,0 +1,11 @@
import json
from methods.economy_v1 import EconomyV1
def run():
with open("config.json") as f:
config = json.load(f)
EconomyV1(roblosecurity=config["user"]["roblosecurity"],
asset_id=config["item"]["asset_id"]).buy()

8
config_example.json Normal file
View File

@ -0,0 +1,8 @@
{
"user": {
"roblosecurity": ""
},
"item": {
"asset_id": 114702108643191
}
}

43
methods/base.py Normal file
View File

@ -0,0 +1,43 @@
import logging
import time
import traceback
import requests
from fake_useragent import UserAgent
class Purchaser:
base_headers = {
"User-Agent": UserAgent().chrome
}
def __init__(self, roblosecurity):
self.roblosecurity = roblosecurity
self.base_cookies = {".ROBLOSECURITY": self.roblosecurity}
self.logger = logging.getLogger(__name__)
def request(self, url, method=requests.get, attempts=10, timeout=20, *args, **kwargs):
if "headers" not in kwargs:
kwargs["headers"] = {}
if "cookies" not in kwargs:
kwargs["cookies"] = {}
kwargs["headers"] = {**self.base_headers, **kwargs["headers"]}
kwargs["cookies"] = {**self.base_cookies, **kwargs["cookies"]}
for attempt in range(attempts):
try:
r = method(url=url, timeout=timeout, *args, **kwargs)
if 500 > r.status_code > 600:
print(f"Statuscode {r.status_code} for {url}...")
time.sleep(5)
continue
return r
except requests.RequestException:
traceback.print_exc()
time.sleep(5)
def get_asset_metadata(self, asset_id):
return self.request(url=f"https://catalog.roblox.com/v1/catalog/items/{asset_id}/details",
params={"itemType": "asset"}).json()

47
methods/economy_v1.py Normal file
View File

@ -0,0 +1,47 @@
import json
import requests
from bs4 import BeautifulSoup
from methods.base import Purchaser
class EconomyV1(Purchaser):
def __init__(self,
asset_id: int,
*args,
**kwargs):
super().__init__(*args, **kwargs)
self.asset_id = asset_id
def buy(self):
meta = self.get_asset_metadata(asset_id=self.asset_id)
item_type = meta["itemType"]
product_id = meta["productId"]
collectible_id = meta["collectibleItemId"]
# TODO check if we need special handling for groups
creator_target_id = meta["creatorTargetId"] # UserID / ?
url = f"https://www.roblox.com/{'bundles' if item_type == 'Bundle' else 'catalog'}/{self.asset_id}"
r = self.request(url=url)
soup = BeautifulSoup(r.text, "html.parser")
csrf_token = soup.find("meta", {"name": "csrf-token"})["data-token"]
r = self.request(url=f"https://economy.roblox.com/v1/purchases/products/{product_id}",
method=requests.post,
cookies=r.cookies,
headers={
"x-csrf-token": csrf_token,
"Content-Type": "application/json; charset=utf-8",
},
json={
"expectedCurrency": 1,
"expectedPrice": 0,
"expectedSellerId": creator_target_id
})
data = r.json()
print(data, r.headers)

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
requests
bs4
fake-useragent

7
start.py Normal file
View File

@ -0,0 +1,7 @@
import logging
import app
if __name__ == "__main__":
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
app.run()