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

3.7 KiB

Connecting and Sending a message to a Planet

After logging in and joining a planet, you need to open a real-time connection before you can interact with it. This sets up the SignalR connection that delivers live events.

Note: Due to a bug in the Valour SDK the built-in channel cache is not working right now, so we use our own dictionary as a workaround.

Creating a channel cache

We store each channel by its ID so we can look them up quickly later.

// Make your own channel cache using the channel's ID as the key
Dictionary<long, Channel> channelCache = new();

Loading planet data

Before we can read a planet's channels we need to fetch its data. We also loop through every channel and add it to the cache.

// Get the first planet the bot joined
Planet planet = client.PlanetService.JoinedPlanets.First();

// Load the planet's data
await planet.EnsureReadyAsync();
await planet.FetchInitialDataAsync();

// Add every channel to the cache
foreach (Channel chan in planet.Channels)
{
    channelCache[chan.Id] = chan;
}

Finding the default channel

Now that the cache is filled we can grab the planet's primary chat channel to send messages to.

// Fetch the default chat channel
if (!channelCache.TryGetValue(planet.PrimaryChatChannel.Id, out var channel)) return;

// Fall back to the first chat channel if the default wasn't found
if (channel is null)
{
    channel = planet.Channels.FirstOrDefault(
        c => c.ChannelType == ChannelTypeEnum.PlanetChat
    );
}

// One final check if the channel is still null (very rare!)
if (channel is null)
{
    Console.WriteLine("Unable to find the Default or First channel");
}

Sending a message

With a channel in hand, sending a message is just one line.

// Send a message to the channel
await channel.SendMessageAsync("Hello from my bot!");

Great, your bot has sent its first message in your Planet!

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;

// Make your own channel cache using the channel's ID as the key
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})");

// Get the first planet the bot joined
Planet planet = client.PlanetService.JoinedPlanets.First();

// Load the planet's data
await planet.EnsureReadyAsync();
await planet.FetchInitialDataAsync();

// Add every channel to the cache
foreach (Channel chan in planet.Channels)
{
    channelCache[chan.Id] = chan;
}

// Fetch the default chat channel
if (!channelCache.TryGetValue(planet.PrimaryChatChannel.Id, out var channel)) return;

// Fall back to the first chat channel if the default wasn't found
if (channel is null)
{
    channel = planet.Channels.FirstOrDefault(
        c => c.ChannelType == ChannelTypeEnum.PlanetChat
    );
}

// One final check if the channel is still null (very rare!)
if (channel is null)
{
    Console.WriteLine("Unable to find the Default or First channel");
}

// Send a message to the channel
await channel.SendMessageAsync("Hello from my bot!");

await Task.Delay(Timeout.Infinite);

The Next step is Receiving Messages and Commands