If you want to create an actual speaker (an entity that typically represents a user but isn’t restricted to representing a user), you can use ChatService:AddSpeaker() (the one that’s replicated under ServerScriptService) to create a new speaker, controlled by the server like so:
local chatService = require(script.Parent:WaitForChild('ChatServiceRunner'):WaitForChild('ChatService'))
task.wait(10)
local speaker = chatService:AddSpeaker('Chat bot')
speaker:JoinChannel('All')
speaker:SayMessage('Hey!', 'All')

Much like a player, you can also make this bot have tags like this:
speaker:SayMessage('Hey!', 'All', {
-- here is where the extra data (like chat tags and chat colour) go
Tags = {
{
-- you can also add multiple tags like so
TagText = 'Bot';
TagColor = Color3.new(1,1,0);
};
{
TagText = 'Cool';
TagColor = Color3.new(1,0,0);
}
};
ChatColor = Color3.new(0.5,0.5,0.5);
NameColor = Color3.new(1,0,1)
})

Or, you can assign extra data to the speaker like so:
speaker:SetExtraData('Tags', {
{
TagText = 'Bot';
TagColor = Color3.new(1,1,0);
};
{
TagText = 'Cool';
TagColor = Color3.new(1,0,0);
}
}
)
speaker:SetExtraData('ChatColor', Color3.new(0.5,0.5,0.5))
speaker:SetExtraData('NameColor', Color3.new(1,0,1))
