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);