/// <summary> /// Удаление старых тикетов. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static async void CheckExpiredTicketsAsync(object sender, ElapsedEventArgs e) { Client.Logger.LogDebug(BotLoggerEvents.Timers, $"CheckExpiredTicketsAsync running"); var expiredTickets = TicketSQL.GetClosedFor(TimeSpan.FromDays(2)); var guild = Client.Guilds[Bot.BotSettings.Guild]; foreach (var ticket in expiredTickets) { ticket.Status = TicketSQL.TicketStatus.Deleted; try { await guild.GetChannel(ticket.ChannelId).DeleteAsync(); } catch (NotFoundException) { } } }
public async Task Support(CommandContext ctx) { if (SupportBlacklistEntry.IsBlacklisted(ctx.User.Id)) { await ctx.RespondAsync("Создание тикетов заблокировано. Свяжитесь с администрацией для выяснения"); return; } DmMessageListener.DmHandled.Add(ctx.User); try { var guild = await ctx.Client.GetGuildAsync(Bot.BotSettings.Guild); //Создание эмбеда тикета и заполнение по шаблону var ticketEmbed = new DiscordEmbedBuilder { Title = "Sea of Thieves RU | Создание тикета", Description = "Выберите категорию вашего запроса через реакцию\n", Color = new DiscordColor("#e67e22") }; ticketEmbed.AddField($"{SupportEmoji[SupportType.Admin]} {SupportNames[SupportType.Admin]}", "Связь с администрацией, используйте только для **ВАЖНЫХ** вопросов", true); ticketEmbed.AddField($"{SupportEmoji[SupportType.Moderator]} {SupportNames[SupportType.Moderator]}", "Вопросы по поводу модерации, нарушений и так далее. (Отвечают модераторы и администраторы)", true); ticketEmbed.AddField($"{SupportEmoji[SupportType.Developer]} {SupportNames[SupportType.Developer]}", "По вопросам бота, сайта, техническим вопросам, помощь с командами и их ошибками.", true); ticketEmbed.AddField($"{SupportEmoji[SupportType.Donate]} {SupportNames[SupportType.Donate]}", "По вопросам рекламы и при проблемах с донатами.", true); ticketEmbed.AddField($"{SupportEmoji[SupportType.FleetCaptain]} {SupportNames[SupportType.FleetCaptain]}", "По вопросам рейдов и нарушений в рейдах. (Ошибки при выдаче роли -> к `Разработчикам`)", true); ticketEmbed.AddField($"{SupportEmoji[SupportType.Events]} {SupportNames[SupportType.Events]}", "По вопросам ивентов на сервере. Как игровых так и внутри сервера.", true); ticketEmbed.WithFooter("\n" + "При злоупотреблении системой тикетов вы будете заблокированы.\n" + "Дождитесь загрузки всех вариантов ответа. У вас есть минута на выбор варианта"); var ticketMessage = await ctx.RespondAsync(embed : ticketEmbed.Build()); var interactivity = ctx.Client.GetInteractivity(); //Создаем предложенные реакции. foreach (var emoji in SupportEmoji.Values) { await ticketMessage.CreateReactionAsync(DiscordEmoji.FromName(ctx.Client, emoji)); await Task.Delay(400); } //Шаблон закрытого тикета var errorEmbed = new DiscordEmbedBuilder() { Title = "Sea of Thieves RU | Создание тикета закрыто", Description = "Произошла ошибка при создании тикета.", Color = new DiscordColor("#e74c3c"), }; errorEmbed.WithThumbnail(guild.IconUrl); errorEmbed.WithTimestamp(DateTime.Now); //Ждем одну из предложенных реакций. (Минута времени) var em = await interactivity.WaitForReactionAsync(x => SupportEmoji.Values.Contains(x.Emoji.GetDiscordName()), ctx.User, TimeSpan.FromSeconds(60)); if (!em.TimedOut) { new Task(async() => { foreach (var emoji in SupportEmoji.Values) { await ticketMessage.DeleteOwnReactionAsync(DiscordEmoji.FromName(ctx.Client, emoji)); await Task.Delay(400); } }).Start(); var selectedCategory = SupportEmoji.FirstOrDefault(x => x.Value == em.Result.Emoji.GetDiscordName()).Key; //Успешное продолжение создания тикета //Запрос описания проблемы ticketEmbed = new DiscordEmbedBuilder { Title = "Sea of Thieves RU | Ожидание вопроса", Description = "Опишите ваш вопрос коротким сообщением.\n", Color = new DiscordColor("#e67e22") }; ticketEmbed.WithThumbnail(guild.IconUrl); ticketEmbed.AddField("Выбранная категория", $"{SupportEmoji[selectedCategory]} {SupportNames[selectedCategory]}", true); ticketEmbed.WithFooter("\nУ вас есть 5 минут для ввода вопроса."); await ticketMessage.ModifyAsync(embed : ticketEmbed.Build()); var emsg = await interactivity.WaitForMessageAsync(x => x.Author.Id == ctx.User.Id && !x.Content.StartsWith(Bot.BotSettings.Prefix), TimeSpan.FromMinutes(5)); if (!emsg.TimedOut) { //Запрос подтверждения тикета. ticketEmbed = new DiscordEmbedBuilder(ticketEmbed) { Title = "Sea of Thieves RU | Подтверждение тикета", Description = "Подтвердите ваш тикет для отправки. \n" + "`✅ отправить` `❌ отменить` \n", Color = new DiscordColor("#e67e22") }; ticketEmbed.AddField("Вопрос", emsg.Result.Content, true); ticketEmbed.WithFooter("\nДождитесь загрузки всех вариантов ответа. У вас есть минута на выбор варианта"); await ticketMessage.ModifyAsync(embed : ticketEmbed.Build()); //Реакции подтверждения var yesEmoji = DiscordEmoji.FromName(ctx.Client, ":white_check_mark:"); var noEmoji = DiscordEmoji.FromName(ctx.Client, ":x:"); await ticketMessage.CreateReactionAsync(yesEmoji); await Task.Delay(400); await ticketMessage.CreateReactionAsync(noEmoji); //Ждем ответа на подтверждение em = await interactivity.WaitForReactionAsync(x => x.Emoji == yesEmoji || x.Emoji == noEmoji, ctx.User, TimeSpan.FromSeconds(60)); if (!em.TimedOut) { await ticketMessage.DeleteOwnReactionAsync(yesEmoji); await Task.Delay(400); await ticketMessage.DeleteOwnReactionAsync(noEmoji); if (em.Result.Emoji == yesEmoji) { //Создание канала для ответа var supportChannel = await guild.CreateChannelAsync($"{DiscordEmoji.FromName(ctx.Client, SupportEmoji[selectedCategory])} {ctx.User.Username}", ChannelType.Text, guild.GetChannel(Bot.BotSettings.SupportCategory)); //Выдача прав на канал await supportChannel.AddOverwriteAsync(await guild.GetMemberAsync(ctx.User.Id), Permissions.AccessChannels); switch (selectedCategory) { case SupportType.Admin: case SupportType.Developer: case SupportType.Donate: //Do nothing break; case SupportType.Moderator: case SupportType.Events: await supportChannel.AddOverwriteAsync(guild.GetRole(Bot.BotSettings.ModeratorsRole), Permissions.AccessChannels); break; case SupportType.FleetCaptain: await supportChannel.AddOverwriteAsync(guild.GetRole(Bot.BotSettings.ModeratorsRole), Permissions.AccessChannels); await supportChannel.AddOverwriteAsync(guild.GetRole(Bot.BotSettings.FleetCaptainRole), Permissions.AccessChannels); break; } //Сохраняем в базу данных var ticketData = TicketSQL.Create(supportChannel.Id, ctx.User.Id, ctx.Channel.Id, ticketMessage.Id, emsg.Result.Content, DateTime.Now, SupportNames[selectedCategory]); //Обновляем тикет в лс ticketEmbed = new DiscordEmbedBuilder(ticketEmbed) { Description = "Тикет был создан.\n", Color = new DiscordColor("#f1c40f") }; ticketEmbed.WithFooter($"\nID: {ticketData.ChannelId}"); ticketEmbed.WithTimestamp(DateTime.Now); await ticketMessage.ModifyAsync(embed : ticketEmbed.Build()); await ctx.RespondAsync($"Ваш запрос был отравлен. Ждите ответ в {supportChannel.Mention}."); //Обновляем тикет для отправки в канал ticketEmbed = new DiscordEmbedBuilder(ticketEmbed) { Title = "Sea of Thieves RU | Тикет", Description = "Ожидайте ответ на ваш запрос.\n" } .WithAuthor(ctx.User.ToString(), iconUrl: ctx.User.AvatarUrl) .WithFooter($"\nID: {ticketData.ChannelId}"); var message = await supportChannel.SendMessageAsync($"Тикет от пользователя: {ctx.User.Mention}", embed : ticketEmbed.Build()); ticketData.MessageId = message.Id; } else { ticketEmbed = new DiscordEmbedBuilder(errorEmbed) .WithDescription("Тикет был отменён."); await ticketMessage.ModifyAsync(embed : ticketEmbed.Build()); } } else { await ticketMessage.DeleteOwnReactionAsync(yesEmoji); await Task.Delay(400); await ticketMessage.DeleteOwnReactionAsync(noEmoji); ticketEmbed = new DiscordEmbedBuilder(errorEmbed) .WithDescription("Время выбора истекло."); await ticketMessage.ModifyAsync(embed : ticketEmbed.Build()); } } else { ticketEmbed = new DiscordEmbedBuilder(errorEmbed) .WithDescription("Время ввода вопроса истекло."); await ticketMessage.ModifyAsync(embed : ticketEmbed.Build()); } } else { new Task(async() => { foreach (var emoji in SupportEmoji.Values) { await ticketMessage.DeleteOwnReactionAsync(DiscordEmoji.FromName(ctx.Client, emoji)); await Task.Delay(400); } }).Start(); ticketEmbed = new DiscordEmbedBuilder(errorEmbed) .WithDescription("Время выбора категории тикета истекло."); await ticketMessage.ModifyAsync(embed : ticketEmbed.Build()); } DmMessageListener.DmHandled.Remove(ctx.User); } catch (Exception) { DmMessageListener.DmHandled.Remove(ctx.User); throw; } }