public override async Task HandleCommandAsync(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Guild guild) { if (guild.RecruitingChannelId == default) { await command.RespondAsync("Channel is not part of a guild that supports recruiting", ephemeral : true); return; } var channel = command.Channel as SocketGuildChannel; var subCommand = command.Data.Options.First(); var options = subCommand.Options.ToDictionary(o => o.Name, o => o); await command.RespondAsync($"Starting Command {command.CommandName} {subCommand.Name}", ephemeral : true); // Get all messages in channel var recruitingChannel = await client.GetChannelAsync(guild.RecruitingChannelId) as ISocketMessageChannel; // What do we do if the policy fails 3 times and the board has values that aren't in the table. We could save values first if we didn't need the message id from new teams, but we do. await Policy.Handle <RequestFailedException>(e => e.Status == 412).RetryAsync(3).ExecuteAsync(async() => { // cache these values eventually as well to improve performance var teams = await storageClient.GetAllRowsAsync <Team>(Team.TableName, guild.Id.ToString()); if (teams.Count == 0) { var messages = await GetAllChannelMessages(recruitingChannel); // Parse messages into teams teams = ParseMessageAsync(messages); if (teams.Count > 0) { await ConvertMessageTeamsToStorage(teams, guild.RowKey, storageClient); } // get etags after for optimistic concurrency teams = await storageClient.GetAllRowsAsync <Team>(Team.TableName, guild.Id.ToString()); } switch (subCommand.Name) { case "add": await AddTrackerCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams); break; case "adminadd": await AdminAddTrackerCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams); break; case "move": await MoveTrackedUserCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams); break; case "remove": await RemoveTrackedUserCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams); break; case "deleteteam": await DeleteTeamTrackerCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams); break; case "lookingforplayers": await LookingForPlayersCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams); break; default: await command.FollowupAsync($"SubCommand {subCommand} not supported", ephemeral: true); return; } }); }