Status #

Nakama users can set a status message when they connect and update it while they’re online.

Users can follow each other to be notified of status changes. This is ideal to know when their friends are online and what they’re up to.

The status is set for each connection, and is erased when the user disconnects. If the user is connected from multiple devices each one is allowed to have a different status.

Set a status #

By default users have no status when they first connect, and will not appear online to their followers. To appear online the user must set a status.

A status can be as simple as a text message from the user to their followers or it can be a structured JSON string with complex information such as the real-time multiplayer match ID the user is currently in - so their friends can jump in and join them!

Code snippet for this language Swift has not been found. Please choose another language to show equivalent examples.
Client
1
socket.updateStatus("Hello everyone!");
Client
1
await socket.UpdateStatusAsync("Hello everyone!");
Client
1
rtClient->updateStatus("Hello everyone!");
Client
1
socket.updateStatus("Hello everyone!").get();
Client
1
2
3
4
5
var update : NakamaAsyncResult = yield(socket.update_status_async(JSON.print({"status": "happy"})), "completed")
if update.is_exception():
    print("An error occurred: %s" % update)
    return
print("Status updated")
Client
1
2
3
4
5
var update : NakamaAsyncResult = await socket.update_status_async(JSON.stringify({"status": "happy"}))
if update.is_exception():
    print("An error occurred: %s" % update)
    return
print("Status updated")
Client
1
socket.status_update(socket, "Hello everyone!")

Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

The status can be set and updated as often as needed with this operation.

Appear offline #

If the user needs to appear offline or “invisible” they can do so by erasing their status. Their followers will receive the same status update as they would if the user disconnects.

Code snippet for this language Swift has not been found. Please choose another language to show equivalent examples.
Client
1
socket.updateStatus();
Client
1
await socket.UpdateStatusAsync(null);
Client
1
rtClient->updateStatus("");
Client
1
socket.updateStatus(null).get();
Client
1
2
3
4
5
var leave : NakamaAsyncResult = yield(socket.update_status_async(""), "completed")
if leave.is_exception():
    print("An error occurred: %s" % leave)
    return
print("Status updated")
Client
1
2
3
4
5
var leave : NakamaAsyncResult = await socket.update_status_async("")
if leave.is_exception():
    print("An error occurred: %s" % leave)
    return
print("Status updated")
Client
1
socket.status_update("")

Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

Receive status updates #

When a user updates their status all of their followers receive an event that contains both the old status and the new one. Clients register an event handler to be called when receiving a status update.

Code snippet for this language Swift has not been found. Please choose another language to show equivalent examples.
Client
1
2
3
4
5
6
7
8
socket.onstatuspresence = (statuspresence) => {
    statuspresence.leaves.forEach((leave) => {
        console.log("User %o no longer has status %o", leave.user_id, leave.status);
    });
    statuspresence.joins.forEach((join) => {
        console.log("User %o now has status %o", join.user_id, join.status);
    });
};
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
socket.ReceivedStatusPresence += presenceEvent =>
{
    Console.WriteLine(presenceEvent);
    foreach (var joined in presenceEvent.Joins)
    {
        Console.WriteLine("User id '{0}' status joined '{1}'", joined.UserId, joined.Status);
    }
    foreach (var left in presenceEvent.Leaves)
    {
        Console.WriteLine("User id '{0}' status left '{1}'", left.UserId, left.Status);
    }
};
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
rtListener->setStatusPresenceCallback([](const NStatusPresenceEvent& event)
{
    for (auto& presence : event.leaves)
    {
        std::cout << "User " << presence.username << " no longer has status " << presence.status << std::endl;
    }

    for (auto& presence : event.joins)
    {
        std::cout << "User " << presence.username << " now has status " << presence.status << std::endl;
    }
});
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
SocketListener listener = new AbstractSocketListener() {
    @Override
    public void onStatusPresence(final StatusPresenceEvent presence) {
        for (UserPresence userPresence : presence.getJoins()) {
            System.out.println("User ID: " + userPresence.getUserId() + " Username: " + userPresence.getUsername() + " Status: " + userPresence.getStatus());
        }

        for (UserPresence userPresence : presence.getLeaves()) {
            System.out.println("User ID: " + userPresence.getUserId() + " Username: " + userPresence.getUsername() + " Status: " + userPresence.getStatus());
        }
    }
};
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
func _ready():
    # First, setup the socket as explained in the authentication section.
    socket.connect("received_status_presence", self, "_on_status_presence")

func _on_status_presence(p_presence : NakamaRTAPI.StatusPresenceEvent):
    print(p_presence)
    for j in p_presence.joins:
        print("%s joined with status: %s" % [j.user_id, j.status])
    for j in p_presence.leaves:
        print("%s left with status: %s" % [j.user_id, j.status])
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
func _ready():
    # First, setup the socket as explained in the authentication section.
    socket.received_status_presence.connect(self._on_status_presence)

func _on_status_presence(p_presence : NakamaRTAPI.StatusPresenceEvent):
    print(p_presence)
    for j in p_presence.joins:
        print("%s joined with status: %s" % [j.user_id, j.status])
    for j in p_presence.leaves:
        print("%s left with status: %s" % [j.user_id, j.status])
Client
1
2
3
4
5
6
7
8
socket.on_status_presence_event(function(presences)
    for i,leave in ipairs(presences.leaves) do
        print(("User %s no longer has status %s"):format(leave.user_id, leave.status))
    end
    for i,join in ipairs(presences.joins) do
        print(("User %s now has status %s"):format(join.user_id, join.status))
    end
end)

Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

If a user is disconnected or appears offline, they will leave their previous status but there will be no corresponding new status.

Follow users #

Users only receive status updates from those they follow. Users can follow anyone they’re interested in, but it’s common to follow a list of friends to see when they’re online and what they’re up to.

When following a set of users, the operation will immediately return the status of those that are online and have set a visible status.

Following a user is only active with the current session. When the user disconnects they automatically unfollow anyone they may have followed while connected.

Code snippet for this language Swift has not been found. Please choose another language to show equivalent examples.
Client
1
2
3
4
var status = await socket.followUsers(["<user id>"]);
status.presences.forEach((presence) => {
  console.log("User %o has status %o", presence.user_id, presence.status);
});
Client
1
await socket.FollowUsersAsync(new[] { "<user id>" });
Client
1
2
3
4
5
6
7
8
9
auto successCallback = [](const NStatus& status)
{
    for (auto& presence : status.presences)
    {
        std::cout << "User " << presence.username << " has status " << presence.status << std::endl;
    }
};

rtClient->followUsers({ "<user id>" }, successCallback);
Client
1
socket.followUsers("<user id>").get();
Client
1
2
3
4
5
6
var user_ids = ["<user-id1>", "<user-id2>"]
var status : NakamaRTAPI.Status = yield(socket.follow_users_async(user_ids), "completed")
if status.is_exception():
    print("An error occurred: %s" % status)
    return
print(status)
Client
1
2
3
4
5
6
var user_ids = ["<user-id1>", "<user-id2>"]
var status : NakamaRTAPI.Status = await socket.follow_users_async(user_ids)
if status.is_exception():
    print("An error occurred: %s" % status)
    return
print(status)
Client
1
2
local user_ids = { "<user id>" }
socket.status_follow(user_ids)

Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

Unfollow users #

Unfollowing a set of users immediately stops the user from receiving any further status updates from them.

Code snippet for this language Swift has not been found. Please choose another language to show equivalent examples.
Client
1
socket.unfollowUsers(["<user id>"]);
Client
1
await socket.UnfollowUsersAsync(new[] { "<user id>" });
Client
1
rtClient->unfollowUsers({ "<user id>" });
Client
1
socket.unfollowUsers("<user id>").get();
Client
1
2
3
4
5
6
var user_ids = ["<user-id1>", "<user-id2>"]
var status : NakamaAsyncResult = yield(socket.unfollow_users_async(user_ids), "completed")
if status.is_exception():
    print("An error occurred: %s" % status)
    return
print(status)
Client
1
2
3
4
5
6
var user_ids = ["<user-id1>", "<user-id2>"]
var status : NakamaAsyncResult = await socket.unfollow_users_async(user_ids)
if status.is_exception():
    print("An error occurred: %s" % status)
    return
print(status)