Loading...
Loading...
Chat and text safety - TextChatService (channels, SendAsync, ShouldDeliverCallback, OnIncomingMessage, commands, bubbles, custom UI), mandatory TextService filtering of any player-authored text, rate limits, privacy checks, PolicyService restrictions, legacy Chat migration. Use when adding chat features or commands, or any feature that shows one player's text to others (names, signs, notes).
npx skill4agent add el4cteo/roblox-skills roblox-text-chatTextChannelChatChatServiceTextChatServiceTextService:FilterStringAsyncCanUserChatAsyncCanUsersChatAsyncCanUsersDirectChatAsyncTextChannel:SetDirectChatRequester()--!strict
local TextService = game:GetService("TextService")
-- Broadcast (e.g. a sign everyone sees). Returns nil if filtering failed: then show nothing.
local function filterForEveryone(text: string, fromUserId: number): string?
local ok, result = pcall(function()
local filterResult = TextService:FilterStringAsync(text, fromUserId, Enum.TextFilterContext.PublicChat)
return filterResult:GetNonChatStringForBroadcastAsync()
end)
return if ok then result else nil
end
-- Per-recipient (respects each viewer's age/settings; e.g. a private note).
local function filterForUser(text: string, fromUserId: number, toUserId: number): string?
local ok, result = pcall(function()
local filterResult = TextService:FilterStringAsync(text, fromUserId, Enum.TextFilterContext.PrivateChat)
return filterResult:GetNonChatStringForUserAsync(toUserId)
end)
return if ok then result else nil
end
return { forEveryone = filterForEveryone, forUser = filterForUser }###CreateDefaultTextChannelsRBXGeneralRBXSystemCreateDefaultCommands/whisper/team/muteChatWindowConfigurationChatInputBarConfigurationBubbleChatConfigurationTextChannel:SendAsyncTextChatService.MessageReceivedTextChannel:SendAsync(text)TextChannel.ShouldDeliverCallback(message, textSource)OnIncomingMessageShouldDeliverCallbackTextChatService.OnIncomingMessageTextChannel.OnIncomingMessagechannel:DisplaySystemMessage(text)TextChannelTextChatServicechannel:AddUserAsync(userId)TextSourceCanSend--!strict
-- Client: chat tags and colors via OnIncomingMessage (formatting only; never yields).
local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")
TextChatService.OnIncomingMessage = function(message: TextChatMessage)
local properties = Instance.new("TextChatMessageProperties")
local source = message.TextSource
if source then
local player = Players:GetPlayerByUserId(source.UserId)
if player and player:GetAttribute("VIP") then
properties.PrefixText = `<font color="#F5CD30">[VIP]</font> {message.PrefixText}`
end
end
return properties
end--!strict
-- Server: a /spawn command, restricted to admins.
local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")
local ADMINS: { [number]: boolean } = { [123456] = true }
local command = Instance.new("TextChatCommand")
command.Name = "SpawnCommand"
command.PrimaryAlias = "/spawn"
command.Parent = TextChatService
command.Triggered:Connect(function(source: TextSource, unfilteredText: string)
if not ADMINS[source.UserId] then
return
end
local player = Players:GetPlayerByUserId(source.UserId)
print(`{player and player.Name} ran: {unfilteredText}`)
end)PolicyService:GetPolicyInfoForPlayerAsync(player)pcallArePaidRandomItemsRestrictedIsPaidItemTradingAllowedAreAdsAllowedAllowedExternalLinkReferencesIsSubjectToChinaPoliciesIsContentSharingAllowedAllowedExternalLinkReferencesroblox-securityroblox-uiroblox-monetizationroblox-data-stores