ChatService:GetSpeaker is returning nil

Hello everyone! Recently, I’ve been attempting to implement chat tags into my game.

However, ChatService:GetSpeaker(player.Name) always returns nil and I don’t understand why that’s happening. I’m using the standard chat system. Nothing has been modified. And it has been ran on studio, in case that changes anything.

Here’s the script I’m using to give tags to the players:

local Players = game:GetService('Players')
local Chat = game:GetService('Chat')
local ChatService = require(Chat:WaitForChild('ChatServiceRunner'):WaitForChild('ChatService'))


Players.PlayerAdded:connect(function(player)
	local PlayerPermissions = _G.PermissionsTable[player.UserId]
	print(PlayerPermissions)
	if PlayerPermissions == nil or PlayerPermissions > 6 or PlayerPermissions < 0 then
		PlayerPermissions = 0
		_G.PermissionsTable[player.UserId] = 0
	end
	local speaker
	local MaxTries = 5
	local Tries = 0
	while not speaker do
		if Tries < MaxTries then
			print("Infinite loop here")
			speaker = ChatService:GetSpeaker(player.Name)
  			wait()
			Tries = Tries + 1
		else
			break
		end
	end
	if speaker.PlayerPermissions > 0 then
		speaker:JoinChannel("Staff")
	end
	if speaker.PlayerPermissions > 3 then
		speaker:JoinChannel("Developer")
	end
	speaker:SetExtraData("Tags", {{ TagText = SpecialTagTable[PlayerPermissions][1], TagColor = SpecialTagTable[PlayerPermissions][2] }})
  	speaker:SetExtraData("NameColor", SpecialTagTable[PlayerPermissions][2])
end)

Yes, I do know that another post was made about the same behavior. However, it appeared to be caused by a different issue.

I always use the ChatService.SpeakerAdded event and never get any problems, how about you try it.

1 Like

This is happening because you’re referencing the ChatService under the Chat service. This is only a holding container for the Chat scripts and is static (scripts don’t run). The proper way to get the ChatService is through ServerScriptService.

If you’re interested in doing this a better way as well, you should look into using the actual ChatService events. That means you should be using SpeakerAdded instead of PlayerAdded. Getting the associated player is a valid method of the ChatSpeaker class so work in terms of the speaker. This will also, in turn, get rid of the need to use weird guards in your code such as the retry fetch system.

local ChatService = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner").ChatService)

local function speakerAdded(speakerName)
    local speaker = ChatService:GetSpeaker(speakerName)
    local player = speaker:GetPlayer()

    if not player then return end

    -- Ew, _G. Use a ModuleScript or ExtraData instead. Or attributes when they're here.
    local playerPermissions = _G.PermissionsTable[player.UserId]
    if not playerPermissions or playerPermissions > 6 or playerPermissions < 0 then
        playerPermissions = 0
        _G.PermissionsTable[player.UserId] = 0
    end

    -- Can't use speaker.PlayerPermissions without setting it
    -- Might as well use the variable since you have it as well
    if playerPermissions > 0 then
        speaker:JoinChannel("Staff")
    end
    if playerPermissions > 3 then
        speaker:JoinChannel("Developer")
    end
    -- Do your tag setting here; pretty sure you have some variable shadowing going on
end

ChatService.SpeakerAdded:Connect(speakerAdded)
for _, speaker in ipairs(ChatService:GetSpeakerList()) do
    speakerAdded(speaker)
end
7 Likes

Thanks, that solved it. speaker.playerPermissions was a mistake. Thanks for pointing it out.