Hello, I am trying to filter a piece of text.
I have tried to read the wiki and several forum posts but I cannot get it to work.
The words do not get filtered.
I would appreciate a guide on exactly how to do this. The text will be shown above their head. This is done in a server script in ServerScriptService.
--serverside
game.ReplicatedStorage.RemoteFunction.OnServerInvoke = function(player,MSG)
return game.Chat:FilterStringForBroadcast(MSG,player)
end
--localscript
local filterString = game.ReplicatedStorage.RemoteFunction:InvokeServer(MSG)
The above method is what I use to filter strings. Of course, you’d need to change variable names, and create a RemoteFunction in replicated storage. If you have any questions, feel free to ask.
local TextService = game:GetService("TextService")
local TEXT_TO_FILTER = "Text"
local filterSuccess, filterResult = pcall(function()
local filteredTextResult = TextService:FilterStringAsync(TEXT_TO_FILTER, player.UserId)
filterResult = filteredTextResult:GetNonChatStringForBroadcastAsync()
end)
if not filterSuccess then
warn("Error filtering: ", TEXT_TO_FILTER) -- Handle failure
else
-- Do what you want with filtered text (filterResult) here
end
You would put this in a RemoteFunction and call it from the client every time you need to use it. It is good practice to wrap functions in a pcall just incase there is an error, so you can handle failures better.
If you’re testing in studio, Text Filtering with FilterStringForBroadcast would not work. Although, FilterStringAsync of TextService should be used for Filtering text now
local TextService = game:GetService("TextService")
local TEXT_TO_FILTER = "Hey"
local filterSuccess, filterResult = pcall(function()
local filteredTextResult = TextService:FilterStringAsync(TEXT_TO_FILTER, game.Players.Its_Groovy.UserId)
filterResult = filteredTextResult:GetNonChatStringForBroadcastAsync()
end)
if not filterSuccess then
warn("Error filtering: ", TEXT_TO_FILTER) -- Handle failure
else
print(filterResult)
end
It’s as simple as using this short code snippet, where it’s expecting you to already have defined the variable playerFrom.
Test this in a published place (not in studio) and it should work fine where the two last words in the sentence should be filtered out.
local serviceChat = game:GetService("Chat") --// I name it "service" at the start so it's easier when I have multiple services defined.
local textToFilter = "inappropriate invalid message stupid"
local filteredText = serviceChat:FilterStringForBroadcast(textToFilter, playerFrom)
print("String filtered: " .. filteredText)
Be very careful using FilterStringForBroadcast. I use FilterStringAsync because then I can filter text based on the user’s account settings. I find that FilterStringForBroadcast just filters everything on the highest level of security which is just terrible as any number+large amounts of words get hashtagged.
Using the ChatService’s filter functions is outdated, last I remember. Personally, you should be using explicitly what the article on Text Filtering says you should use - that is, the TextService. See LordHammy’s response for the full code.
local TextService = game:GetService("TextService")
local TextFilterResult = TextService:FilterStringAsync(string, UserId, context)
The text you want the client to have filtered should be passed through a RemoteFunction, where it’s filtered and the proper text is retrieved using a method of TextFilterResult. For your use case, you’d be looking to use GetNonChatStringForBroadcastAsync.
cc @Rawbyte
I’d actually be cautious of circumventing the use of FilterStringForBroadcast instead, actually. There are certain requirements for your filtering and publicly displayed text that isn’t player-to-player needs to be under Broadcast. The filter restrictions are they way they are for a reason.
Passing the player as both the sender and receiver doesn’t respect global standards for filtering, it only respects the sender’s. Broadcast should be used for broadcasts - when you’re having the client send out a message to the server. If it’s only between one player and another, then you’re free to pass the respective sender and receiver, which respects user settings.
I load in any text for broadcast using a client to server system where for each player who sees it, it will be checked for that specific player on the server. Instead of just making it for a broadcast i just parse through every player in that way.
Honestly, I didn’t even realize there was a new TextService, I just grabbed FilterStringForBroadcast from my old radios, since they still worked fine. I’ll make sure to update some time to filter locally and not on the server. Thanks.
local serviceChat = game:GetService("Chat") --// I name it "service" at the start so it's easier when I have multiple services defined.
local textToFilter = "inappropriate invalid message stupid"
local Success,filteredText = pcall(serviceChat.FilterStringForBroadcast,textToFilter,playerFrom)
if not Success then
warn("Something went wrong : "..tostring(filteredText))
return
end
if Success and filteredText then
print("String filtered: " .. filteredText)
end
Typically you don’t have to, but you should (and it’s good practice too). Text filtering is a web call internally, so if you don’t pcall it, then the function will throw an error and terminate the thread. Async merely describes the nature of which the method operates in, which it’s a yielding function.
What exactly do you mean by there isn’t a new TextService? It’s referenced as the current go-to service for the Text and Chat Filtering article. It and the Chat service are fairly different and don’t sport the same methods. All associated filter methods, either way, link back to CommunitySift iirc.