heh, chat filtering, my name sake. Ok so…
To implement this, you should be using the
TextService:FilterStringAsync(message, userID, context) function.
You must implement this correctly, so for sending global messages in chat, you should be using the
PublicChat TextFilterContext enum.
When you have successfully filtered a message, you’ll get a object called TextFilterResult
You should then send the TextFilterResult:GetChatForUserAsync(userID) function to each client respectively. (You also have to filter
"" as a fail safe, roblox is weird ik)
A possible implementation for this could be
--FilterStringAsync can fail so we'll need to wrap it in a pcall
local worked, filterResult = pcall(TextService.FilterStringAsync, TextService, message, p.UserId, Enum.TextFilterContext.PublicChat) --pcall adds error handling, pretty much required for HTTP calls
if not worked then
--find some way to handle it not being filtered, you CANNOT return the message unfiltered
return --ends the function early returning nothing
for _, v in pairs(Players:GetPlayers()) do --runs the code in this block for every player as 'v'
ReplicatedStorage.SendFilteredMessage:FireClient(v, filterResult:GetChatForUserAsync(v.UserId), p.Name) --this can yield but shouldn't in most usecases, so we'll let it run synchronously here
Wait what’s going on with Line 3
Table:Function() is actually just syntax sugar for Table.Function(Table), they’ll behave exactly the same way. pcall will always call a function with
., so we need to parse the TextService itself aswell. It will work exactly the same way and will not hinder performance.
I only told how to do filtering here, you also need to factor
Chat:CanUserChat() for users which have the setting off in privacy settings.
You should just stick the default ChatService, once you open it’s API, it’s very powerful, and you can probably make your own GUIs for it with enough work.