public async Task <IActionResult> NewPoll([FromServices] IDiscordGuildService guildService, [FromServices] IMessageService messageService, ulong guildId, NewPollViewModel viewModel, List <string> options) { // All channels for guild. var channels = await guildService.GetChannels(guildId); // Text channels for guild. var textChannels = channels.Where(x => x.Type == (int)ChannelType.Text).ToList(); // Authorization - make sure channel belongs to the guild (prevents exploitation by providing a channel that isn't theirs, if they're authorized). // Note - this should be extracted into a seperate web filter. if (textChannels.FirstOrDefault(x => x.Id == viewModel.ChannelId) == null) { ModelState.AddModelError("All", "You are not authorized to perform this action."); viewModel.Channels = new SelectList(textChannels, "Id", "Name"); return(View(viewModel)); } var validOptions = options.Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); // Make sure user supplied valid no of options if (validOptions.Count < 2 || validOptions.Count > ModuleConstants.TotalOptions) { ModelState.AddModelError("All", $"Please provide between 2 and {ModuleConstants.TotalOptions} valid options."); viewModel.Channels = new SelectList(textChannels, "Id", "Name"); return(View(viewModel)); } if (!ModelState.IsValid) { return(View(viewModel)); } var poll = new StringBuilder(); // Add poll title. poll.Append(":small_blue_diamond: " + viewModel.Title + Environment.NewLine); var discordNumbers = MessageService.DiscordNumberEmotes; // Add options to poll. for (var i = 0; i < validOptions.Count; i++) { poll.Append($"{discordNumbers[i + 1]} {validOptions[i]}{Environment.NewLine}"); } // Post message and get message details. var message = await messageService.Post(viewModel.ChannelId, poll.ToString()); // Create poll settings entry for guild in db, if doesn't exist. if (await _entityServicePollSettings.Find(guildId) == null) { await _entityServicePollSettings.Create(new PollSettings() { GuildId = guildId }); } // Save poll to database await _entityServicePoll.Create(new Poll() { ChannelId = viewModel.ChannelId, MessageId = message.Id, PollTitle = viewModel.Title, GuildId = guildId }); // Add reactions to message to act as voting buttons. for (var i = 1; i < validOptions.Count + 1; i++) { await messageService.AddReaction(message, new Emoji(discordNumbers[i])); } return(RedirectToAction("Index")); }