The script does not print the correct number of badges

Hi, I want to count how many badges a user has, but it doesn’t work because it doesn’t print the correct amount.

Players.PlayerAdded:Connect(function(player)
	local success, data = pcall(function()
		return DonationODS:GetAsync(player.UserId)
	end)

	local badgesEarned = {}

	local response = HttpService:RequestAsync({
		Url = "https://badges.roproxy.com/v1/users/" .. player.UserId .. "/badges?limit=100&sortOrder=Asc",
		Method = "GET"
	})

	if response.Success and response.Body then
		local data = HttpService:JSONDecode(response.Body)
		task.spawn(function()
			for i, badge in ipairs(data.data) do
				table.insert(badgesEarned, badge.id)
			end
		end)
		if not data.nextPageCursor == "null" then
			repeat
				local response = HttpService:RequestAsync({
					Url = "https://badges.roproxy.com/v1/users/" .. player.UserId .. "/badges?limit=100&cursor=" .. data.nextPageCursor .. "&sortOrder=Asc",
					Method = "GET"
				})

				if response.Success and response.Body then
					local data = HttpService:JSONDecode(response.Body)
					task.spawn(function()
						for i, badge in ipairs(data.data) do
							table.insert(badgesEarned, badge.id)
						end
					end)
				elseif not response.Success then
					warn("The request failed:", response.StatusCode, response.StatusMessage)
				end
			until data.nextPageCursor == "null"
		end
	end
	print(#badgesEarned)
end)

I assume your code doesn’t work if the player has more than 200 badges? If that assumption is correct, you have to use a recursive function:

local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")

function getBadgesRecursive(userId, max, badges, cursor)
	--sets defaults
	badges = badges or {} 
	max = max or math.huge 
	
	if max <= 0 then 
		return badges 
	end
	
	local response 
	local url = "https://badges.roproxy.com/v1/users/"..userId.."/badges?limit=100&sortOrder=Asc" 
	if cursor then 
		url ..= "&cursor="..cursor
	end
	local Success, Error = pcall(function()
		response = HttpService:GetAsync(url)
	end)

	if Success then 
		local data = HttpService:JSONDecode(response)
		for i, badge in pairs(data.data) do 
			table.insert(badges, badge.id)
		end
	
		cursor = data.nextPageCursor 
		if cursor and cursor ~= "null" then 
			return getBadgesRecursive(userId, max-100, badges, cursor) 
		else 
			return badges 
		end
	else 
		if Error then 
			warn(Error)
		end
		task.wait(4) --wait for some time, before making a new request
		return getBadgesRecursive(userId, max, badges, cursor)
	end
end

Players.PlayerAdded:Connect(function(player)
	--stops requesting badges when it reach 1500(you should add some kind of max to avoid spamming requests for people with ridiculous amount of badges)
	local badgesEarned = getBadgesRecursive(player.UserId, 1500)

	print(#badgesEarned)
end)

PS: Expect the script to be slow when a user owns a lot of badges due to Roblox limitations.

1 Like

Roblox should really add an endpoint which provides the total number of badges a user has, it used to be a stat visible from the website.