From f9cff81d733ea52dca47b495d7564acb4cc7ff2e Mon Sep 17 00:00:00 2001 From: wlft <100052562+wlft@users.noreply.github.com> Date: Sun, 27 Sep 2026 20:38:04 +1000 Subject: [PATCH] feat: migrate all modules from ED to apiunto --- .../GroupInfobox/GroupInfobox.module.luau | 76 ++----- .../ObbyGameInfobox.module.luau | 200 ++---------------- .../PlayerInfobox/PlayerInfobox.module.luau | 26 ++- .../RobloxBadgesV1/RobloxBadges.module.luau | 51 ++--- .../RobloxBadgesV2/RobloxBadgesV2.module.luau | 42 ++-- .../RobloxGamePasses.module.luau | 48 ++--- 6 files changed, 124 insertions(+), 319 deletions(-) diff --git a/modules/obbywiki.com/GroupInfobox/GroupInfobox.module.luau b/modules/obbywiki.com/GroupInfobox/GroupInfobox.module.luau index 2f42274..b766057 100644 --- a/modules/obbywiki.com/GroupInfobox/GroupInfobox.module.luau +++ b/modules/obbywiki.com/GroupInfobox/GroupInfobox.module.luau @@ -28,6 +28,19 @@ local function page_exists(page_title) return title and title.exists end +local apiunto = mw.ext.Apiunto + +local function fetch_json(source, uri, args) + local raw = apiunto.fetch(source, uri, args) + if type(raw) ~= 'string' or raw == '' or raw == 'Could not retrieve API Data' then return nil, raw or 'no response' end + + local ok, decoded = pcall(mw.text.jsonDecode, raw) + if not ok or type(decoded) ~= 'table' then return nil, 'invalid JSON' end + + return decoded +end + + local smm = { twitter = { @@ -210,31 +223,12 @@ function GroupInfobox.main( frame ) local thumb = args.image or args.thumbnail or args.thumb - -- - - -- local universe_id - - -- local _, res = pcall(function() - -- return mw.ext.externalData.getExternalData{ - -- url = 'https://apis.roblox.com/universes/v1/places/' .. obby_starter_place_id .. '/universe', - -- format = 'json' - -- }; - -- end) - - -- universe_id = res and res.__json and res.__json.universeId - - - --- - if group_id then - local group_res = mw.ext.externalData.getExternalData{ - url = 'https://groups.roblox.com/v1/groups/'.. tostring(group_id), - format = 'json' - } - - local group_json = group_res and group_res.__json - local row = group_json - mw.log(group_res, row) + local s, row = pcall(fetch_json, 'RobloxGroups', 'v1/groups/' .. tostring(group_id)) + if not s then + row = nil + end + mw.log(row) if row and row.owner then local c = row.owner @@ -281,40 +275,6 @@ function GroupInfobox.main( frame ) end end - -- local s2, universe_data = pcall(function() - -- return mw.ext.externalData.getExternalData{ - -- data = { - -- creator_name = 'json.data[0].creator.name', - -- creator_id = 'json.data[0].creator.id', - -- is_verified = 'json.data[0].creator.hasVerifiedBadge' - -- }, - -- url = 'https://games.roblox.com/v1/games?universeIds=' .. universe_id, - -- format = 'json', - -- } - -- end) - - -- if s2 and universe_data then - -- if universe_data.creator_name then - -- obby_developer = universe_data.creator.name or obby_developer - - -- if universe_data.is_verified == 'true' or universe_data.is_verified == true then obby_developer = obby_developer .. ' [[File:Roblox_Verification_Badge.svg|12px|link=|alt=Verified]]' end - -- end - -- end - - -- local universe - - -- if universe_id then - -- local universe_data = mw.ext.externalData.getExternalData{ - -- url = 'https://games.roblox.com/v1/games?universeIds=' .. universe_id - -- } - - -- universe = universe_data and universe_data[1] - - -- if universe then - -- obby_developer = universe.creator and universe.creator.name or obby_developer - -- end - -- end - --- diff --git a/modules/obbywiki.com/ObbyGameInfobox/ObbyGameInfobox.module.luau b/modules/obbywiki.com/ObbyGameInfobox/ObbyGameInfobox.module.luau index 2e836fb..58e468f 100644 --- a/modules/obbywiki.com/ObbyGameInfobox/ObbyGameInfobox.module.luau +++ b/modules/obbywiki.com/ObbyGameInfobox/ObbyGameInfobox.module.luau @@ -44,6 +44,18 @@ local function format_with_total(value, total) return value or '' end +local apiunto = mw.ext.Apiunto + +local function fetch_json(source, uri, args) + local raw = apiunto.fetch(source, uri, args) + if type(raw) ~= 'string' or raw == '' or raw == 'Could not retrieve API Data' then return nil, raw or 'no response' end + + local ok, decoded = pcall(mw.text.jsonDecode, raw) + if not ok or type(decoded) ~= 'table' then return nil, 'invalid JSON' end + + return decoded +end + local smm = { twitter = { @@ -342,189 +354,11 @@ function ObbyGameInfobox.main( frame ) local thumb = args.image or args.thumbnail or args.thumb - -- - - -- local universe_id - - -- local _, res = pcall(function() - -- return mw.ext.externalData.getExternalData{ - -- url = 'https://apis.roblox.com/universes/v1/places/' .. obby_starter_place_id .. '/universe', - -- format = 'json' - -- }; - -- end) - - -- universe_id = res and res.__json and res.__json.universeId - - - -- --- - - -- local last_updated = '' - -- if universe_id then - -- local game_res = mw.ext.externalData.getExternalData{ - -- url = 'https://games.roblox.com/v1/games?universeIds=' .. tostring(universe_id), - -- format = 'json' - -- } - - -- local game_json = game_res and game_res.__json - -- local row = game_json and game_json.data and game_json.data[1] - -- mw.log(game_res, row) - - -- if row and row.creator then - -- local c = row.creator - -- local base = (c.type == 'Group') and 'communities' or 'users' - - -- obby_developer_raw = obby_developer -- TODO remove - - -- if page_exists(c.type == 'Group' and c.name or '@' .. c.name) then - -- obby_developer = '[[' .. c.name .. ']]' .. (c.hasVerifiedBadge and ' [[File:Roblox_Verification_Badge.svg|12px|alt=Verified|link=' .. obby_developer_raw .. ']]' or '') - -- else - -- obby_developer = string.format( - -- '[https://roblox.com/%s/%s/%s %s%s]', - -- base, c.id, base == 'communities' and (string.gsub(c.name, ' ', '_') .. '#!/about') or 'profile', (c.type == 'User' and '@' or '') .. c.name, - -- (c.hasVerifiedBadge and ' [[File:Roblox_Verification_Badge.svg|12px|alt=Verified|link=]]') or '' - -- ) - - -- obby_developer_was_corrected = true - -- end - - -- obby_developer_canonical = c.type == 'User' and '@'.. c.name or c.name - -- end - - -- if row then - -- obby_stats_visits = row.visits or obby_stats_visits - -- obby_stats_favorites = row.favoritedCount or 'N/A' - -- if row.visits and tonumber(obby_stats_visits) ~= nil then obby_stats_visits_raw = tonumber(obby_stats_visits); obby_stats_visits = get_comma_val(obby_stats_visits) end - -- if row.favoritedCount and tonumber(obby_stats_favorites) ~= nil then obby_stats_favorites = get_comma_val(obby_stats_favorites) end - - -- if row.updated then - -- last_updated = row.updated -- iso, e.g., 2026-03-07T09:29:16.4508416Z - -- end - -- end - - -- --- - - -- local votes_res = mw.ext.externalData.getExternalData{ - -- url = 'https://games.roblox.com/v1/games/votes?universeIds=' .. tostring(universe_id), - -- format = 'json' - -- } - - -- local votes_json = votes_res and votes_res.__json - -- local vrow = votes_json and votes_json.data and votes_json.data[1] - - -- if vrow then - -- if vrow.upVotes and tonumber(vrow.upVotes) ~= nil then obby_stats_likes = tonumber(vrow.upVotes) end - -- if vrow.downVotes and tonumber(vrow.downVotes) ~= nil then obby_stats_dislikes = tonumber(vrow.downVotes) end - -- end - -- end - - -- local thumbs - -- local use_external_thumbs = false - -- if universe_id then - -- local thumb_overall_s, thumb_overall_err = pcall(function() - - -- -- request needs to route through oxalyl due to integer overflow issues on roblox's end - -- --- imageIds are in some cases too large for int32 and arent returned as strings, use oxalyl to get them returned as strings - -- local media_res = mw.ext.externalData.getExternalData{ - -- -- url = 'https://games.roblox.com/v2/games/' .. tostring(universe_id) .. '/media', - -- -- 'https://oxalyl.apis.wolf1te.com/roblox.com/thumbnails/v1/badges/icons?badgeIds=%s&size=150x150&format=Png&isCircular=false&returnPolicy=PlaceHolder&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9&oxalyl_convert_int=true' - -- url = 'https://oxalyl.apis.wolf1te.com/roblox.com/games/v2/games/' .. tostring(universe_id) .. '/media?fetchAllExperienceRelatedMedia=false&oxalyl_convert_int=true&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9', - -- format = 'json' - -- } - - -- local media_json = media_res and media_res.__json - -- local mdata = media_json and media_json.data - - -- local image_ids = {} - -- local thumb_urls = {} - -- local thumb_found = false - - -- if mdata then - -- for _, v in ipairs(mdata) do - -- if v.assetType == 'Image' and v.imageId and (v.assetTypeId == 1 or v.assetTypeId == '1') then - -- -- - -- if v.approved == true then - -- table.insert(image_ids, v.imageId) - -- thumb_found = true - -- end - -- end - -- end - - -- if thumb_found and #image_ids > 0 then - -- local thumb_res = mw.ext.externalData.getExternalData{ - -- url = 'https://thumbnails.roblox.com/v1/games/' .. tostring(universe_id) .. '/thumbnails?thumbnailIds=' .. table.concat(image_ids, ',') .. '&size=768x432&format=Webp&isCircular=false', - -- format = 'json' - -- } - - -- local thumb_json = thumb_res and thumb_res.__json - -- local tdata = thumb_json and thumb_json.data - - -- if tdata then - -- for _, v in ipairs(tdata) do - -- if v.state == 'Completed' and v.imageUrl then - -- table.insert(thumb_urls, v.imageUrl) - -- use_external_thumbs = true - -- end - -- end - - -- thumbs = thumb_urls - -- end - -- end - -- end - -- end) - - -- if not thumb_overall_s then - -- mw.log('Error fetching thumbnail: ' .. tostring(thumb_overall_err)) - -- end - -- end - - -- local s2, universe_data = pcall(function() - -- return mw.ext.externalData.getExternalData{ - -- data = { - -- creator_name = 'json.data[0].creator.name', - -- creator_id = 'json.data[0].creator.id', - -- is_verified = 'json.data[0].creator.hasVerifiedBadge' - -- }, - -- url = 'https://games.roblox.com/v1/games?universeIds=' .. universe_id, - -- format = 'json', - -- } - -- end) - - -- if s2 and universe_data then - -- if universe_data.creator_name then - -- obby_developer = universe_data.creator.name or obby_developer - - -- if universe_data.is_verified == 'true' or universe_data.is_verified == true then obby_developer = obby_developer .. ' [[File:Roblox_Verification_Badge.svg|12px|link=|alt=Verified]]' end - -- end - -- end - - -- local universe - - -- if universe_id then - -- local universe_data = mw.ext.externalData.getExternalData{ - -- url = 'https://games.roblox.com/v1/games?universeIds=' .. universe_id - -- } - - -- universe = universe_data and universe_data[1] - - -- if universe then - -- obby_developer = universe.creator and universe.creator.name or obby_developer - -- end - -- end - - --- - - local s, res = pcall(function() - return mw.ext.externalData.getExternalData{ - url = 'https://edge.obbywiki.com/v1/get-obby/' .. obby_starter_place_id, - -- a new endpoint which collects and fetches all data needed for the infobox in typescript and node, - -- about 3s faster due to concurrency being possible in the environment! - format = 'json' - } - end) - - - - local obby_wiki_edge_res = res and res.__json + -- edge aggregates all infobox Roblox data in typescript/node + local s, obby_wiki_edge_res = pcall(fetch_json, 'ObbyEdge', 'v1/get-obby/' .. obby_starter_place_id) + if not s then + obby_wiki_edge_res = nil + end local universe_id, thumbs local last_updated = '' diff --git a/modules/obbywiki.com/PlayerInfobox/PlayerInfobox.module.luau b/modules/obbywiki.com/PlayerInfobox/PlayerInfobox.module.luau index bd547a2..632dbf5 100644 --- a/modules/obbywiki.com/PlayerInfobox/PlayerInfobox.module.luau +++ b/modules/obbywiki.com/PlayerInfobox/PlayerInfobox.module.luau @@ -28,6 +28,19 @@ local function page_exists(page_title) return title and title.exists end +local apiunto = mw.ext.Apiunto + +local function fetch_json(source, uri, args) + local raw = apiunto.fetch(source, uri, args) + if type(raw) ~= 'string' or raw == '' or raw == 'Could not retrieve API Data' then return nil, raw or 'no response' end + + local ok, decoded = pcall(mw.text.jsonDecode, raw) + if not ok or type(decoded) ~= 'table' then return nil, 'invalid JSON' end + + return decoded +end + + local smm = { twitter = { @@ -167,14 +180,11 @@ function PlayerInfobox.main( frame ) local player_is_terminated = false if player_user_id then - local user_res = mw.ext.externalData.getExternalData{ - url = 'https://users.roblox.com/v1/users/'.. tostring(player_user_id), - format = 'json' - } - - local user_json = user_res and user_res.__json - local row = user_json - mw.log(user_json, row) + local s, row = pcall(fetch_json, 'RobloxUsers', 'v1/users/' .. tostring(player_user_id)) + if not s then + row = nil + end + mw.log(row) if row and row.name then player_user_name_raw = '@' .. row.name diff --git a/modules/obbywiki.com/RobloxBadgesV1/RobloxBadges.module.luau b/modules/obbywiki.com/RobloxBadgesV1/RobloxBadges.module.luau index fc801db..275119c 100644 --- a/modules/obbywiki.com/RobloxBadgesV1/RobloxBadges.module.luau +++ b/modules/obbywiki.com/RobloxBadgesV1/RobloxBadges.module.luau @@ -1,17 +1,20 @@ local p = {} -local ED = mw.ext.externalData +local apiunto = mw.ext.Apiunto local html = mw.html -local function fetch_json(url) - local data, errs = ED.getExternalData{ url = url } - if errs and #errs > 0 then - return nil, table.concat(errs, "; ") +local oxalyl_auth = 'public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9' + +local function fetch_json(source, uri, args) + local raw = apiunto.fetch(source, uri, args) + if type(raw) ~= 'string' or raw == '' or raw == 'Could not retrieve API Data' then + return nil, raw or 'no response' end - if not data or not data.__json then - return nil, "no JSON" + local ok, decoded = pcall(mw.text.jsonDecode, raw) + if not ok or type(decoded) ~= 'table' then + return nil, 'invalid JSON' end - return data.__json, nil + return decoded end local function format_date_timestamp(iso_date) @@ -35,13 +38,13 @@ local function gather_badges(universe_id) local tries = 0 repeat tries = tries + 1 - local url = string.format( - -- "https://badges.roblox.com/v1/universes/%s/badges?limit=100&sortOrder=Asc%s", - 'https://oxalyl.apis.wolf1te.com/roblox.com/badges/v1/universes/%s/badges?limit=100&sortOrder=Asc%s&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9&oxalyl_convert_int=true', - tostring(universe_id), - cursor and ("&cursor=" .. mw.uri.encode(cursor)) or "" - ) - local json, err = fetch_json(url) + local json, err = fetch_json('Oxalyl', 'roblox.com/badges/v1/universes/' .. tostring(universe_id) .. '/badges', { + limit = 100, + sortOrder = 'Asc', + cursor = cursor, + wlft_auth = oxalyl_auth, + oxalyl_convert_int = 'true', + }) if not json then return nil, err end if json.data then for _, b in ipairs(json.data) do @@ -74,15 +77,15 @@ local function fetch_thumbnails(badges) local csv, n = {}, 0 local function pull(ids_csv) - local url = ( - -- 'https://thumbnails.roblox.com/v1/badges/icons?badgeIds=%s&size=150x150&format=Png&isCircular=false&returnPolicy=PlaceHolder' - 'https://oxalyl.apis.wolf1te.com/roblox.com/thumbnails/v1/badges/icons?badgeIds=%s&size=150x150&format=Webp&isCircular=false&returnPolicy=PlaceHolder&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9&oxalyl_convert_int=true' - ) - :format(ids_csv) - local data, errs = ED.getExternalData{ url = url, cache = 3600 } - if errs and #errs > 0 then return end - - local json = data and data.__json + local json = fetch_json('Oxalyl', 'roblox.com/thumbnails/v1/badges/icons', { + badgeIds = ids_csv, + size = '150x150', + format = 'Webp', + isCircular = 'false', + returnPolicy = 'PlaceHolder', + wlft_auth = oxalyl_auth, + oxalyl_convert_int = 'true', + }) if not json or not json.data then return end for _, item in ipairs(json.data) do diff --git a/modules/obbywiki.com/RobloxBadgesV2/RobloxBadgesV2.module.luau b/modules/obbywiki.com/RobloxBadgesV2/RobloxBadgesV2.module.luau index 5633790..9414d01 100644 --- a/modules/obbywiki.com/RobloxBadgesV2/RobloxBadgesV2.module.luau +++ b/modules/obbywiki.com/RobloxBadgesV2/RobloxBadgesV2.module.luau @@ -2,7 +2,7 @@ local p = {} -- PROTOTYPE -local ED = mw.ext.externalData +local apiunto = mw.ext.Apiunto local aggrid = require('mw.ext.aggrid') local DEFAULT_ICON_PX = 64 @@ -10,16 +10,16 @@ local ROW_PAD = 16 local MIN_ROW_HEIGHT = 48 local BADGE_HREF = 'https://www.roblox.com/badges/%s/badge' -local BADGES_URL = 'https://oxalyl.apis.wolf1te.com/roblox.com/badges/v1/universes/%s/badges?limit=100&sortOrder=Asc%s&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9&oxalyl_convert_int=true' -local THUMBS_URL = 'https://oxalyl.apis.wolf1te.com/roblox.com/thumbnails/v1/badges/icons?badgeIds=%s&size=150x150&format=Webp&isCircular=false&returnPolicy=PlaceHolder&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9&oxalyl_convert_int=true' +local oxalyl_auth = 'public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9' -local function fetch_json(url) - local data, errs = ED.getExternalData{ url = url } +local function fetch_json(source, uri, args) + local raw = apiunto.fetch(source, uri, args) + if type(raw) ~= 'string' or raw == '' or raw == 'Could not retrieve API Data' then return nil, raw or 'no response' end - if errs and #errs > 0 then return nil, table.concat(errs, '; ') end - if not data or not data.__json then return nil, 'no JSON' end + local ok, decoded = pcall(mw.text.jsonDecode, raw) + if not ok or type(decoded) ~= 'table' then return nil, 'invalid JSON' end - return data.__json, nil + return decoded end local function gather_badges(universe_id) @@ -29,12 +29,13 @@ local function gather_badges(universe_id) repeat tries = tries + 1 - local url = string.format( - BADGES_URL, - tostring(universe_id), - cursor and ('&cursor=' .. mw.uri.encode(cursor)) or '' - ) - local json, err = fetch_json(url) + local json, err = fetch_json('Oxalyl', 'roblox.com/badges/v1/universes/' .. tostring(universe_id) .. '/badges', { + limit = 100, + sortOrder = 'Asc', + cursor = cursor, + wlft_auth = oxalyl_auth, + oxalyl_convert_int = 'true', + }) if not json then return nil, err end @@ -74,10 +75,15 @@ local function fetch_thumbnails(badges) local csv, n = {}, 0 local function pull(ids_csv) - local data, errs = ED.getExternalData{ url = THUMBS_URL:format(ids_csv), cache = 3600 } - if errs and #errs > 0 then return end - - local json = data and data.__json + local json = fetch_json('Oxalyl', 'roblox.com/thumbnails/v1/badges/icons', { + badgeIds = ids_csv, + size = '150x150', + format = 'Webp', + isCircular = 'false', + returnPolicy = 'PlaceHolder', + wlft_auth = oxalyl_auth, + oxalyl_convert_int = 'true', + }) if not json or not json.data then return end for _, item in ipairs(json.data) do diff --git a/modules/obbywiki.com/RobloxGamePasses/RobloxGamePasses.module.luau b/modules/obbywiki.com/RobloxGamePasses/RobloxGamePasses.module.luau index 2e01a01..211d609 100644 --- a/modules/obbywiki.com/RobloxGamePasses/RobloxGamePasses.module.luau +++ b/modules/obbywiki.com/RobloxGamePasses/RobloxGamePasses.module.luau @@ -1,19 +1,19 @@ local p = {} -local ED = mw.ext.externalData +local apiunto = mw.ext.Apiunto local html = mw.html -local function fetch_json(url) - local data, errs = ED.getExternalData{ url = url } - if errs and #errs > 0 then - return nil, table.concat(errs, "; ") - end - if not data or not data.__json then - return nil, "no JSON" - end - return data.__json, nil +local function fetch_json(source, uri, args) + local raw = apiunto.fetch(source, uri, args) + if type(raw) ~= 'string' or raw == '' or raw == 'Could not retrieve API Data' then return nil, raw or 'no response' end + + local ok, decoded = pcall(mw.text.jsonDecode, raw) + if not ok or type(decoded) ~= 'table' then return nil, 'invalid JSON' end + + return decoded end + local function format_date_timestamp(iso_date) local timestamp = iso_date or '2025-11-08T21:49:17.671+00:00' @@ -35,14 +35,10 @@ local function gather_passes(universe_id) -- local tries = 0 -- repeat -- tries = tries + 1 - local url = string.format( - -- "https://badges.roblox.com/v1/universes/%s/badges?limit=100&sortOrder=Asc%s", - -- 'https://oxalyl.apis.wolf1te.com/roblox.com/badges/v1/universes/%s/badges?limit=100&sortOrder=Asc%s&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9&oxalyl_convert_int=true', - 'https://apis.roblox.com/game-passes/v1/universes/%s/game-passes?pageSize=50&passView=Full', - tostring(universe_id) - -- cursor and ("&cursor=" .. mw.uri.encode(cursor)) or "" - ) - local json, err = fetch_json(url) + local json, err = fetch_json('RobloxApis', 'game-passes/v1/universes/' .. tostring(universe_id) .. '/game-passes', { + pageSize = 50, + passView = 'Full', + }) if not json then return nil, err end if json.gamePasses then for _, g in ipairs(json.gamePasses) do @@ -72,16 +68,12 @@ local function fetch_thumbnails(passes) local csv, n = {}, 0 local function pull(ids_csv) - local url = ( - -- 'https://thumbnails.roblox.com/v1/badges/icons?badgeIds=%s&size=150x150&format=Png&isCircular=false&returnPolicy=PlaceHolder' - -- 'https://oxalyl.apis.wolf1te.com/roblox.com/thumbnails/v1/badges/icons?badgeIds=%s&size=150x150&format=Png&isCircular=false&returnPolicy=PlaceHolder&wlft_auth=public-key-obbywiki-14-11-25-Vx9q7VCbM2Srn38LVDDhMk58GKf5bxD14KpPkS5XFzNEcM2FRHEaXNMbran621QySY0ueSUXZL5y4pTwjZ55nyyHhBTBuJ9BFnCAHzFLyPB3CfB9k9FGxBhAFST9qygnqtjd3PfUYtEEd4BRvhPpdQ25bLDjmjNhfucKqfE1DWJ2qkGuDubMSCGCqJGyLSFY5t2dpmTg4ij8viyCbu5dunfJfuZ71pCiz1ia4MUNBHdaPDSkg6wvWd9AJZGcHUT9&oxalyl_convert_int=true' - 'https://thumbnails.roblox.com/v1/game-passes?gamePassIds=%s&size=150x150&format=Webp&isCircular=false' - ) - :format(ids_csv) - local data, errs = ED.getExternalData{ url = url, cache = 3600 } - if errs and #errs > 0 then return end - - local json = data and data.__json + local json = fetch_json('RobloxThumbnails', 'v1/game-passes', { + gamePassIds = ids_csv, + size = '150x150', + format = 'Webp', + isCircular = 'false', + }) if not json or not json.data then return end for _, item in ipairs(json.data) do