feat: post stats to discord.bots.gg

This commit is contained in:
sam 2024-10-30 14:35:56 +01:00
parent 4b74005110
commit 8ed9b4b143
Signed by: sam
GPG key ID: 5F3C3C1B3166639D
2 changed files with 50 additions and 2 deletions

View file

@ -60,6 +60,9 @@ public class Config
// If enabled, nothing will be logged. // If enabled, nothing will be logged.
public bool TestMode { get; init; } = false; public bool TestMode { get; init; } = false;
// Token for discord.bots.gg stats
public string? BotsGgToken { get; init; }
} }
public class WebConfig public class WebConfig

View file

@ -13,6 +13,9 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
using Catalogger.Backend.Bot; using Catalogger.Backend.Bot;
using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Abstractions.Objects;
using Remora.Discord.API.Gateway.Commands; using Remora.Discord.API.Gateway.Commands;
@ -24,15 +27,16 @@ public class StatusUpdateService(ILogger logger, ShardedGatewayClient shardedCli
: BackgroundService : BackgroundService
{ {
private readonly ILogger _logger = logger.ForContext<StatusUpdateService>(); private readonly ILogger _logger = logger.ForContext<StatusUpdateService>();
private readonly HttpClient _client = new();
protected override async Task ExecuteAsync(CancellationToken ct) protected override async Task ExecuteAsync(CancellationToken ct)
{ {
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(3)); using var timer = new PeriodicTimer(TimeSpan.FromMinutes(3));
while (await timer.WaitForNextTickAsync(ct)) while (await timer.WaitForNextTickAsync(ct))
UpdateShardStatuses(ct); await UpdateShardStatuses(ct);
} }
private void UpdateShardStatuses(CancellationToken ct = default) private async Task UpdateShardStatuses(CancellationToken ct = default)
{ {
_logger.Information( _logger.Information(
"Updating status for {TotalShards} shards. Guild count is {GuildCount}", "Updating status for {TotalShards} shards. Guild count is {GuildCount}",
@ -59,6 +63,8 @@ public class StatusUpdateService(ILogger logger, ShardedGatewayClient shardedCli
client.SubmitCommand(PresenceFor(shardId)); client.SubmitCommand(PresenceFor(shardId));
} }
await ReportStatsAsync();
} }
private UpdatePresence PresenceFor(int shardId) private UpdatePresence PresenceFor(int shardId)
@ -75,4 +81,43 @@ public class StatusUpdateService(ILogger logger, ShardedGatewayClient shardedCli
Activities: [new Activity(Name: "Beep", Type: ActivityType.Custom, State: status)] Activities: [new Activity(Name: "Beep", Type: ActivityType.Custom, State: status)]
); );
} }
private async Task ReportStatsAsync()
{
if (config.Discord.BotsGgToken == null)
return;
_logger.Debug("Posting stats to discord.bots.gg");
var req = new HttpRequestMessage(
HttpMethod.Post,
$"https://discord.bots.gg/api/v1/bots/{config.Discord.ApplicationId}/stats"
);
req.Headers.Add("Authorization", config.Discord.BotsGgToken);
req.Content = new StringContent(
JsonSerializer.Serialize(
new BotsGgStats(
(int)CataloggerMetrics.GuildsCached.Value,
shardedClient.TotalShards
)
),
new MediaTypeHeaderValue("application/json", "utf-8")
);
var resp = await _client.SendAsync(req);
if (!resp.IsSuccessStatusCode)
{
var content = await resp.Content.ReadAsStringAsync();
_logger.Error(
"Error updating stats for discord.bots.gg: {StatusCode}, {Content}",
(int)resp.StatusCode,
content
);
}
}
private record BotsGgStats(
[property: JsonPropertyName("guildCount")] int GuildCount,
[property: JsonPropertyName("shardCount")] int ShardCount
);
} }