Global Announcement (MessagingService)

if point.difficulty == "Simple" then
    local MessagingService = game:GetService("MessagingService")
    local AnnouncementTopic = "GlobalAnnouncement"

    MessagingService:SubscribeAsync(AnnouncementTopic, function(message)
        local data = message.Data
        if data.Message then
            ReplicatedStorage.Message:FireAllClients(data.Message, data.Color)
        end
    end)

    MessagingService:PublishAsync(AnnouncementTopic, {
        Message = "[GLOBAL] " .. player.Name .. " has passed the difficulty " .. point.difficulty .. " and therefore beaten the game.. for now.",
        Color = point.color
    })
else
    ReplicatedStorage.Message:FireAllClients(
        player.Name .. " has passed the difficulty " .. point.difficulty .. "!",
        point.color
    )
end

This is not working. My goal is to get the RemoteEvent to fire in every server but it won’t work.

Output:

MessagingService:PublishAsync(): Cannot publish Dictionary, can only accept valid UTF-8 characters.  -  Server - DifficultyMessager:82

Error Line:

MessagingService:PublishAsync(AnnouncementTopic, {


If someone could help, I would appreciate it.

3 Likes

I never used it, but it seems you cannot publish dictionaries. You can try making it with rich text. turn second argument into a string with

<font color="#your color">your text</font>

if you want your message to be colored. Rich Text Markup | Documentation - Roblox Creator Hub

1 Like

JSONEncode and JSONDecode is the right choice for you.

2 Likes

And how would that look. It’s not everyday I use Messaging Service. :grimacing:

if point.difficulty == "Simple" then
    local MessagingService = game:GetService("MessagingService")
    local AnnouncementTopic = "GlobalAnnouncement"

    MessagingService:SubscribeAsync(AnnouncementTopic, function(message)
        local data = game:GetService("HTTPSerivce"):JSONDecode(message)
        if data.Message then
            ReplicatedStorage.Message:FireAllClients(data.Message, data.Color)
        end
    end)

    MessagingService:PublishAsync(AnnouncementTopic, game:GetService("HTTPService"):JSONEncode({Message = "[GLOBAL] " .. player.Name .. " has passed the difficulty " .. point.difficulty .. " and therefore beaten the game.. for now.", Color = point.color)})
else
    ReplicatedStorage.Message:FireAllClients(
        player.Name .. " has passed the difficulty " .. point.difficulty .. "!",
        point.color
    )
end

Something like this. I am not too much of a pro at httpservice but this should work?

You shouldn’t publish all this text, because that is hardcoded. Instead, make the message during SubscribeAsync.

What should PublishAsync be then?

Sidenote: MessagingService does have documentation but not the best one, so it gets a little trickier.

It should be a JSON enconded dictionary containing data you need to use for the global announcement, like the player who made it, and the text. You can decode it in SubscribeAsync.

1 Like

Yeah, but I am confused. What should PublishAsync() contain then?

This is how it currently looks:

MessagingService:PublishAsync(
    AnnouncementTopic,
    HttpService:JSONEncode({
        Message = "[GLOBAL] " ..
                  player.Name ..
                  " has passed the difficulty " ..
                  point.difficulty ..
                  " and therefore beaten the game.. for now.",
        Color = point.color,
    })
)

And this is how SubscribeAsync() looks:

MessagingService:SubscribeAsync(AnnouncementTopic, function(message)
    local data = HttpService:JSONDecode(message)

    local announcement = HttpService:JSONEncode({
        Message = "[GLOBAL] " ..
            player.Name ..
            " has passed the difficulty " ..
            point.difficulty ..
            " and therefore beaten the game.. for now.",
        Color = point.color,
    })

    if data.Message then
        ReplicatedStorage.Message:FireAllClients(data.Message, data.Color)
    end
end)

This would be my approach.

local DefaultMessages = {
    BeatGame = "{player} has passed the difficulty %s and beat the game... for now.",
    Default = "{player}: %s",
}
local data = {
    Name = player.Name, 
    UserId = player.UserId
    Type = "BeatGame",
    Args = {point.difficulty},
}

MessagingService:PublishAsync(AnnouncementTopic, HttpService:JSONEncode(data))
MessagingService:SubscribeAsync(AnnouncementTopic, function(m)
    local data = HttpService:JSONDecode(m.Message)
    local f = DefaultMessages[data.Type] or DefaultMessages.Default
    f = f:gsub("{player}", "@" .. data.Name)
    
    for i, v in pairs(data.Args) do
        data.Args[i] = tostring(v)
    end

    f = f:format(unpack(data.Args))

    ReplicatedStorage.Message:FireAllClients(f, Color3.new(1,1,0))
end)
1 Like

Nothing was sent out.

Only this part worked when it was not Simple

No errors in the output.

Current script:

if point.difficulty == "Simple" then
    local DefaultMessages = {
        BeatGame = "{player} has passed the difficulty %s and beat the game... for now.",
        Default = "{player}: %s",
    }

    local MessagingService = game:GetService("MessagingService")
    local AnnouncementTopic = "GlobalAnnouncement"

    local data = {
        Name = player.Name,
        UserId = player.UserId,
        Type = "BeatGame",
        Args = { point.difficulty },
    }

    MessagingService:PublishAsync(AnnouncementTopic, HttpService:JSONEncode(data))

    MessagingService:SubscribeAsync(AnnouncementTopic, function(m)
        local data = HttpService:JSONDecode(m.Message)
        local f = DefaultMessages[data.Type] or DefaultMessages.Default
        f = f:gsub("{player}", "@" .. data.Name)

        for i, v in pairs(data.Args) do
            data.Args[i] = tostring(v)
        end

        f = f:format(unpack(data.Args))

        ReplicatedStorage.Message:FireAllClients(f, Color3.new(1, 1, 0))
    end)
else
    ReplicatedStorage.Message:FireAllClients(
        player.Name .. " has passed the difficulty " .. point.difficulty .. "!",
        point.color
    )
end

For some of the respondents above, please stop suggesting that dictionaries can’t be passed to PublishAsync: read the docs and the error message. The error keyphrase is can only accept valid UTF-8 characters. OP, with your original code, what is the type of color? You can add it just before publishing your message: print(typeof(point.color)).

PublishAsync can only accept valid UTF-8 characters and serialisable datatypes, so I have a strong feeling that you’re sending a Color3 through PublishAsync and it can’t serialise the colour.

JSONEncode is bloat and unnecessary here.

This is the results:

  1. Print print(typeof(point.color)) [:white_check_mark:]
    image
    image

Sorry for wrong response, i think what he said is true. You should be able to send dictionaries but turn your color3 into a hex value, so it fits UTF-8.

Like this?

You can’t send Color3 through MessagingService. Opt to send the colour components instead.

-- As:
local r, g, b = point.color.R, point.color.G, point.color.B

-- Or:
local h, s, v = point.color:ToHSV()

-- Or:
local hex = point.color:ToHex()

Color3.