Skip to main content
This feature requires:

Panora Basic Admin Essentials Promote Integration

πŸ“₯ Installation

1

Open Roblox Studio

Navigate to your Basic Admin Essentials model in Roblox Studio.
2

Inserting Script

Create a Module Script under the Plugins folder, get rid of everything in it, and paste the following.
PanoraPromote.lua
--[[
πŸ“Œ Panora Promote Plugin - BAE (Basic Admin Essentials) Integration

πŸ”§ INSTALLATION & CONFIGURATION INSTRUCTIONS

1. Insert this ModuleScript under the "Plugins" folder in your Basic Admin Essentials system.
2. Navigate to https://app.panora.cc and obtain your unique API key. Replace the API_KEY variable below with that key.
3. Set your Roblox Group ID that is linked to your Panora Workspace in the GROUP_ID variable.
4. In the Panora dashboard, under the "Panora API" tab, whitelist your game's Universal Game ID to allow API access.
5. Customize the settings below as needed.

⚠️ WARNING:
Panora support will not assist with issues caused by unauthorized backend modifications. You may safely modify:
- API Key
- Group ID
- Cooldown Time
- Settings block (username min length, anti-abuse toggle)

πŸ› οΈ This plugin allows authorized users to promote a player to the next rank using the Panora API.

--]]

local HttpService = game:GetService("HttpService")
local GroupServiceModule = require(95677908346714)

local Plugin = function(...)
local Data = {...}
local remoteEvent = Data[1][1]
local remoteFunction = Data[1][2]
local returnPermissions = Data[1][3]
local Commands = Data[1][4]
local Prefix = Data[1][5]
local actionPrefix = Data[1][6]
local returnPlayers = Data[1][7]
local cleanData = Data[1][8]
local pluginName = script.Name
local pluginPrefix = Prefix
local pluginLevel = 2
local pluginUsage = "<username>"
local pluginDescription = "Promote a User | Panora"


--\\ [ SETTINGS ] //--
local API_KEY = "PANORA_API_KEY_HERE" -- API Key from https://app.panora.cc
local GROUP_ID = 00000 -- Group ID from Roblox Group
local COOLDOWN_TIME = 0 -- Cooldown in seconds
local WEBHOOK_URL = "" -- If a webhook URL is set it will send rank logs to the webhook

-- Anti-Abuse Settings
local MIN_USERNAME_LENGTH = 0 -- Minimum username length required
local EveryoneAntiAbuse = true -- If true, blocks staff members from running :promote all/everyone






--\\ [ END OF SETTINGS .. DO NOT EDIT BELOW THIS UNLESS YOU KNOW WHAT YOU ARE DOING ] //--

local recentPromotions = {}

local function findNextRank(currentRank, groupId)
	return GroupServiceModule.getNextRank(currentRank, groupId)
end

local function rankUser(rankData)
	local url = "https://api.panora.cc/v1/ranker?placeid=" .. game.GameId
	local payload = HttpService:JSONEncode(rankData)

	local success, response = pcall(function()
		return HttpService:RequestAsync({
			Url = url,
			Method = "POST",
			Headers = {
				["Authorization"] = "Bearer " .. API_KEY,
				["Content-Type"] = "application/json"
			},
			Body = payload
		})
	end)

	if not success then
		warn("❌ HTTP Request failed to send:", tostring(response))
		return false
	end

	local parsed
	local ok, result = pcall(function()
		return HttpService:JSONDecode(response.Body)
	end)

	if ok then
		parsed = result
	else
		parsed = { message = response.Body }
	end

	if response.Success then
		print("βœ… [PANORA BAE INTEGRATION | PROMOTE]:", parsed.message or HttpService:JSONEncode(parsed))
		return true
	else
		warn("❌ [PANORA BAE INTEGRATION | PROMOTE]:", parsed.message or parsed.error or HttpService:JSONEncode(parsed))
		return false
	end
end

local function pluginFunction(Args)
	local player = Args[1]
	local target = Args[3]

	if not target then
		return "Please provide a username."
	end

	local lowered = string.lower(target)
	if EveryoneAntiAbuse and (lowered == "everyone" or lowered == "all") then
		return "Anti-Abuse setting is enabled. Mass promotions are not allowed."
	end

	if #target < MIN_USERNAME_LENGTH then
		return `Username must be at least {MIN_USERNAME_LENGTH} characters long.`
	end

	local victims = returnPlayers(player, target)
	if not victims or #victims == 0 then
		return "Couldn't find player."
	end

	local targetPlayer = victims[1]

	if player.UserId == targetPlayer.UserId then
		return "You can't promote yourself!"
	end

	local lastPromoteTime = recentPromotions[targetPlayer.UserId]
	if lastPromoteTime and os.time() - lastPromoteTime < COOLDOWN_TIME then
		local remaining = COOLDOWN_TIME - (os.time() - lastPromoteTime)
		return `{targetPlayer.Name} was recently promoted. Please wait {remaining} seconds.`
	end

	local currentRank = GroupServiceModule.getUserGroupRank(targetPlayer.UserId, GROUP_ID)
	local currentRoleName = nil

	local roles = GroupServiceModule.getGroupRoles(GROUP_ID)
	for _, role in pairs(roles) do
		if role.Rank == currentRank then
			currentRoleName = role.Name
			break
		end
	end

	local nextRank = findNextRank(currentRank, GROUP_ID)

	if not nextRank then
		return "Already at highest rank or no higher rank available."
	end

	local rankData = {
		rankerName = player.Name,
		rankerId = player.UserId,
		rankeeName = targetPlayer.Name,
		rankeeId = targetPlayer.UserId,
		newRankId = nextRank.Rank,
		oldRankName = currentRoleName,
		command = "promote | BAE Integration",
		prefix = Prefix,
		webhookUrl = WEBHOOK_URL
	}

	local success = rankUser(rankData)
	if success then
		recentPromotions[targetPlayer.UserId] = os.time()
		return `Promoted {targetPlayer.Name} to {nextRank.Name}.`
	else
		return "Promotion failed. Check logs or Panora API key."
	end
end

local descToReturn = pluginPrefix .. pluginName .. (pluginUsage ~= "" and (" " .. pluginUsage) or "") .. "\n" .. pluginDescription
return pluginName, pluginFunction, pluginLevel, pluginPrefix, {pluginName, pluginUsage, pluginDescription}
end

return Plugin
3

API Key

  • Visit https://app.panora.cc and copy your API Key.
    See API Key
  • Replace the API_KEY in the script with your actual API key.
  • Under the Panora Dashboard > Panora API, whitelist your game’s Universal Game ID.
    See Whitelist
4

Roblox Group

  • Set your GROUP_ID to match the Roblox group linked to your Panora workspace.
    See Initial Setup
  • Configure your group ranks in the ranks table in ascending order.
  • Set a cooldown time to avoid rapid promotions (recommended: 20 seconds).

βš™οΈ Configuration

VariableDescriptionRequired
API_KEYYour Panora API key from app.panora.ccβœ…
GROUP_IDRoblox Group ID linked to your workspaceβœ…
ranksAn ordered table of your group ranksβœ…
COOLDOWN_TIMESeconds to wait before promoting a user again⚠️ Recommended
Example ranks table:
local ranks = {
  {rankId = 1, rankName = "Member"},
  {rankId = 2, rankName = "Moderator"},
  {rankId = 3, rankName = "Admin"},
}
⌘I