njmango / sales-bot

0 stars 2 forks source link

Pull items from API #12

Open mcmcford opened 2 months ago

mcmcford commented 2 months ago

Pulling all the items from the API on startup / at a regular interval will make the bot much more robust to game changes such as new items being added.

https://www.simcompanies.com/api/v2/market-ticker/0/<ISO date>/ can be used to get lowest exchange price, item IDs and item pictures. From the item pictures paths, the names can likely be derived. There is also likely a better endpoint to use for this usecase

mcmcford commented 2 months ago

The easiest place to get items full names and ids from seems to be the language file https://d1fxy698ilbz6u.cloudfront.net/static/js/lang6/en.json

This clearly also avoids issue of item picture names not matching the items actual name, examples of which are below

aero research Gold watch Solid rocket Simmi shoes Pizza

  "be-re-1": "Power",
  "be-re-2": "Water",
  "be-re-3": "Apples",
  "be-re-4": "Oranges",
  "be-re-5": "Grapes",
  "be-re-6": "Grain",
  "be-re-7": "Steak",
  "be-re-8": "Sausages",
  "be-re-9": "Eggs",
  "be-re-10": "Crude oil",
  "be-re-11": "Petrol",
  "be-re-12": "Diesel",
  "be-re-13": "Transport",
  "be-re-14": "Minerals",
  "be-re-15": "Bauxite",
  "be-re-16": "Silicon",
  "be-re-17": "Chemicals",
  "be-re-18": "Aluminium",
  "be-re-19": "Plastic",
  "be-re-20": "Processors",
  "be-re-21": "Electronic components",
  "be-re-22": "Batteries",
  "be-re-23": "Displays",
  "be-re-24": "Smart phones",
  "be-re-25": "Tablets",
  "be-re-26": "Laptops",
  "be-re-27": "Monitors",
  "be-re-28": "Televisions",
  "be-re-29": "Plant research",
  "be-re-30": "Energy research",
  "be-re-31": "Mining research",
  "be-re-32": "Electronics research",
  "be-re-33": "Breeding research",
  "be-re-34": "Chemistry research",
  "be-re-35": "Software",
  "be-re-40": "Cotton",
  "be-re-41": "Fabric",
  "be-re-42": "Iron ore",
  "be-re-43": "Steel",
  "be-re-44": "Sand",
  "be-re-45": "Glass",
  "be-re-46": "Leather",
  "be-re-47": "On-board computer",
  "be-re-48": "Electric motor",
  "be-re-49": "Luxury car interior",
  "be-re-50": "Basic interior",
  "be-re-51": "Car body",
  "be-re-52": "Combustion engine",
  "be-re-53": "Economy e-car",
  "be-re-54": "Luxury e-car",
  "be-re-55": "Economy car",
  "be-re-56": "Luxury car",
  "be-re-57": "Truck",
  "be-re-58": "Automotive research",
  "be-re-59": "Fashion research",
  "be-re-60": "Underwear",
  "be-re-61": "Gloves",
  "be-re-62": "Dress",
  "be-re-63": "Stiletto Heel",
  "be-re-64": "Handbags",
  "be-re-65": "Sneakers",
  "be-re-66": "Seeds",
  "be-re-67": "Xmas crackers",
  "be-re-68": "Gold ore",
  "be-re-69": "Golden bars",
  "be-re-70": "Luxury watch",
  "be-re-71": "Necklace",
  "be-re-72": "Sugarcane",
  "be-re-73": "Ethanol",
  "be-re-74": "Methane",
  "be-re-75": "Carbon fibers",
  "be-re-76": "Carbon composite",
  "be-re-77": "Fuselage",
  "be-re-78": "Wing",
  "be-re-79": "High grade e-comps",
  "be-re-80": "Flight computer",
  "be-re-81": "Cockpit",
  "be-re-82": "Attitude control",
  "be-re-83": "Rocket fuel",
  "be-re-84": "Propellant tank",
  "be-re-85": "Solid fuel booster",
  "be-re-86": "Rocket engine",
  "be-re-87": "Heat shield",
  "be-re-88": "Ion drive",
  "be-re-89": "Jet engine",
  "be-re-90": "Sub-orbital 2nd stage",
  "be-re-91": "Sub-orbital rocket",
  "be-re-92": "Orbital booster",
  "be-re-93": "Starship",
  "be-re-94": "BFR",
  "be-re-95": "Jumbo jet",
  "be-re-96": "Luxury jet",
  "be-re-97": "Single engine plane",
  "be-re-98": "Quadcopter",
  "be-re-99": "Satellite",
  "be-re-100": "Aerospace research",
  "be-re-101": "Reinforced concrete",
  "be-re-102": "Bricks",
  "be-re-103": "Cement",
  "be-re-104": "Clay",
  "be-re-105": "Limestone",
  "be-re-106": "Wood",
  "be-re-107": "Steel beams",
  "be-re-108": "Planks",
  "be-re-109": "Windows",
  "be-re-110": "Tools",
  "be-re-111": "Construction units",
  "be-re-112": "Bulldozer",
  "be-re-113": "Materials research",
  "be-re-114": "Robots",
  "be-re-115": "Cows",
  "be-re-116": "Pigs",
  "be-re-117": "Milk",
  "be-re-118": "Coffee beans",
  "be-re-119": "Coffee powder",
  "be-re-120": "Vegetables",
  "be-re-121": "Bread",
  "be-re-122": "Cheese",
  "be-re-123": "Apple pie",
  "be-re-124": "Orange juice",
  "be-re-125": "Apple cider",
  "be-re-126": "Ginger beer",
  "be-re-127": "Frozen pizza",
  "be-re-128": "Pasta",
  "be-re-129": "Hamburger",
  "be-re-130": "Lasagna",
  "be-re-131": "Meat balls",
  "be-re-132": "Cocktails",
  "be-re-133": "Flour",
  "be-re-134": "Butter",
  "be-re-135": "Sugar",
  "be-re-136": "Cocoa",
  "be-re-137": "Dough",
  "be-re-138": "Sauce",
  "be-re-139": "Fodder",
  "be-re-140": "Chocolate",
  "be-re-141": "Vegetable oil",
  "be-re-142": "Salad",
  "be-re-143": "Samosa",
  "be-re-144": "Xmas ornament",
  "be-re-145": "Recipes",
mcmcford commented 2 months ago

Successfully implemented in slash commands branch d49c746384ef8e17b17174db42d4ce41a2cd6e94

async function getAllItems(){

    logToFileAndConsole("Fetching all items...");

    const url = `https://d1fxy698ilbz6u.cloudfront.net/static/js/lang6/en.json`;
    let items = {};

    try {
        const response = await fetch(url);

        if (response.status === 429) {
            logToFileAndConsole("Rate limit exceeded. Waiting 62 seconds and trying again...");
            // wait 62 seconds and try again
            await new Promise(resolve => setTimeout(resolve, 62000));
            return getAllItems();
        } else if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();

        // loop through all the keys and their values in the dictionary
        for (const [key, value] of Object.entries(data)) {
            // check if the key matches the regex be-re-\d{1,3}
            const regex = /be-re-\d{1,3}/;

            if (regex.test(key)) {
                // split the key by "be-re-"
                const splitKey = key.split("be-re-");
                const itemID = parseInt(splitKey[1]);
                const item = value;

                // add the item to the items dictionary
                items[itemID] = item;
            }
        }

        return items;
    } catch (error) {
        console.error(`Failed to fetch items: ${error}`);
        return null;
    }

}