signing up through the discord bot works now

This commit is contained in:
Sarah Faey 2022-11-07 00:16:49 +01:00
parent e445b2a181
commit 69337e69ae
11 changed files with 327 additions and 42 deletions

View file

@ -2,6 +2,9 @@
using Discord.Commands;
using Discord.WebSocket;
using System.Reflection;
using DiscordBot.Services;
using SharedClasses.SharedModels;
using DiscordBot.Messages;
namespace DiscordBot
{
@ -9,18 +12,21 @@ namespace DiscordBot
{
private readonly DiscordSocketClient _client;
private readonly CommandService _commands;
private readonly HttpService _httpService;
// Retrieve client and CommandService instance via ctor
public CommandHandler(DiscordSocketClient client, CommandService commands)
public CommandHandler(DiscordSocketClient client, CommandService commands, HttpService httpService)
{
_commands = commands;
_client = client;
_httpService = httpService;
}
public async Task InstallCommandsAsync()
{
_client.SlashCommandExecuted += SlashCommandHandler;
_client.ButtonExecuted += MyButtonHandler;
_client.ButtonExecuted += ButtonHandler;
_client.SelectMenuExecuted += SelectMenuHandler;
}
private async Task SlashCommandHandler(SocketSlashCommand command)
@ -54,28 +60,95 @@ namespace DiscordBot
await command.RespondAsync(embed: embedBuiler.Build());
}
public async Task MyButtonHandler(SocketMessageComponent component)
public async Task ButtonHandler(SocketMessageComponent component)
{
string[] ids = component.Data.CustomId.Split('-');
List<ApiRole> roles = new List<ApiRole>();
int parsedRaidId = 0;
if(ids.Length > 1)
{
int.TryParse(ids[1],out parsedRaidId);
}
switch(ids[0])
{
case Constants.ComponentIds.SIGN_UP:
//await component.RespondAsync($"{component.User.Mention} has clicked the SignUp button!");
var mb = new ModalBuilder()
.WithTitle("Fav Food")
.WithCustomId("food_menu")
.AddTextInput("What??", "food_name", placeholder:"Pizza")
.AddTextInput("Why??", "food_reason", TextInputStyle.Paragraph,
"Kus it's so tasty");
//await component.RespondWithModalAsync(mb.Build());
await component.RespondAsync("hi", ephemeral: true);
case Constants.ComponentIds.SIGN_UP_BUTTON:
roles = await _httpService.GetRoles(parsedRaidId, component.User.Id);
await component.RespondAsync("Please choose a role.", components: SignUpMessage.buildMessage(roles, parsedRaidId, ids[0], false) , ephemeral: true);
break;
case Constants.ComponentIds.SIGN_OFF:
//await component.RespondAsync($"{component.User.Mention} has clicked the SignOff button!");
case Constants.ComponentIds.MAYBE_BUTTON:
case Constants.ComponentIds.BACKUP_BUTTON:
case Constants.ComponentIds.FLEX_BUTTON:
roles = await _httpService.GetRoles(parsedRaidId, component.User.Id);
await component.RespondAsync("Please choose a role.", components: SignUpMessage.buildMessage(roles, parsedRaidId, ids[0], true) , ephemeral: true);
break;
case Constants.ComponentIds.SIGN_OFF_BUTTON:
ApiSignUp signOff = new ApiSignUp()
{
raidId = parsedRaidId,
userId = component.User.Id
};
await _httpService.SignOff(signOff);
await Respond(component);
break;
}
}
public async Task SelectMenuHandler(SocketMessageComponent component)
{
string[] ids = component.Data.CustomId.Split('-');
List<ApiRole> roles = new List<ApiRole>();
int parsedRaidId = 0;
if(ids.Length > 1)
{
int.TryParse(ids[1],out parsedRaidId);
}
switch(ids[0])
{
case Constants.ComponentIds.SIGN_UP_DROP_DOWN:
await ManageSignUp(ids[2], parsedRaidId, component);
await Respond(component);
break;
}
}
private async Task ManageSignUp(string buttonType, int raidId, SocketMessageComponent component)
{
if(! int.TryParse(component.Data.Values.First(), out int parsedRoleId)) return;
ApiSignUp signUp = new ApiSignUp()
{
raidId = raidId,
userId = component.User.Id,
roleId = parsedRoleId
};
switch(buttonType)
{
case Constants.ComponentIds.SIGN_UP_BUTTON:
await _httpService.SignUp(signUp);
break;
case Constants.ComponentIds.MAYBE_BUTTON:
await _httpService.SignUpMaybe(signUp);
break;
case Constants.ComponentIds.BACKUP_BUTTON:
await _httpService.SignUpBackup(signUp);
break;
case Constants.ComponentIds.FLEX_BUTTON:
await _httpService.SignUpFlex(signUp);
break;
}
}
//to avoid error messages because of no response...
private async Task Respond(SocketMessageComponent component)
{
try
{
await component.RespondAsync();
}
catch(Discord.Net.HttpException e)
{
}
}
}

View file

@ -2,10 +2,16 @@
{
public class Constants
{
public const string HTTP_CLIENT_NAME = "LiebWebsite";
public class ComponentIds
{
public const string SIGN_UP = "su";
public const string SIGN_OFF = "so";
{
public const string SIGN_UP_BUTTON = "signUpButton";
public const string MAYBE_BUTTON = "maybeButton";
public const string BACKUP_BUTTON = "backupButton";
public const string FLEX_BUTTON = "flexButton";
public const string SIGN_OFF_BUTTON = "signOffButton";
public const string SIGN_UP_DROP_DOWN = "signUpDropDown";
}
public class SlashCommands

View file

@ -33,18 +33,12 @@ namespace DiscordBot.Messages
public async Task<ApiRaid> PostRaidMessage(ApiRaid raid)
{
var menuBuilder = new SelectMenuBuilder()
.WithPlaceholder("Select an option")
.WithCustomId("menu-1")
.WithMinValues(1)
.WithMaxValues(1)
.AddOption("Option A", "opt-a", "Option B is lying!")
.AddOption("Option B", "opt-b", "Option A is telling the truth!");
var builder = new ComponentBuilder()
.WithButton("SignUp", $"{Constants.ComponentIds.SIGN_UP}-{raid.RaidId.ToString()}", ButtonStyle.Secondary)
.WithButton("SignOff", $"{Constants.ComponentIds.SIGN_OFF}-{raid.RaidId.ToString()}", ButtonStyle.Secondary);
//.WithSelectMenu(menuBuilder);
.WithButton("SignUp", $"{Constants.ComponentIds.SIGN_UP_BUTTON}-{raid.RaidId.ToString()}", ButtonStyle.Success)
.WithButton("Maybe", $"{Constants.ComponentIds.MAYBE_BUTTON}-{raid.RaidId.ToString()}", ButtonStyle.Secondary)
.WithButton("Backup", $"{Constants.ComponentIds.BACKUP_BUTTON}-{raid.RaidId.ToString()}", ButtonStyle.Secondary)
.WithButton("Flex", $"{Constants.ComponentIds.FLEX_BUTTON}-{raid.RaidId.ToString()}", ButtonStyle.Secondary)
.WithButton("SignOff", $"{Constants.ComponentIds.SIGN_OFF_BUTTON}-{raid.RaidId.ToString()}", ButtonStyle.Danger);
MessageComponent components = builder.Build();
Embed raidMessage = CreateRaidMessage(raid);
@ -62,7 +56,8 @@ namespace DiscordBot.Messages
Embed = raidMessage,
Components = components
};
await messageChannel.ModifyMessageAsync(message.MessageId, new Action<MessageProperties>(x => x = properties));
IUserMessage discordMessage = (IUserMessage)await messageChannel.GetMessageAsync(message.MessageId);
await discordMessage.ModifyAsync(msg => msg.Embed = raidMessage);
}
else
{
@ -105,7 +100,7 @@ namespace DiscordBot.Messages
Dictionary<string, string> fieldList = new Dictionary<string, string>();
embed.AddField("Signed up", $"({raid.Roles.Sum(r => r.Users.Count)}/{raid.Roles.Sum(r => r.Spots)}):");
foreach (ApiRaid.Role role in raid.Roles)
foreach (ApiRaid.Role role in raid.Roles.OrderBy(x => x.RoleId))
{
//print signed up users
string signedUpUsers = PrintUsers(role);

View file

@ -0,0 +1,68 @@
using Discord;
using Discord.WebSocket;
using System;
using System.ComponentModel.DataAnnotations;
using SharedClasses.SharedModels;
namespace DiscordBot.Messages
{
public class SignUpMessage
{
public static MessageComponent buildMessage(List<ApiRole> roles, int raidId, string buttonType, bool allRoles)
{
var signUpSelect = new SelectMenuBuilder()
.WithPlaceholder("Select an option")
.WithCustomId($"{Constants.ComponentIds.SIGN_UP_DROP_DOWN}-{raidId}-{buttonType}")
.WithMinValues(1)
.WithMaxValues(1);
foreach(ApiRole role in roles)
{
if(allRoles || role.IsSignUpAllowed)
signUpSelect.AddOption(role.Name, role.roleId.ToString(), role.Description);
}
var builder = new ComponentBuilder()
.WithSelectMenu(signUpSelect, 0);
return builder.Build();
}
/*
public static MessageComponent buildMessage(List<ApiRole> roles, int raidId)
{
var signUpSelect = new SelectMenuBuilder()
.WithPlaceholder("Select an option")
.WithCustomId(Constants.ComponentIds.SIGN_UP_DROP_DOWN)
.WithMinValues(1)
.WithMaxValues(1);
foreach(ApiRole role in roles)
{
if(role.IsSignUpAllowed)
signUpSelect.AddOption(role.Name, role.roleId.ToString(), role.Description);
}
var flexSelect = new SelectMenuBuilder()
.WithPlaceholder("Select an option")
.WithCustomId(Constants.ComponentIds.FLEX_DROP_DOWN)
.WithMinValues(1)
.WithMaxValues(1);
foreach(ApiRole role in roles)
{
flexSelect.AddOption(role.Name, role.roleId.ToString(), role.Description);
}
var builder = new ComponentBuilder()
.WithSelectMenu(signUpSelect, 0)
.WithButton("SignUp", $"{Constants.ComponentIds.SIGN_UP_BUTTON}-{raidId.ToString()}", ButtonStyle.Success, row: 1)
.WithSelectMenu(flexSelect, 2)
.WithButton("Maybe", $"{Constants.ComponentIds.MAYBE_BUTTON}-{raidId.ToString()}", ButtonStyle.Success, row: 3)
.WithButton("Backup", $"{Constants.ComponentIds.BACKUP_BUTTON}-{raidId.ToString()}", ButtonStyle.Success, row: 3)
.WithButton("Flex", $"{Constants.ComponentIds.FLEX_BUTTON}-{raidId.ToString()}", ButtonStyle.Success, row: 3);
return builder.Build();
}*/
}
}

View file

@ -2,9 +2,11 @@ using Discord;
using Discord.Commands;
using Discord.Net;
using Discord.WebSocket;
using Microsoft.Net.Http.Headers;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Reflection;
using DiscordBot.Services;
namespace DiscordBot
{
@ -28,6 +30,7 @@ namespace DiscordBot
builder.Services.AddSingleton<DiscordSocketClient>();
builder.Services.AddSingleton<CommandService>();
builder.Services.AddSingleton<CommandHandler>();
builder.Services.AddSingleton<HttpService>();
builder.Services.AddControllers();
@ -35,6 +38,24 @@ namespace DiscordBot
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpClient(Constants.HTTP_CLIENT_NAME , httpClient =>
{
httpClient.BaseAddress = new Uri("https://localhost:7216/");
httpClient.DefaultRequestHeaders.Add(
HeaderNames.Accept, "application/vnd.github.v3+json");
httpClient.DefaultRequestHeaders.Add(
HeaderNames.UserAgent, "HttpRequestsSample");
}).ConfigurePrimaryHttpMessageHandler(() => {
var handler = new HttpClientHandler();
if (builder.Environment.IsDevelopment())
{
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
}
return handler;
});
var app = builder.Build();
// Configure the HTTP request pipeline.

View file

@ -0,0 +1,77 @@
using SharedClasses.SharedModels;
using System.Net.Http;
using static System.Net.Mime.MediaTypeNames;
using System.Text.Json;
using System.Text;
namespace DiscordBot.Services
{
public class HttpService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly JsonSerializerOptions _serializerOptions;
public HttpService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
_serializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
}
public async Task<List<ApiRole>> GetRoles(int raidId, ulong userId)
{
var httpClient = _httpClientFactory.CreateClient(Constants.HTTP_CLIENT_NAME);
var httpResponseMessage = await httpClient.GetAsync($"DiscordBot/GetRoles/{raidId}/{userId}");
if (httpResponseMessage.IsSuccessStatusCode)
{
using var contentStream =
await httpResponseMessage.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync<List<ApiRole>>(contentStream, _serializerOptions);
}
return new List<ApiRole>();
}
public async Task SignUp(ApiSignUp signUp)
{
await SendSignUp(signUp, "DiscordBot/SignUp");
}
public async Task SignUpMaybe(ApiSignUp signUp)
{
await SendSignUp(signUp, "DiscordBot/SignUpMaybe");
}
public async Task SignUpBackup(ApiSignUp signUp)
{
await SendSignUp(signUp, "DiscordBot/SignUpBackup");
}
public async Task SignUpFlex(ApiSignUp signUp)
{
await SendSignUp(signUp, "DiscordBot/SignUpFlex");
}
public async Task SignOff(ApiSignUp signUp)
{
await SendSignUp(signUp, "DiscordBot/SignOff");
}
private async Task SendSignUp(ApiSignUp signUp, string requestUri)
{
var httpClient = _httpClientFactory.CreateClient(Constants.HTTP_CLIENT_NAME);
var raidItemJson = new StringContent(
JsonSerializer.Serialize(signUp),
Encoding.UTF8,
Application.Json);
var httpResponseMessage = await httpClient.PostAsync(requestUri, raidItemJson);
}
}
}