--[[
π 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