Note: Please give feedback in the comments. I am a relatively new scripter
Message history saving in action.
I made an instant messaging service in ROBLOX. Possibly the first messenger that saves message history. Before I explain how I did it to the curious people in the back, let’s explore the history of MessageService and chat:
On February 24, 2019, a ROBLOX developer asked (How do I make a cross-server chat?) how he can go about making a cross-server chat system. The users in that thread mentioned DataStore and web requests. At that time, MessagingService was only on the 2019 Roadmap, not to be implemented until it was released for Beta in March. On April 25, 2019, ForeverHD showed off (MessagingService: Creating an 'infinite player server') a new game called Room 201. The game only had 1-player servers, yet other players were in the game. Their body part positions were sent at rapid speeds (<1s delay) to other servers, forming the illusion that the server has many players.
Over time, many cross-server chat systems were created for individual games. So I started making my own, but I wanted to create a full-on messenger. One where you can choose who to message, provided that the person is online. Of course, this is a stupid idea because there is a lot of limitations making a messenger on ROBLOX. First, there is not calling/video chat, which is a very popular feature with messengers. Second, there is no file sharing, which is a popular feature for Internet Relay Chats. Third, there cannot be a notification system that disrupts your daily life.
But this is a cool type of creation. I will call it a “novelty game”.
Group DM creation as seen in-game
The way I handled messages was simple. When you make a new message, a key of that message appears in an OrderedDataStore. The message data is stored in a seperate DataStore. The scopes of those datastores (a place where the data is organized into) is the ID of the group. Message data:
local msgdata = {
["Sender"] = tonumber(player.UserId),
["Message"] = filtered,
["ID"] = id,
}
Once a player that is in the group logs on, they will load all the pages of the OrderedDataStore (from newest to oldest, up to an amount of messages) and load the messages from the DataStore. The keys of all the messagedata match the keys of the OrderedDataStore. Once the loading is finished, the player subscribes to their own userid and starts to take in messages in real-time. Messages can include group invites, notifications of someone leaving, and of course, messages. When you post a message, you publish that message to all the userids in that server. Here is how the messages are handled:
local connection = messagingService:SubscribeAsync(mainplayer.UserId, function(undecodeddata)
local data = HttpService:JSONDecode(undecodeddata.Data)
if data["Message"] then -- if it is a message
print ("Message from".. data["ID"])
RS.Remotes.IncomingMessage:FireClient(mainplayer,data)
elseif data["Members"] then -- if it is an invitation to a group
print ("Invite to".. data["ID"])
RS.Remotes.GroupInv:FireClient(mainplayer,data)
elseif data["Kick"] then -- if someone is removed from the group
local groupdatastore = DS:GetDataStore(joineddatastore)
local groups = groupdatastore:GetAsync(mainplayer.UserId)
local kicked = data["Kick"]
local groupid = data["ID"]
local thegroup = nil
print ("Kick".. data["Kick"].." from " ..data["ID"])
for _,group in pairs (groups) do
if group["ID"] == data["ID"] then
for i,v in pairs (group["Members"]) do
if v == kicked then
print ("Removed member")
table.remove(group["Members"],i)
thegroup = group
groupdatastore:SetAsync(mainplayer.UserId,groups)
RS.Remotes.ForgetPlayer:FireClient(mainplayer,thegroup)
return
end
end
end
end
end
end)
The DataStore saves all the messages that were put on the group. The MessagingService puts up new messages real-time and gives feedback to the client that their message was sent.
Here is the game by the way: https://www.roblox.com/games/4844791293/Messenger-UI-Concept
Here is some things that I could have done:
- Maybe find a way to optimize DataStore requests before continuing?
- OOP
- Hold the server open until all the save requests are done so that messages are not deleted (going to find out how that is possible soon)
Make sure to give feedback! Bye!