TextChatMessage turns into an instance in script

I’m trying to set a custom bubble chat config for a phone I’ve programmed and something i’ve noticed is that messages recieved during TextChatService.SendingMessage is that the message at some point stops being a TextChatMessage and is instead an instance.

TextChatService.SendingMessage:Connect(function(message: TextChatMessage)
	local isInZoneOfPhone = valueFolder.isInZoneOfPhone.Value
	local callingPhone = valueFolder.callingPhone.Value
	
	local recievingPhone = nil
	
	if isInZoneOfPhone == true then
		for _,v in PhoneNumbers do
			if callingPhone ~= "" and v.Name == callingPhone then
				recievingPhone = v
			end
		end
		
		if recievingPhone ~= nil and recievingPhone:GetAttribute("hasPickedUp") == true then
			print(typeof(message))
			SendMessageEvent:FireServer(message, recievingPhone.PhonePart)
		end
	end
	
end)


SendMessageEvent.OnClientEvent:Connect(function(message: Instance, phone: Part)
	TextChatService:DisplayBubble(phone, message.Text)
end)

Printing the typeof the message returns instance and that makes it so I can’t send the message through a remote event for configuration

2 Likes

I believe that it remains a TextChatMessage.
When doing typeof(), it will return “Instance” for basically any object that you pass (it will give different results if you give it a string or a number, for example).
If you want to check if it is indeed a TextChatMessage, you would need to use message.ClassName.

Ah you’re right, it does remain a textchatmessage. But I still have an issue, When I pass it through a remote event it becomes nil

SendMessageEvent.OnServerEvent:Connect(function(player, message: TextChatMessage, phone: Part)
	print(message.ClassName)
	SendMessageEvent:FireAllClients(message, phone)
end)

The second print(message.ClassName) in this part of the script causes the error: “attempt to index nil with ClassName”

I don’t believe that your use of .SendingMessage is correct for what you are trying to do.
Can you please clarify your intentions (just so I’m on the same page), and I’ll see if there’s a more appropriate way to achieve it.

Well currently I’m coding communication between 2 phones. When the player sends a message when close to the phone it will show the message in a bubble chat above the receiving phone

I don’t believe you can send the TextChatMessage from the client to the server via remote events.

If you want to detect the message on the server side, I found 2 possible options (events):

  • utilising Player.Chatted (although this only contains the text in the message, rather than the TextChatMessage.)
  • Utilising TextChannel.OnIncomingMessage / TextChannel.ShouldDeliverCallback

This should allow you to get the message on the server, to then send it out to the clients.

(I’ve not messed around with TextChatService much, so this may be inaccurate)

I need textchatmessage to customize the bubblechat and onincomingmessage is client-only (also i believe thats for receiving messages

The TextChatMessage is an instance created on the client; thus it cannot be transferred via remote events.

However, your code just uses message.Text, so why don’t you just fire the string instead?

You could probably also just rewrite your system to not need a remote event, too. If rewrote, you could simply hook the bubble chat creation into the same function as the rest of the code.

For example:

if message.TextSource and message.TextSource.UserId == recievingPhone:GetAttribute("RecievingPlayer") then
    TextChatService:DisplayBubble(recievingPhone.PhonePart, message.Text)
end
  • I’m not actually in studio rn so I can’t verify is this is correct.

That’s a smart idea. But I need the bubble chat to appear for everyone as its a universal phone

Alright, well then, another solution around it is to get the player sending the message, and then read data from the player to see if they’re calling someone, if they are, then find and display the text bubble on the target phone.

For example:

if not message.TextSource or not message.TextSource.UserId then return end

local sendingPlayer = game.Players:GetPlayerFromUserId(message.TextSource.UserId)
if sendingPlayer:GetAttribute("OnCallWith") end
    local callingPlayer = game.Players:GetPlayerFromUserId(sendingPlayer:GetAttribute("OnCallWith"))
    if not callingPlayer then return end
    
    local callingPhone = callingPlayer.Character:FindFirstChild("Phone")
    if not callingPhone then return end
    
    TextChatService:DisplayBubble(callingPhone.PhonePart, message.Text)
end

Will check if this works. My phone isn’t like a mobile phone or anything it’s like a phonebooth phone

Alright, well maybe then just create an ObjectValue for each player that points to each corresponding PhonePart, or again just writing a system to find what phone part is the one to send to.