Roblox
The Roblox integration handles verification, role binds (Discord roles โ Roblox group ranks/gamepasses/badges), playtime XP, and automatic promotions in your Roblox group when members hit rank thresholds.
Verification
Members link their Roblox account to their Discord account via OAuth. One click for the user; no verification codes, no bio-editing, no botting.
Requirements: register a Roblox OAuth application at create.roblox.com/credentials and enter its Client ID + Secret in the dashboard.
Role binds
Automatically assign Discord roles based on the member's state in your Roblox group:
- Group rank binds โ "members at rank 100+ get the Officer role"
- Gamepass binds โ "members who own the VIP gamepass get the VIP role"
Configured in the Role Binds tab of the Roblox dashboard. Runs when a member first links, then again on demand via /roblox sync or the Sync button.
Playtime XP
Players earn XP passively while active in your Roblox game. Default rate: 1 XP per 10 minutes of active playtime. Idle players (no input for 2+ minutes) don't accumulate.
XP flows into the ranks system โ see Ranks & XP for the full explanation of divisions, ranks, and auto-promotion.
Roblox group rank promotion
When Mira auto-promotes a member in Discord AND that rank has a robloxGroupRank value set, Mira also promotes the member in your actual Roblox group via the Open Cloud Groups API.
- A Roblox API key with
group:writescope for your group, generated at create.roblox.com/credentials - The API key owner's Roblox account must be in the group at a rank higher than the highest rank Mira will grant (Roblox's API can't promote to a rank โฅ the caller's own)
- The Universe ID and Group ID must match the ones set in the dashboard
Bridge script
Paste this ServerScript into ServerScriptService in your Roblox game. Set BRIDGE_URL to your Mira domain and BRIDGE_KEY to the value from your dashboard (Roblox tab โ Bridge โ Reveal key).
-- =============================================================
-- MIRA BRIDGE โ Playtime โ XP
-- Paste into ServerScriptService. Set the constants below.
-- =============================================================
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
-- ==== CONFIG ====
local BRIDGE_URL = "https://www.rbananz.xyz" -- your Mira domain
local BRIDGE_KEY = "PASTE_YOUR_BRIDGE_KEY_HERE" -- Dashboard โ Roblox โ Bridge key
local UNIVERSE_ID = tostring(game.GameId) -- auto-detected
local HEARTBEAT_S = 30
local IDLE_TIMEOUT = 120
-- ================
local sessionToken, sessionExpiresAt = nil, 0
local function fetchSessionToken()
local ok, res = pcall(function()
return HttpService:RequestAsync({
Url = BRIDGE_URL .. "/api/roblox/bridge/session",
Method = "POST",
Headers = { ["X-Bridge-Key"] = BRIDGE_KEY, ["Content-Type"] = "application/json" },
Body = "{}",
})
end)
if not ok or not res.Success then
warn("[Mira] session fetch failed"); return nil
end
local data = HttpService:JSONDecode(res.Body)
sessionToken = data.token
sessionExpiresAt = tick() + (data.expiresInSeconds or 3600) - 300
return sessionToken
end
local function getSessionToken()
if sessionToken and tick() < sessionExpiresAt then return sessionToken end
return fetchSessionToken()
end
local state = {}
local function initPlayer(player)
state[player.UserId] = { lastActive = tick(), pendingActive = 0 }
local function onCharacter(character)
local root = character:WaitForChild("HumanoidRootPart", 10)
if not root then return end
local lastPos = root.Position
while character.Parent and state[player.UserId] do
task.wait(5)
if not root or not root.Parent then break end
if (root.Position - lastPos).Magnitude > 1 then
state[player.UserId].lastActive = tick()
lastPos = root.Position
end
end
end
if player.Character then task.spawn(onCharacter, player.Character) end
player.CharacterAdded:Connect(function(c) task.spawn(onCharacter, c) end)
player.Chatted:Connect(function()
if state[player.UserId] then state[player.UserId].lastActive = tick() end
end)
end
Players.PlayerAdded:Connect(initPlayer)
Players.PlayerRemoving:Connect(function(p) state[p.UserId] = nil end)
for _, p in ipairs(Players:GetPlayers()) do initPlayer(p) end
RunService.Heartbeat:Connect(function(dt)
local now = tick()
for _, s in pairs(state) do
if now - s.lastActive < IDLE_TIMEOUT then
s.pendingActive = s.pendingActive + dt
end
end
end)
task.spawn(function()
while true do
task.wait(HEARTBEAT_S)
local token = getSessionToken()
if not token then continue end
local players = {}
for userId, s in pairs(state) do
if s.pendingActive >= 1 then
table.insert(players, {
robloxUserId = tostring(userId),
activeSeconds = math.floor(s.pendingActive),
})
s.pendingActive = s.pendingActive - math.floor(s.pendingActive)
end
end
if #players == 0 then continue end
local ok, res = pcall(function()
return HttpService:RequestAsync({
Url = BRIDGE_URL .. "/api/roblox/bridge/heartbeat",
Method = "POST",
Headers = {
["Authorization"] = "Bearer " .. token,
["Content-Type"] = "application/json",
},
Body = HttpService:JSONEncode({ universeId = UNIVERSE_ID, players = players }),
})
end)
if ok and res.StatusCode == 401 then
sessionToken, sessionExpiresAt = nil, 0
elseif ok and res.StatusCode == 403 then
warn("[Mira] universe mismatch โ check dashboard Universe ID")
end
end
end)
print("[Mira] bridge loaded โ heartbeat " .. HEARTBEAT_S .. "s, idle " .. IDLE_TIMEOUT .. "s")Also required: in Studio, go to Game Settings โ Security and enable Allow HTTP Requests. Save and publish. The script runs on every server instance.
Commands
/verifyโ start the verification flow/roblox whois @userโ look up someone's linked Roblox account/roblox sync @userโ force resync of role binds for a user/roblox setupโ quick setup wizard for the current server
Configuration
On the Roblox dashboard page, configure:
- Verification โ verified role, verify channel, rename-on-verify
- OAuth app โ Client ID and Client Secret from Roblox Creator Hub
- Group sync โ group ID + rank mappings to Discord roles
- Gamepass sync โ gamepass ID + Discord role
- Playtime XP & group promotion โ Universe ID, Group ID, Group API key, XP rate
- Bridge โ the API key your game uses to authenticate