Mute/ Kick Script not working

I tried to make a script that kicks or mutes a player for certain words, but nothing works. Any tips? I tried using the AI and nothing worked.

local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")

print("[Anti-Hate-Script] Script started.")

-- List of banned hate speech phrases (all lowercase, no duplicates)
local bannedPhrases = {
    "rock",
    "Colest",
    "ali",
    "pool",
    "trash",
    "men",
    "dudeee",
    "gagaga",
    "menl",
    "baed",
    "bad",
    "tom",
    "air"
}

-- Track offenses and mute timers
local offenseCount = {}      -- userId → number
local mutedPlayers = {}      -- userId → unmuteTime (tick)

-- Normalize text (lowercase, trim spaces)
local function cleanMessage(msg)
    local cleaned = string.lower((msg:gsub("%s+", " ")):gsub("^%s*(.-)%s*$", "%1"))
    print("[Anti-Hate-Script] Cleaned message: '" .. cleaned .. "'")
    return cleaned
end

-- Helper to check if message contains any banned phrase
local function containsBannedPhrase(msg)
    for _, phrase in bannedPhrases do
        if string.find(msg, phrase, 1, true) then
            print("[Anti-Hate-Script] Banned phrase detected: '" .. phrase .. "' in message: '" .. msg .. "'")
            return true, phrase
        end
    end
    return false, nil
end

-- Handler for incoming chat messages
local function onIncomingMessage(message)
    print("[Anti-Hate-Script] Incoming message event triggered.")
    if not message.TextSource then
        print("[Anti-Hate-Script] message.TextSource missing, returning original message.")
        return message
    end

    local player = Players:GetPlayerByUserId(message.TextSource.UserId)
    if not player then
        print("[Anti-Hate-Script] Player not found for UserId: " .. tostring(message.TextSource.UserId))
        return message
    end

    local userId = player.UserId
    local msg = cleanMessage(message.Text)

    -- If muted, suppress chat message
    if mutedPlayers[userId] and tick() < mutedPlayers[userId] then
        print("[Anti-Hate-Script] Player " .. player.Name .. " is currently muted. Message suppressed.")
        return nil
    end

    -- Check for banned phrases
    local found, phrase = containsBannedPhrase(msg)
    if found then
        offenseCount[userId] = (offenseCount[userId] or 0) + 1
        local offenses = offenseCount[userId]

        if offenses == 1 then
            mutedPlayers[userId] = tick() + 30
            print("[MODERATION] " .. player.Name .. " warned for hate speech (1st offense). Muted 30s.")
            return {
                Text = player.Name .. " has been warned for hate speech. Text suspended for 30 seconds.",
                TextChannel = message.TextChannel,
                PrefixText = message.PrefixText,
                Metadata = message.Metadata,
            }
        elseif offenses == 2 then
            mutedPlayers[userId] = tick() + 60
            print("[MODERATION] " .. player.Name .. " warned again for hate speech (2nd offense). Muted 60s.")
            return {
                Text = player.Name .. " has been warned again for hate speech. Text suspended for 1 minute.",
                TextChannel = message.TextChannel,
                PrefixText = message.PrefixText,
                Metadata = message.Metadata,
            }
        else
            print("[MODERATION] " .. player.Name .. " kicked for repeated hate speech (3rd offense).")
            player:Kick("You have been kicked for repeated hate speech.")
            return nil
        end
    end

    -- If clean, show message normally
    print("[Anti-Hate-Script] Message from " .. player.Name .. " passed moderation.")
    return message
end

-- Connect to TextChatService event
if TextChatService.OnIncomingMessageReceived then
    print("[Anti-Hate-Script] Using TextChatService.OnIncomingMessageReceived event.")
    TextChatService.OnIncomingMessageReceived:Connect(function(message)
        local result = onIncomingMessage(message)
        if result == nil then
            print("[Anti-Hate-Script] Message destroyed (suppressed).")
            message:Destroy()
        elseif type(result) == "table" then
            print("[Anti-Hate-Script] Message replaced with warning text.")
            message.Text = result.Text
        end
    end)
else
    -- Fallback for legacy chat (if needed)
    print("[Anti-Hate-Script] TextChatService.OnIncomingMessageReceived not found. Please enable TextChatService.")
end

1 Like

question: how does ‘air’ relate to hate speech

I made a muslim avatar store so I’ll replace the words ppl normally say in it instead of that when it works. So like pork or something uk.

1 Like

Scripting Support

2 Likes

Can you give more specfics, which part isn’t working?

nothing is working here, For example. I say those words nothing happens or prints.

Quick question: Is this the script you made or something the AI made to try to help you?

Just wanna know if this is the script you wanna edit or if you’re tryna make a new one

p.s. OnIncomingMessageReceived isn’t a member of textchatserv

ik how to kick players but for the mute part I used roblox ai which broke everything. I’m trying to edit to fix it but have no clue what to do.

Alright! TextChatService relies heavily on the client, so you need a server script and a local script

I’ll see if I can help you build the foundation of it.

To start off:

To detect when a player has chatted on the server, you’ll have to call the Player.Chatted event instead of TextChatServ

Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		--function
	end)
end)

Chat Censoring
If you wanna chat filter, you would have to filter it from the client. something like this:

--Make sure this is in a client-sided script

local mod_Message = "<b>[Message removed by moderation]</b>"

local bannedPhrases = {
	"this is a very obscene, vulgar, and offensive message! 😱",
}

local function DetectBannedPhrase(message)
	for _, phrase in pairs(bannedPhrases) do
		if message:lower():find(phrase) then
--[[you'll prolly wanna check for surrounding letters/spaces to make sure it's not
inside another word]]--
			return true
		end
	end
	return false
end

TextChatServ.OnIncomingMessage = function(message)
	if DetectCensoredPhrase(message.Text) then
		message.Text = mod_Message
	end
end

Muting players
You can simply send an event from the server whenever a player is muted or unmuted, and disable/enable their inputbar accordingly. example:

muteEvent.OnClientEvent:Connect(function(muted)
	TextChatServ.ChatInputBarConfiguration.Enabled = not muted
end)

Tracking player status
If you want to keep track of the player’s status, you can make a table that holds all of the players’ information. Something like this:

local PlayerStatus = {}

Players.PlayerAdded:Connect(function(player)
	local Status
--you'll prolly wanna check it incase they rejoin
	if PlayerStatus[player.UserId] == nil the
		Status = {
			Muted = false,
			Offenses = 0,
			Kicked = false
		}
		PlayerStatus[player.UserId] = Status
	else
		Status = PlayerStatus[player.UserId]
		if Status.Kicked == true then
			player:Kick("You are no longer allowed in this server!")
			return
 
		end
	end
end)

If you have any more questions (or something doesn’t work), just ask me! :))
p.s.if you wanna keep em from terrorising other servers for the day, use datastoreserv