public async ValueTask <AdminCommandResult> SendMessageAsync(CachedTextChannel channel, [Remainder] string text = null) { if (string.IsNullOrWhiteSpace(text) && Context.Message.Attachments.Count == 0) { return(CommandErrorLocalized("utility_send_empty")); } if (!string.IsNullOrWhiteSpace(text)) { text = await text.FormatPlaceHoldersAsync(Context, random : Random); } var file = new MemoryStream(); var filename = string.Empty; if (Context.Message.Attachments.FirstOrDefault() is { } attachment) { await using var stream = await Http.GetStreamAsync(attachment.Url); await stream.CopyToAsync(file); file.Seek(0, SeekOrigin.Begin); filename = attachment.FileName; } if (JsonEmbed.TryParse(text, out var embed)) { await channel.SendMessageAsync( !string.IsNullOrWhiteSpace(filename)?new LocalAttachment(file, filename) : null, embed.Text, embed : embed.ToLocalEmbed()); return(CommandSuccess()); } if (!string.IsNullOrWhiteSpace(filename)) { await channel.SendMessageAsync(new LocalAttachment(file, filename), text); } else { await channel.SendMessageAsync(text); } return(CommandSuccess()); }
public async Task SendLoggingRevocationEmbedAsync(RevocablePunishment punishment, IUser target, IUser moderator, CachedTextChannel logChannel, LocalizedLanguage language) { var typeName = punishment.GetType().Name.ToLower(); var builder = new LocalEmbedBuilder().WithWarnColor() .WithTitle(_localization.Localize(language, $"punishment_{typeName}") + $" - {_localization.Localize(language, "punishment_case", punishment.Id)}") .WithDescription(_localization.Localize(language, $"punishment_{typeName}_revoke_description_guild", $"**{target}** (`{target.Id}`)")) .AddField(_localization.Localize(language, "title_reason"), punishment.RevocationReason ?? _localization.Localize(language, "punishment_noreason")) .WithFooter(_localization.Localize(language, "punishment_moderator", moderator.Tag), moderator.GetAvatarUrl()) .WithTimestamp(punishment.RevokedAt ?? DateTimeOffset.UtcNow); if (punishment is Mute channelMute && channelMute.ChannelId.HasValue) { builder.AddField(_localization.Localize(language, "punishment_mute_channel"), _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value)?.Mention ?? "???"); } await logChannel.SendMessageAsync(embed : builder.Build()); }
private async Task <IUserMessage> SendLoggingEmbedAsync(Punishment punishment, IUser target, IUser moderator, Punishment additionalPunishment, CachedTextChannel logChannel, LocalizedLanguage language) { var typeName = punishment.GetType().Name.ToLower(); var builder = new LocalEmbedBuilder() .WithErrorColor() .WithTitle(_localization.Localize(language, $"punishment_{typeName}") + $" - {_localization.Localize(language, "punishment_case", punishment.Id)}") .AddField(_localization.Localize(language, "title_reason"), punishment.Reason ?? _localization.Localize(language, "punishment_needsreason", Markdown.Code( $"{_config.DefaultPrefix}reason {punishment.Id} [{_localization.Localize(language, "title_reason").ToLower()}]"))) .WithFooter(_localization.Localize(language, "punishment_moderator", moderator.Tag), moderator.GetAvatarUrl()) .WithTimestamp(punishment.CreatedAt); builder = punishment switch { Ban ban => builder.AddField( _localization.Localize(language, "punishment_duration"), ban.Duration.HasValue ? ban.Duration.Value.Humanize(minUnit: TimeUnit.Second, culture: language.Culture) : _localization.Localize(language, "punishment_permanent")), Mute mute => builder.AddField( _localization.Localize(language, "punishment_duration"), mute.Duration.HasValue ? mute.Duration.Value.Humanize(minUnit: TimeUnit.Second, culture: language.Culture) : _localization.Localize(language, "punishment_permanent")), _ => builder }; if (punishment is Mute channelMute && channelMute.ChannelId.HasValue) { builder.AddField(_localization.Localize(language, "punishment_mute_channel"), _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value).Mention); } if (punishment is Warning) { using var ctx = new AdminDatabaseContext(_provider); var warningCount = await ctx.Punishments.OfType <Warning>().CountAsync(x => x.TargetId == target.Id && x.GuildId == punishment.GuildId && !x.RevokedAt.HasValue); builder.WithDescription(_localization.Localize(language, "punishment_warning_description_guild", $"**{target}** (`{target.Id}`)", Markdown.Bold(warningCount.ToOrdinalWords(language.Culture)))); if (!(additionalPunishment is null)) { builder.AddField(FormatAdditionalPunishment(additionalPunishment, language)); } } else { builder.WithDescription(_localization.Localize(language, $"punishment_{typeName}_description_guild", $"**{target}** (`{target.Id}`)")); } if (punishment.Format != ImageFormat.Default) { // TODO: Copying stream - is it necessary? var image = new MemoryStream(punishment.Image.ToArray()); builder.WithImageUrl($"attachment://attachment.{punishment.Format.ToString().ToLower()}"); return(await logChannel.SendMessageAsync(new LocalAttachment(image, $"attachment.{punishment.Format.ToString().ToLower()}"), embed : builder.Build())); } return(await logChannel.SendMessageAsync(embed : builder.Build())); }
public async ValueTask <AdminCommandResult> ReplyToModmailAsync(int id, [Remainder, MustBe(StringLength.ShorterThan, LocalEmbedBuilder.MAX_DESCRIPTION_LENGTH)] string message) { var modmail = await Context.Database.Modmails.FindAsync(id); if (modmail is null) { return(CommandErrorLocalized("modmail_notfound")); } if (Context.IsPrivate && modmail.UserId != Context.User.Id) { return(CommandErrorLocalized("modmail_notfound")); } if (!Context.IsPrivate && modmail.GuildId != Context.Guild.Id) { return(CommandErrorLocalized("modmail_notfound")); } CachedTextChannel loggingChannel = null; if (Context.IsPrivate) { if (!(await Context.Database.GetLoggingChannelAsync(modmail.GuildId, LogType.Modmail) is CachedTextChannel logChannel)) { return(CommandErrorLocalized("requireloggingchannel_notfound", args: LogType.Modmail)); } if (modmail.ClosedBy.HasValue) { return(modmail.ClosedBy.Value == ModmailTarget.User ? CommandErrorLocalized("modmail_closed_user") : CommandErrorLocalized("modmail_closed_guild")); } loggingChannel = logChannel; } else { if (modmail.ClosedBy.HasValue) { return(modmail.ClosedBy.Value == ModmailTarget.User ? CommandErrorLocalized("modmail_closed_user_guild") : CommandErrorLocalized("modmail_closed_guild")); } } Context.Database.ModmailMessages.Add(new ModmailMessage(Context.IsPrivate ? ModmailTarget.User : ModmailTarget.Modteam, message, modmail)); await Context.Database.SaveChangesAsync(); if (Context.IsPrivate) { await loggingChannel.SendMessageAsync(embed : new LocalEmbedBuilder() .WithColor(new Color(0x8ED0FF)) .WithAuthor(new LocalEmbedAuthorBuilder { IconUrl = modmail.IsAnonymous ? Discord.GetDefaultUserAvatarUrl(Context.User.Discriminator) : Context.User.GetAvatarUrl(), Name = modmail.IsAnonymous ? Context.Localize("modmail_anonymous") : Context.User.Tag.Sanitize() }) .WithDescription(message) .WithTitle(Context.Localize("modmail_title", modmail.Id)) .WithFooter(Context.Localize("modmail_reply_command", Markdown.Code($"{Context.Prefix}mm reply {modmail.Id} [...]"), Markdown.Code($"{Context.Prefix}mm close {modmail.Id}"))) .WithTimestamp(DateTimeOffset.UtcNow) .Build()); } else { _ = Task.Run(async() => { var user = await Context.Client.GetOrDownloadUserAsync(modmail.UserId); _ = user.SendMessageAsync(embed: new LocalEmbedBuilder() .WithColor(new Color(0x8ED0FF)) .WithAuthor(new LocalEmbedAuthorBuilder { IconUrl = Context.Guild.GetIconUrl(), Name = $"{Context.Guild.Name} modteam" }) .WithDescription(message) .WithTitle(Context.Localize("modmail_title", modmail.Id)) .WithFooter(Context.Localize("modmail_reply_command", Markdown.Code($"{Context.Prefix}mm reply {modmail.Id} [...]"), Markdown.Code($"{Context.Prefix}mm close {modmail.Id}"))) .WithTimestamp(DateTimeOffset.UtcNow) .Build()); }); } return(CommandSuccessLocalized("modmail_reply_success")); }