As a developer, there’s currently no way for me to accurately be able to tell whether or not a player’s message passed TextChatService’s filter using that service alone.
I can technically guess this by checking if the message is made up entirely of hashtags –
Which is my current workaround
export type MessageStatusType = "sending" | "success" | "failed" | "filtered"
local ChatUtils = {
MessageStatus = {
SENDING = "sending",
SUCCESS = "success",
FAILED = "failed",
FILTERED = "filtered",
},
DEBUG_STATUS = false,
}
ChatUtils.DEBUG_STATUS_MSG_MAP = {
[";dbgStatusSending"] = ChatUtils.MessageStatus.SENDING,
[";dbgStatusSuccess"] = ChatUtils.MessageStatus.SUCCESS,
[";dbgStatusFailed"] = ChatUtils.MessageStatus.FAILED,
[";dbgStatusFiltered"] = ChatUtils.MessageStatus.FILTERED,
}
function ChatUtils.resolveMessageStatus(message: TextChatMessage): MessageStatusType
if ChatUtils.DEBUG_STATUS == true and ChatUtils.DEBUG_STATUS_MSG_MAP[message.Text] ~= nil then
return ChatUtils.DEBUG_STATUS_MSG_MAP[message.Text]
end
if message.Status == Enum.TextChatMessageStatus.Sending then
return ChatUtils.MessageStatus.SENDING
end
if message.Status == Enum.TextChatMessageStatus.Success then
local hits: number = select(2, string.gsub(message.Text, "#", ""))
if ChatUtils.len(message.Text) == hits then
return ChatUtils.MessageStatus.FILTERED
end
return ChatUtils.MessageStatus.SUCCESS
end
return ChatUtils.MessageStatus.FAILED
end
return ChatUtils
– But this does not guarantee that the contents were transformed after filtering, since a player can just… send a message made up entirely of hashtags.
The downside of this workaround is that this gives players the ability to make their messages appear as if filtered whenever they want, in turn giving other players the impression that Roblox’s chat filter is “broken” when they see a player spout out nothing but filtered messages.
It also gets in the way of the experience I’m trying to give players with my use case explained later on.
There are also some DevForum posts that suggest sending messages to the server using remotes and compare for a filter pass there, but considering how Roblox’s system actively monitors how TextChatService is used, I do not feel comfortable using solutions such as these, especially since the system I’m developing is for someone else’s use.
With or without this issue addressed, my use case is as follows:
I’m making a custom chat system for someone’s game, and I have the desire to replace a player’s message that didn’t pass the filter with a random one of many pre-defined, humorous messages instead.
For example, it’s not at all uncommon to get eaten by a shark in the game. So, one of the messages could be “This message has been eaten by a shark.”.
You’re also likely to get struck by lightning at some point when playing the game, so another message could be “This message was struck by lightning.” – you get the idea.
Having your messages just turn into a bunch of hashtags often does nothing but frustrate players, so I think replacing them with some funny messages can likely turn someone’s frustration into laughter, making their chat experience more pleasant.
With this issue addressed, custom features such as the one I described in my use case can function as intended by design. It’s unfortunate that players will be able to use the side effect explained in my workaround in order to see most if not all of the unique filter messages I’ll be building in, because then the effect they’ll have on players that stumble upon them will become minimal due to potential over-exposure.
Additionally, players forcing their messages to appear as if filtered will not negatively impact Roblox’s image due to recipients perceiving the filter as “not working correctly” or being “broken”.
Side request
I intentionally suggested the property “PassedFilter” in the post’s title instead of “IsFiltered” (the latter being a property of a message instance passed through the OnNewMessage event in Roblox’s legacy chat bubble system).
The reason for this is because “IsFiltered” is misleading.
TextChatService always passes messages through a filter, so with that context in mind, IsFiltered would then always be true, unless you switch your context to whether or not the message did not pass the filter (which is what it’s intended to convey).
Therefore I request that, if this feature request were to be implemented, a name that better conveys the meaning would be chosen instead of IsFiltered.
I’m aware TextChatService is still very much new and that new features and changes are to be expected in the coming months and years.
Thank you for your time.