For BloxChat to work, your Roblox game must integrate with the backend to complete the verification flow. This allows users to prove their Roblox identity and receive a JWT session token.
Game integration is required for self-hosting. Without it, users cannot log in.
Create a server script (ServerScriptService) to handle verification:
ServerScriptService/BloxChatVerification
local HttpService = game:GetService("HttpService")local Players = game:GetService("Players")-- Configuration (store securely, never expose to client)local API_URL = "https://your-api-domain.com" -- Your backend URLlocal VERIFICATION_SECRET = "your_verification_secret_64_chars_minimum" -- From backend .envlocal VERIFICATION_ENDPOINT = API_URL .. "/trpc/auth.completeVerification"-- Function to complete verificationlocal function completeVerification(player: Player, code: string) local success, result = pcall(function() local response = HttpService:RequestAsync({ Url = VERIFICATION_ENDPOINT, Method = "POST", Headers = { ["Content-Type"] = "application/json", ["x-verification-secret"] = VERIFICATION_SECRET, }, Body = HttpService:JSONEncode({ code = code, robloxUserId = tostring(player.UserId), }), }) return HttpService:JSONDecode(response.Body) end) if success and result and result.ok then print("Verification successful for", player.Name) return true else warn("Verification failed for", player.Name, ":", result) return false endend-- Example: Verify on join (if code stored in DataStore)Players.PlayerAdded:Connect(function(player) -- In practice, get code from user via GUI or chat local code = getCodeFromPlayer(player) -- Your implementation if code then completeVerification(player, code) endend)-- Example: Verify via RemoteEvent from client GUIlocal verifyRemote = Instance.new("RemoteEvent")verifyRemote.Name = "VerifyBloxChat"verifyRemote.Parent = game:GetService("ReplicatedStorage")verifyRemote.OnServerEvent:Connect(function(player, code) -- Validate code format if typeof(code) ~= "string" or #code < 6 or #code > 12 then warn("Invalid code format from", player.Name) return end local success = completeVerification(player, code) -- Optionally notify client of result verifyRemote:FireClient(player, success)end)
local Players = game:GetService("Players")local TextChatService = game:GetService("TextChatService")Players.PlayerAdded:Connect(function(player) player.Chatted:Connect(function(message) -- Check for /verify command local code = message:match("^/verify%s+(%w+)$") if code then local success = completeVerification(player, code) if success then -- Send confirmation message to player local function sendMessage(text) local textChannel = TextChatService.TextChannels.RBXGeneral textChannel:DisplaySystemMessage(text) end sendMessage("BloxChat verification successful! You can close Roblox now.") else sendMessage("BloxChat verification failed. Check your code.") end end end)end)
Follow these practices to keep your integration secure.
1
Never expose VERIFICATION_SECRET to clients
Store the secret only in server scripts. Never:
Send to client via RemoteEvent/RemoteFunction
Store in ReplicatedStorage or client-accessible locations
Log or print in game output
2
Validate user input
Always validate the verification code:
if typeof(code) ~= "string" or #code < 6 or #code > 12 then warn("Invalid code format") return falseend
3
Rate limit verification attempts
The backend has built-in rate limiting (20 requests/minute per user), but you can add additional client-side checks:
local lastAttempt = {}local function canAttemptVerification(player) local now = tick() local last = lastAttempt[player.UserId] or 0 if now - last < 5 then -- 5 second cooldown return false end lastAttempt[player.UserId] = now return trueend
4
Use HTTPS in production
Always use HTTPS for your API URL:
local API_URL = "https://your-api-domain.com" -- HTTPS
HTTP connections expose the verification secret in transit.
5
Handle errors gracefully
Wrap HTTP requests in pcall and handle failures:
local success, result = pcall(function() return HttpService:RequestAsync({...})end)if not success then warn("HTTP request failed:", result) return falseend
local DataStoreService = game:GetService("DataStoreService")local verificationStore = DataStoreService:GetDataStore("BloxChatVerification")local function saveVerificationCode(userId, code) local success, err = pcall(function() verificationStore:SetAsync(tostring(userId), { code = code, timestamp = os.time(), }) end) if not success then warn("Failed to save verification code:", err) endendlocal function getVerificationCode(userId) local success, data = pcall(function() return verificationStore:GetAsync(tostring(userId)) end) if success and data then return data.code end return nilend
Players.PlayerAdded:Connect(function(player) local code = getVerificationCode(player.UserId) if code then task.wait(1) -- Brief delay local success = completeVerification(player, code) if success then -- Clear code after successful verification verificationStore:RemoveAsync(tostring(player.UserId)) end endend)
local VERIFICATION_PLACES = { 123456789, -- Main place 987654321, -- VIP server}local function isVerificationPlace() for _, placeId in ipairs(VERIFICATION_PLACES) do if game.PlaceId == placeId then return true end end return falseendif isVerificationPlace() then -- Enable verification GUI/commandsend