Files
Valour-Bot-Guide/Guides/6.MemberInfo.md
2026-03-29 02:07:51 +01:00

6.2 KiB

Member Info

Now that we have commands with arguments, lets make them more personal by fetching info about the user who sent the message.

A bg/whoami command will reply with something like:

**Username:** SkyJoshua
**Display Name:** SkyJoshua
**User ID:** 15652354820931584
**Member ID:** 42170205766156288
**Roles:** Admin, Moderator, Member
**Joined Valour:** 01/01/2022 00:00:00
**Bot:** False

Fetching the member

Every Message has a FetchAuthorMemberAsync() method that returns a PlanetMember — the sender's membership on that planet. We always check if it's null before using it.

// Fetch the member object for the message author
PlanetMember member = await message.FetchAuthorMemberAsync();

if (member is null)
{
    await channel.SendMessageAsync("Could not find your member info!");
    return;
}

Getting the linked User

From the PlanetMember you can access the global User account directly via member.User. This gives you their username, ID, join date, and whether they are a bot.

// Get the linked user account
User user = member.User;

Reading member properties

Here are the useful properties available on member and user:

Property Description
user.Name Their global Valour username
member.Nickname Their planet-specific nickname (empty if not set)
user.Id Their global user ID
member.Id Their member ID on this planet
member.Roles The list of roles they have on this planet
user.TimeJoined When they created their Valour account
user.Bot Whether they are a bot account

Handling nicknames

A member may or may not have a nickname set on the planet. We fall back to their username when there isn't one.

// Use their nickname if they have one, otherwise fall back to their username
string displayName = string.IsNullOrWhiteSpace(member.Nickname) ? user.Name : member.Nickname;

Getting role names

member.Roles gives us the list of roles the member has. We can use LINQ to pull out each role's name and join them into a single string.

// Build a comma-separated list of the member's role names
string roleNames = string.Join(", ", member.Roles.Select(r => r.Name));

Putting it together

Here is the full whoami command using everything above:

else if (command == "whoami")
{
    // Fetch the member object for the message author
    PlanetMember member = await message.FetchAuthorMemberAsync();

    if (member is null)
    {
        await channel.SendMessageAsync("Could not find your member info!");
        return;
    }

    // Get the linked user account
    User user = member.User;

    // Use their nickname if they have one, otherwise fall back to their username
    string displayName = string.IsNullOrWhiteSpace(member.Nickname) ? user.Name : member.Nickname;

    // Build a comma-separated list of the member's role names
    string roleNames = string.Join(", ", member.Roles.Select(r => r.Name));

    // Build and send the info reply
    await channel.SendMessageAsync($@"
        **Username:** {user.Name}
        **Display Name:** {displayName}
        **User ID:** {user.Id}
        **Member ID:** {member.Id}
        **Roles:** {roleNames}
        **Joined Valour:** {user.TimeJoined}
        **Bot:** {user.Bot}
    ");
}



Full code below

using Valour.Sdk.Client;
using Valour.Shared;
using DotNetEnv;
using Valour.Sdk.Models;
using Valour.Shared.Models;

ValourClient client = new ValourClient("https://api.valour.gg/");
client.SetupHttpClient();

Env.Load();

string token = Environment.GetEnvironmentVariable("TOKEN") ?? string.Empty;

Dictionary<long, Channel> channelCache = new();

if (string.IsNullOrWhiteSpace(token))
{
    Console.WriteLine($"Token invalid. Please make sure you set a valid token in your .env");
    return;
}

TaskResult loginResult = await client.InitializeUser(token);
if (!loginResult.Success)
{
    Console.WriteLine($"Login failed: {loginResult.Message}");
}

Console.WriteLine($"Logged in as {client.Me.Name} (ID: {client.Me.Id})");

foreach (Planet planet in client.PlanetService.JoinedPlanets)
{
    await planet.EnsureReadyAsync();
    await planet.FetchInitialDataAsync();

    foreach (Channel chan in planet.Channels)
    {
        channelCache[chan.Id] = chan;

        if (chan.ChannelType == ChannelTypeEnum.PlanetChat)
        {
            await chan.OpenWithResult("YourBotName");
        }
    }
}

client.MessageService.MessageReceived += onMessageReceived;

async Task onMessageReceived(Message message)
{
    string prefix = "bg/";
    string content = message.Content;

    if (!channelCache.TryGetValue(message.ChannelId, out var channel)) return;
    if (!content.StartsWith(prefix)) return;

    string withoutPrefix = content.Substring(prefix.Length);
    string[] parts = withoutPrefix.Split(' ', StringSplitOptions.RemoveEmptyEntries);

    if (parts.Length == 0) return;

    string command = parts[0].ToLower();
    string[] args = parts.Skip(1).ToArray();

    if (command == "ping")
    {
        await channel.SendMessageAsync("Pong!");
    }
    else if (command == "whoami")
    {
        // Fetch the member object for the message author
        PlanetMember member = await message.FetchAuthorMemberAsync();

        if (member is null)
        {
            await channel.SendMessageAsync("Could not find your member info!");
            return;
        }

        // Get the linked user account
        User user = member.User;

        // Use their nickname if they have one, otherwise fall back to their username
        string displayName = string.IsNullOrWhiteSpace(member.Nickname) ? user.Name : member.Nickname;

        // Build a comma-separated list of the member's role names
        string roleNames = string.Join(", ", member.Roles.Select(r => r.Name));

        // Build and send the info reply
        await channel.SendMessageAsync($@"
            **Username:** {user.Name}
            **Display Name:** {displayName}
            **User ID:** {user.Id}
            **Member ID:** {member.Id}
            **Roles:** {roleNames}
            **Joined Valour:** {user.TimeJoined}
            **Bot:** {user.Bot}
        ");
    }
}

await Task.Delay(Timeout.Infinite);

The Next step is Permission Checking