Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
11 changes: 11 additions & 0 deletions DiscordBot/Commands/HelloCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Discord;
using Discord.Interactions;

public class HelloCommand : InteractionModuleBase<SocketInteractionContext>
{
[SlashCommand("hello", "says hello to the chat")]
public async Task Hello(){

await RespondAsync($"Hello, {Context.User.GlobalName}");
}
}
51 changes: 0 additions & 51 deletions Program.cs → DiscordBot/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public async Task MainAsync()
_client.Log += Log;
_client.Ready += ClientReady;
_client.InteractionCreated += HandleInteraction;
_client.SlashCommandExecuted += SlashCommandHandler;

string? botToken = Environment.GetEnvironmentVariable("DISCORD_API_KEY");
await _client.LoginAsync(TokenType.Bot, botToken);
Expand All @@ -52,63 +51,13 @@ private async Task ClientReady()
{
foreach(SocketGuild guild in _client.Guilds)
{
Console.WriteLine("****************");

Console.WriteLine($"Name: {guild.Name}");
Console.WriteLine($"ID: {guild.Id}");
Console.WriteLine($"Owner: {guild.OwnerId}");
Console.WriteLine($"Icon URL: {guild.IconUrl}");

Console.WriteLine("****************");


await _interactionService.AddModulesAsync(typeof(Program).Assembly, _services);
await _interactionService.RegisterCommandsToGuildAsync(guild.Id);
SlashCommandBuilder suiCommand = new SlashCommandBuilder()
.WithName("sui")
.WithDescription("suuuuiii");

try
{
await guild.CreateApplicationCommandAsync(suiCommand.Build());
}
catch (HttpException exception)
{
string json = JsonSerializer.Serialize(exception.Errors, new JsonSerializerOptions
{
WriteIndented = true
});

Console.WriteLine(json);
}

if (guild != null){

var textChannel = guild.TextChannels
.FirstOrDefault(c =>
c.GetUser(_client.CurrentUser.Id)?.GetPermissions(c).SendMessages == true);

if (textChannel != null){

await textChannel.SendMessageAsync("The bot is alive");

}
else{
Console.WriteLine("Can't access text channels for this bot");
}
}
}

}
private async Task SlashCommandHandler(SocketSlashCommand command)
{
switch (command.Data.Name)
{
case "sui":
await command.RespondAsync($"SUIIIII");
break;
}
}
private async Task HandleInteraction(SocketInteraction interaction)
{
var ctx = new SocketInteractionContext(_client, interaction);
Expand Down
34 changes: 19 additions & 15 deletions RonaldoAI.cs → DiscordBot/Services/RonaldoAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@
using Discord.Interactions;
using System.Text.Json.Nodes;

public class RonaldoAI : InteractionModuleBase<SocketInteractionContext> {
public class ChatAI : InteractionModuleBase<SocketInteractionContext> {

private readonly static string _modelName = "gemeni-2.5-flash-lite";
private readonly static string _endpoint=$"https://generativelanguage.googleapis.com/v1beta/models/{_modelName}:generateContent";
private static string? _message;

[SlashCommand("chat", "Chat with AI")]
public async Task Chat([Summary("text", "Say anything")] string message)
{
_message = message;
//let the bot think a bit longer
await DeferAsync();
//asynchronsly iterate over IEnumarable splited text
await foreach (var answer in GetAnswerAsync(message))
await foreach (var answer in SplitAnswer())
{
await FollowupAsync(answer);
}
}

private static async IAsyncEnumerable<string> GetAnswerAsync(string message)
private static async Task<JsonNode> MakeRequest()
{

string? apiKey = Environment.GetEnvironmentVariable("GEMENI_API");
string modelName = "gemini-2.5-flash-lite";
string endpoint = $"https://generativelanguage.googleapis.com/v1beta/models/{modelName}:generateContent";

using HttpClient http = new();
http.DefaultRequestHeaders.Add("x-goog-api-key", apiKey);
Expand All @@ -35,20 +40,26 @@ private static async IAsyncEnumerable<string> GetAnswerAsync(string message)
{
new JsonObject
{
["text"] = message
["text"] = _message
}
}
}
}
};

StringContent content = new(json.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage response = await http.PostAsync(endpoint, content);

HttpResponseMessage response = await http.PostAsync(_endpoint, content);

string? resultString = await response.Content.ReadAsStringAsync() ?? "";

JsonNode? doc = JsonNode.Parse(resultString)
?? throw new InvalidOperationException("didn't parse JSON");
return doc;
}
private static async IAsyncEnumerable<string> SplitAnswer()
{

JsonNode doc = await MakeRequest();

string? resultText = doc["candidates"]?[0]?["content"]?["parts"]?[0]?["text"]?.ToString();
Console.WriteLine(resultText);
Expand All @@ -58,13 +69,6 @@ private static async IAsyncEnumerable<string> GetAnswerAsync(string message)
int end = Math.Min(2000, resultText.Length - i);
yield return resultText.Substring(i, end);
}
//more FP approch but I prefer for-loop in this case because it is more clear
//IEnumerable<string> resultEnum = Enumerable
// .Range(0, (resultText.Length + 2000 - 1) / 2000)
// .Select(i => resultText.Substring(i * 2000, Math.Min(2000, resultText.Length - i)));



}
}

File renamed without changes.