Partial Lichess API client for managing challenges and social interactions. It accepts/declines challenges, lists current challenges, and sends a challenge to a user by constructing HTTP requests, applying rate limit consumption, and deserializing JSON responses.
#nullable enable annotations
using LichessNET.Entities.Enumerations;
using LichessNET.Entities.Social;
namespace LichessNET.API;
public partial class LichessApiClient
{
/// <summary>
/// Accepts a challenge from Lichess
/// </summary>
/// <param name="challengeId">The challenge ID to accept</param>
/// <returns>A bool whether the operation was successful or not</returns>
public async Task<bool> AcceptChallengeAsync(string challengeId)
{
await _ratelimitController.Consume();
var endpoint = $"api/challenge/{challengeId}/accept";
var request = GetRequestScaffold(endpoint);
var response = await SendRequest(request, "POST");
return response.Content.ReadAsStringAsync().Result.Contains("true");
}
/// <summary>
/// Declines a challenge from Lichess
/// </summary>
/// <param name="challengeId">The challenge ID to decline</param>
/// <param name="reason">The reason why the challenge is declined. Default is ChallengeDeniedReason.Generic</param>
/// <returns>A bool whether the operation was successful or not</returns>
public async Task<bool> DeclineChallengeAsync(string challengeId,
ChallengeDeniedReason reason = ChallengeDeniedReason.Generic)
{
await _ratelimitController.Consume();
var endpoint = $"api/challenge/{challengeId}/decline";
var request = GetRequestScaffold(endpoint);
var response = await SendRequest(request, "POST");
return response.Content.ReadAsStringAsync().Result.Contains("true");
}
/// <summary>
/// Gets all challenges by a user. Those are sorted by incoming and outgoing challenges.
/// </summary>
/// <returns>A struct with all challenges</returns>
public async Task<ChallengeResponse> GetChallengesAsync()
{
await _ratelimitController.Consume();
var endpoint = "api/challenge";
var request = GetRequestScaffold(endpoint);
var response = await SendRequest(request);
var content = await response.Content.ReadAsStringAsync();
var challengeResponse = LichessJson.Deserialize<ChallengeResponse>(content);
return challengeResponse;
}
/// <summary>
/// Challenge a user to a game on Lichess
/// </summary>
/// <param name="username">The user to challenge</param>
/// <param name="rated">Whether the game should be rated or not</param>
/// <param name="clockLimit">The clock limit</param>
/// <param name="clockIncrement">The increment on the clock</param>
/// <param name="days">Days per move (for correspondence)</param>
/// <param name="color">The color you want to play</param>
/// <param name="variant">The variant to play</param>
/// <param name="fen">The starting FEN</param>
/// <param name="keepAliveStream">Keep the challenge alive after 20 seconds</param>
/// <param name="rules">Rules</param>
/// <returns>The challenge entity</returns>
public async Task<Challenge> ChallengeUserAsync(string username, bool rated = false, int clockLimit = 0,
int clockIncrement = 0, int? days = null, string color = "random", string variant = "standard",
string fen = null, bool keepAliveStream = false, string rules = null)
{
await _ratelimitController.Consume();
var endpoint = $"api/challenge/{username}";
var request = GetRequestScaffold(endpoint);
var parameters = new Dictionary<string, string>
{
{ "rated", rated.ToString().ToLower() },
{ "clock.limit", clockLimit.ToString() },
{ "clock.increment", clockIncrement.ToString() },
{ "color", color },
{ "variant", variant }
};
if (days.HasValue)
{
parameters.Add("days", days.Value.ToString());
}
if (!string.IsNullOrEmpty(fen))
{
parameters.Add("fen", fen);
}
if (keepAliveStream)
{
parameters.Add("keepAliveStream", "true");
}
if (!string.IsNullOrEmpty(rules))
{
parameters.Add("rules", rules);
}
var response = await SendRequest(request, "POST", formData: parameters);
var content = await response.Content.ReadAsStringAsync();
var challengeResponse = LichessJson.Deserialize<Challenge>(content);
return challengeResponse;
}
}