Overwriting Chat message content on each Client

So I’ve got this in my Chat:

structure

One of my Server Scripts posts Chat messages with selected speaker. I wanted to make the content of the message unique for each Player (translate the message for each Player).

To show you what I mean here is an example:

  • Player1 has got his language settings in my game set to English, the message doesn’t get translated for him,
  • Player2 has got his language settings in my game set to German, for example, the message gets transated for him.

Here is a similar topic on this (I’ve messed up something when I touched the Script): How could I edit a message in the roblox chat? - #15 by Decker004

Let’s say that each Player has his Folder in ServerStorage > PlayerValues (example: ServerStorage > PlayerValues > Jermartynojm) and there is a String Value named ‘Language’. Default one is ‘English’, custom one is ‘English2’.

Here is what I’ve made so far (note that it is not completed):

-- Server-side module-script for the chat-system's `ChatModules` folder
local function Run(ChatService)
	local ReplicatedStorage = game:GetService("ReplicatedStorage")

	-- Found the chat system's remote-events folder, by looking in ChatServiceRunner server-script code
	local EventFolderName = "DefaultChatSystemChatEvents"
	local EventFolder = ReplicatedStorage:FindFirstChild(EventFolderName)

	-- The OnMessageDoneFiltering remote-event can be used to make chat's localscript replace a previously sent message.
	local RemoteEventName = "OnMessageDoneFiltering"
	local OnMessageDoneFiltering = (EventFolder and EventFolder:FindFirstChild(RemoteEventName)) or nil
	
	local Messages = {}
	
	local function HandleMessage(handlerId)
		--OnMessageDoneFiltering:FireAllClients(messageObj, channelName)
	end
	
	local function Main(speakerName, messageObj, channelName)
		table.insert(Messages, 
			{
				messageObj = messageObj,
				originalMessageText = messageObj.Message,
				channelName = channelName,
				speakerName = speakerName,
			}
		)
		messageObj.Message = "test"
	end
	
	if OnMessageDoneFiltering then
		ChatService:RegisterFilterMessageFunction("MainFunction", Main)
		local f = coroutine.wrap(function()
			HandleMessage()
		end)
		f()
	else
		error("Could not find needed remote-event `" .. RemoteEventName .. "`.")
	end
end

return Run

How would I go about translating message with selected speaker (example: ‘TestSpeaker’) for each Player? So Players with Value set to ‘English’ would have the message not translated for them and the ones with ‘English2’ would have the message changed to ‘Hello’.

3 Likes

Hi,

I don’t know how you can edit the message, but i got an idea. What if you just did FireAllClients on server and on client you translate given string (You can have a module scripts for every language and this module script will contain pre-made translated strings, your string is a key and value will be a translated one) then after you got translated string you do SetCore:ChatMakeSystemMessage with Text key set to your translated string.

1 Like

The problem is that I use game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner"):WaitForChild("ChatService") and stuff for making the message. I do not fire the event.

Edit: I know that it would be 100 times easier with firing the event.

That’s why i suggested my idea, because i don’t know how you can change the message. And with my way each client will send its own message which will be seen only for them, so if server did FireAllClients("Hello World!) Player1, who have English selected, will send message without changes and Player2 who have German selected will have a translated message - “Hallo Welt!” (I used google translator, to show how it will be in German, sorry if its not right!).

It looks like I would have to rescript the message suystem. Anyways, thank you for posting.

I don’t know if this is right either.

Hey there,
This is the code that I wrote for your case, here I don’t translate any text because I was looking and couldn’t find anything free, anyways, the way that I decided to check what language wants the player to translate the text is creating a stringValue in the playerObject. Now here is almost the same code as yours, what it does is register the filterFunction and then will send the translated message to every player according with the stringValue previously mentioned.

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

local function Run(ChatService)
	local EventFolderName = "DefaultChatSystemChatEvents"
	local EventFolder = ReplicatedStorage:FindFirstChild(EventFolderName)

	local RemoteEventName = "OnMessageDoneFiltering"
	local OnMessageDoneFiltering = EventFolder and EventFolder:FindFirstChild(RemoteEventName)

	local function TranslateToPlayers(speakerName, messageObj, channelName)
		local OriginalMessage = messageObj.Message
		
		--I put a wait here with 0.05 as argument because
		--it seems to not work with just a wait()
		coroutine.wrap(function()
			wait(0.05)
			
			--Iterate over all players and send their translated message.
			for _, player in ipairs(Players:GetPlayers()) do
				local lang = player:FindFirstChild("Language") 

				if lang and lang:IsA("StringValue") then 
					--Here you'll send them your translated message
					messageObj.Message = lang.Value..": "..OriginalMessage
					
					--Fire only the player with the translated message
					OnMessageDoneFiltering:FireClient(player, messageObj, channelName)
				end
			end
		end)()
	end

	if OnMessageDoneFiltering then
		ChatService:RegisterFilterMessageFunction("TranslateToPlayers", TranslateToPlayers)
	else
		error("Could not find needed remote-event `" .. RemoteEventName .. "`.")
	end
end

return Run

There are some problems with the Script:

  • the message’s color disappears (it can probably be fixed → messageObj.Something property)
  • there is this wait() that I don’t like (what if function runs after that time?)
  • I check for speaker’s name when I want to translate text (the system would collide with speaker with selected name).

If you wondered how I remixed your Script:
roblox chat testing.rbxl (23.7 KB)

I would probably stick with the remotes in this case (it would cost me rescripting my Module but whatever).