Create Custom Chat Channels with TextChatService

Greetings,

Recently a friend of mine has questioned me how to create custom channels with the new Roblox chat system, however, after reading the documentation, there’s no objective way of doing so and implementing such feature isn’t very clear.

This tutorial aims to help people understand the new chat system better and allow to create custom channels.

The code I’m providing is just a way for people to study the TextChatService API, I will not be answering questions such as “How do I make it so only admins can join X channel”, this knowledge can be acquired by understanding the basis of the tutorial.

Set Up

In order to set up the custom channels that you’re going to use, first let’s create two folders inside TextChatService in the Explorer.

image

If you cannot find “TextChatService” in your Explorer, simply open the Command Bar and type

 game:GetService("TextChatService")

and the TextChatService should appear in your Explorer, mine is at the very bottom.

Creating the Channel

After creating the folders, we’re now going to create the custom channel that we want inside the CustomChannels folder.

image

Then, we’re going to name the Channel as we’d like.

image

Coloring the Channel

You can also choose your own color for the channel, to do so simply create an attribute named “Color” with type “Color3” and set the color for your channel. This is optional and if no color is specified, it’ll default to white.

image
image

Assigning command to open Channel

After naming the channel, we’re now going to assign a command to join that channel. To do so, head over to your CustomCommands folder and create a command like this:

image
image

Make sure to name the TextChatCommand instance with the same name as the Channel you’re assigning it to

image

Then, head down in its properties and change the “PrimaryAlias” property to the command you’d like to open this channel.
image

You can also use a SecondaryAlias, which is basically a different way to use the same command (similar to how you can use /team or /t for team chat), for the sake of testing I will be setting a SecondaryAlias to be a simpler version of PrimaryAlias, but it can be anything you want.

image

We’re using ‘/’ but you can use any prefix or no prefix, however messages that are detected as commands are NOT posted in chat!

Inserting the scripts to make everything work

Now that you have all your channels set up, you need to add in the scripts that will make it work.

Firstly, create a Remote Event in ReplicatedStorage called “ChatReplicate”

image

Secondly, create a Server Script in ServerScriptService called “ChatServer”

image

And paste this code inside of it:


local TextChatService = game:GetService("TextChatService")

local Commands = TextChatService:FindFirstChild("CustomCommands")
local Channels = TextChatService:FindFirstChild("CustomChannels")

local Remote = game:GetService("ReplicatedStorage"):WaitForChild("ChatReplicate")

for _ , command in pairs(Commands:GetChildren()) do
	command.Triggered:Connect(function(origin, unfiltered)
		
		--// Makes sure the command ran has a channel related to it
		if Channels:FindFirstChild(command.Name) then

			if Channels[command.Name]:FindFirstChild(origin.Name) then
				
				--// If user is in channel, remove user
				Channels[command.Name][origin.Name]:Destroy()
				
				--// Forces client to only send messages to Default Roblox Chat
				Remote:FireClient(game.Players:FindFirstChild(origin.Name), "RBXGeneral")
				
			else 
				
				--// If the user is not in the channel, add user
				Channels[command.Name]:AddUserAsync(origin.UserId)
				
				--// Forces client to only send messages to newly joined Channel
				Remote:FireClient(game.Players:FindFirstChild(origin.Name), command.Name)
				
			end
		end
		
	end)
end

Lastly, create a Local Script inside StarterPlayerScripts and paste this code inside of it:


local TextChatService = game:GetService("TextChatService")
local ChatBar = TextChatService:WaitForChild("ChatInputBarConfiguration")
local Remote = game:GetService("ReplicatedStorage"):WaitForChild("ChatReplicate")

--// Replicating server requests
Remote.OnClientEvent:Connect(function(ChannelName)
	
	--// Forces target text channel to assigned channel
	local Channel = TextChatService.CustomChannels:FindFirstChild(ChannelName) or TextChatService.TextChannels:FindFirstChild(ChannelName)
	ChatBar.TargetTextChannel = Channel
	
	--// Informs client of new channel
	if ChannelName == "RBXGeneral" then
		Channel:DisplaySystemMessage("You're now chatting on Default Chat.")
	else
		Channel:DisplaySystemMessage("You're now chatting on " .. ChannelName .. ".")
	end
	
end)

--// Adds the Channel Tag and Color when receiving messages from Channels different than Roblox Default
TextChatService.OnIncomingMessage = function(message: TextChatMessage)
	local properties = Instance.new("TextChatMessageProperties")

	if TextChatService.TextChannels:FindFirstChild(message.TextChannel.Name) then
		return
	end
	
	if message.TextSource then
		local player = game.Players:GetPlayerByUserId(message.TextSource.UserId)

		local ChannelColor = message.TextChannel:GetAttribute("Color") or {R = 1, G = 1, B = 1}

		properties.PrefixText = (string.format("<font color='rgb(%s, %s, %s)'>[%s] %s</font>",
			math.round(ChannelColor.R * 255),
			math.round(ChannelColor.G * 255),
			math.round(ChannelColor.B * 255),
			message.TextChannel.Name,
			message.PrefixText
			)
		)
	end

	return properties
end

And there you have it! Your own custom channels built-in Roblox Chat!

image

How to return to default channel after I joined a channel?

If you wish to leave a channel that you’ve joined, simply re-run the command to exit. Unfortunately, I could not implement the same behaviour as Team or Whisper Chat, whereas if you press Backspace it returns to Default Chat.

Hope this tutorial helps everyone!

Was this Tutorial Useful?

  • Yes
  • No
  • For Future Use

0 voters

4 Likes

This is cool and all but did they still not implement a ShowChannelBar system like in the old chat service?

I’ve noticed that some of the most basic features in roblox tend to be the most tedious to use… I wonder why.