New property: TextChatMessage.PassedFilter

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.

5 Likes