GetBanHistoryAsync() returning nil?

I’m using the new Ban API’s GetBanHistoryAsync() function to retrieve a player’s ban history. This is for a friend’s game, which has a custom made admin panel system built by me. However, GetBanHistoryAsync() is always returning nil, even after trying to convert the ID to a number.

Code (Server):

remotes:WaitForChild("getBanHistory").OnServerInvoke = function(player, id)
	id = tonumber(id)
	print("Loading ban history for ID: "..id)
	local success, banHistory = pcall(function()
		return game.Players:GetBanHistoryAsync(id)
	end)
	return success, banHistory
end

Code (Client):

local getBanHistory = remotes:WaitForChild("getBanHistory")
local banHistoryFrame = panelToggleables:WaitForChild("banHistory")

function loadBanHistory(id)
	for i, cases in banHistoryFrame.caseList:GetChildren() do
		if cases.Name ~= "temp" and cases:IsA("Frame") then
			cases:Destroy()
		end
	end
	local success, playerBanHistory: BanHistoryPages = getBanHistory:InvokeServer(id)
	if success then
		if playerBanHistory then
			pcall(function()
				repeat
					local page = playerBanHistory:GetCurrentPage()
					for caseId, caseInfo in page do
						local newCaseFrame = banHistoryFrame.caseList:WaitForChild("temp"):Clone()
						local caseProperties = newCaseFrame:WaitForChild("banInfo")
						caseProperties.caseId.Text = "Case #"..caseId
						local lengthDisplay = (caseInfo.Duration == -1) and "Permanent" or (caseInfo.Duration / 86400).." day(s)"
						local actionDisplay = caseInfo.Ban and "Ban" or "Unban"
						caseProperties.banLength.Text =  lengthDisplay
						caseProperties.action.Text = actionDisplay
						caseProperties.reason.Text = caseInfo.DisplayReason
						caseProperties.ad.Text = caseInfo.PrivateReason
						caseProperties.Parent = banHistoryFrame.caseList
						caseProperties.Visible = true
					end
					if playerBanHistory.IsFinished then
						break
					end
					playerBanHistory:AdvanceToNextPageAsync()
				until playerBanHistory.IsFinished == true
			end)
		else
			task.spawn(function()
				local sound = Instance.new("Sound", workspace)
				sound.Name = "NotificationSound"
				sound.SoundId = "rbxassetid://550209561"
				sound:Play()
				sound.Ended:Connect(function()
					sound:Destroy()
				end)
				notificationModule:Notify(
					"Admin Panel",
					"This player may not have a ban history.",
					"rbxassetid://11419709766",
					5,
					{
						.3,
						Color3.fromRGB(190, 0, 0)
					}
				)
			end)
		end
	else
		task.spawn(function()
			local sound = Instance.new("Sound", workspace)
			sound.Name = "NotificationSound"
			sound.SoundId = "rbxassetid://550209561"
			sound:Play()
			sound.Ended:Connect(function()
				sound:Destroy()
			end)
			notificationModule:Notify(
				"Admin Panel",
				"Failed to get ban history. Please try again.",
				"rbxassetid://11419709766",
				5,
				{
					.3,
					Color3.fromRGB(190, 0, 0)
				}
			)
		end)
	end
	print("History status:", success, playerBanHistory)
end

banHistoryFrame.id.FocusLost:Connect(function(enterPressed)
	if banHistoryFrame.id.Text == "" then return end
	local providedId = tonumber(banHistoryFrame.id.Text)
	if providedId then
		loadBanHistory(providedId)
	else
		local p = game.Players:GetUserIdFromNameAsync(banHistoryFrame.id.Text)
		if p then
			loadBanHistory(p)
		end
	end
end)

A solution for this is greatly appreciated.

Having the same issue since yesterday

It turns out that the BanHistoryPages object is only accessible on the server. Below is the updated code.

Server:

remotes:WaitForChild("getBanHistory").OnServerInvoke = function(player, id)
	id = tonumber(id)
	print("Loading ban history for ID: "..id)
	local success, banHistory = pcall(function()
		return game.Players:GetBanHistoryAsync(id)
	end)
	if not success then
		warn("Error:", banHistory)
		return nil
	end
	local finalBanHistory = {}
	repeat
		local page = banHistory:GetCurrentPage()
		for caseId, case in page do
			print("Case "..caseId)
			for c, thing in case do
				print(c..": "..tostring(thing))
			end
			table.insert(finalBanHistory, case)
		end
		if banHistory.IsFinished then
			break
		end
		banHistory:AdvanceToNextPageAsync()
	until banHistory.IsFinished == true
	return finalBanHistory
end

Client:

local getBanHistory = remotes:WaitForChild("getBanHistory")
local banHistoryFrame = panelToggleables:WaitForChild("banHistory")

function loadBanHistory(id)
	for i, cases in banHistoryFrame.caseList:GetChildren() do
		if cases.Name ~= "temp" and cases:IsA("Frame") then
			cases:Destroy()
		end
	end
	local playerBanHistory: BanHistoryPages = getBanHistory:InvokeServer(id)
	local success, message = pcall(function()
		for caseId, caseInfo in playerBanHistory do
			local newCaseFrame = banHistoryFrame.caseList:WaitForChild("temp"):Clone()
			local caseProperties = newCaseFrame:WaitForChild("banInfo")
			caseProperties.caseId.Text = "Case #"..caseId
			local lengthDisplay = (caseInfo.Duration == -1) and "Permanent" or (caseInfo.Duration / 86400).." day(s)"
			local actionDisplay = caseInfo.Ban and "Ban" or "Unban"
			caseProperties.banLength.Text =  lengthDisplay
			caseProperties.action.Text = actionDisplay
			caseProperties.reason.Text = caseInfo.DisplayReason
			caseProperties.ad.Text = caseInfo.PrivateReason
			newCaseFrame.Parent = banHistoryFrame.caseList
			newCaseFrame.Visible = true
		end
	end)
	print(success, message)
end

banHistoryFrame.id.FocusLost:Connect(function(enterPressed)
	if not enterPressed then return end
	if banHistoryFrame.id.Text == "" then return end
	local providedId = tonumber(banHistoryFrame.id.Text)
	if providedId then
		loadBanHistory(providedId)
	else
		local p = game.Players:GetUserIdFromNameAsync(banHistoryFrame.id.Text)
		if p then
			loadBanHistory(p)
		end
	end
end)
1 Like

With using the server code that you provide as well, it returns with a 403 (Forbidden) error on the server side. Any reason for this?

(Edit: Works it was returning with the 403 since no was banned before in the game… Strange however it works now)

Did you enable “Allow HTTP Requests” in security tab in game settings?