Scam Prevention - TextChatService

I have made a very simple system that notifies players if a potential scam message is sent in the chat system, as you can see in the screenshot below:

Feel free to use this, as creators we should care more about the safety of our players!

Installation:

  1. Create a local script, place this code inside.
  2. Place the local script under StarterPlayerScripts.

Open Sourced Script:

local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")
local localPlayer = Players.LocalPlayer

if TextChatService.ChatVersion ~= Enum.ChatVersion.TextChatService then
	warn("Scam filter requires the new TextChatService to be enabled!")
	return
end

local scamPatterns = {
	-- Free Robux scams
	"free robux", "freerobux", "free r$", "freer$",
	"claim robux", "get robux", "earn robux", "robux generator",
	"free rbx", "freerbx",
	-- Phishing sites
	"blox", "rbx", "rblx", "robox", "robIox",
	"rewards", "rewαrds", "rewords", "clαim",
	-- Discord bypasses
	"disc", "dscrd", "discÎżrd", "dis cord",
	"d1scord", "d!scord",
	-- Other platforms
	"youtube%.com", "youtu%.be", "twitter%.com",
	"tiktok%.com", "twitch%.tv",
	-- Suspicious phrases
	"click here", "visit", "join now", "limited time",
	"hurry", "expires", "go to", "check out",
	-- Fake system messages
	"%[system%]", "%[roblox%]", "%[admin%]",
	-- Common scam phrases
	"become admin", "get admin", "free admin",
	"hack", "exploit", "cheat",
	"account giveaway", "giving away"
}

local function containsScam(message)
	local lowerMsg = message:lower()
	local noSpaces = lowerMsg:gsub("%s+", "")

	for _, pattern in ipairs(scamPatterns) do
		if lowerMsg:match(pattern) or noSpaces:match(pattern) then
			return true
		end
	end

	if lowerMsg:match("https?://") or lowerMsg:match("www%.") or 
		lowerMsg:match("%.com") or lowerMsg:match("%.gg") then
		return true
	end

	local specialCharCount = select(2, lowerMsg:gsub("[^%w%s]", ""))
	if specialCharCount > 5 then
		return true
	end

	return false
end

local function sendWarning(isSelf)
	local textChannels = TextChatService:WaitForChild("TextChannels")
	local channel = textChannels:WaitForChild("RBXGeneral")

	local warningText
	if isSelf then
		warningText = "<font color='#ffff00'>⚠️ Your message contains potentially dangerous content, please refrain from sharing!</font>"
	else
		warningText = "<font color='#ffff00'>⚠️ Be careful! This message may contain scams or direct you off-site. Never share your account info, or open links in the chat system!</font>"
	end

	pcall(function()
		task.wait(.5)
		channel:DisplaySystemMessage(warningText)
	end)
end

local function onMessageReceived(textChannel, message)
	if message.TextSource then
		local player = Players:GetPlayerByUserId(message.TextSource.UserId)
		if player and containsScam(message.Text) then
			local isSelf = (player == localPlayer)
			sendWarning(isSelf)
		end
	end
end

local function setupChannel(channel)
	if channel then
		channel.MessageReceived:Connect(function(message)
			onMessageReceived(channel, message)
		end)
	end
end

repeat task.wait() until game:IsLoaded()
task.wait(2)

local textChannels = TextChatService:WaitForChild("TextChannels")
for _, channel in ipairs(textChannels:GetChildren()) do
	if channel:IsA("TextChannel") then
		setupChannel(channel)
	end
end

textChannels.ChildAdded:Connect(function(child)
	if child:IsA("TextChannel") then
		setupChannel(child)
	end
end)
5 Likes

Right so won’t this just block all normal messages too?

People say “hurry” a lot and “go to” as well. “claim” is also a common word.

There can be many false reports from this. Instead, a better way is to check if the senders username and account age are suspiscious.

the phrases had been generated by AI as an example, you can edit the phrases however you want.

wont this just notify everyone when someone says whatever word is blacklisted, besides this wont help much as most scambots of today will leave immediately after chatting