public async Task <DiscordEmbed> CreateMessageInfoEmbed(DiscordClient client, FullMessage msg) { var ctx = LookupContext.ByNonOwner; var channel = await _client.GetChannel(msg.Message.Channel); var serverMsg = channel != null ? await channel.GetMessage(msg.Message.Mid) : null; // Need this whole dance to handle cases where: // - the user is deleted (userInfo == null) // - the bot's no longer in the server we're querying (channel == null) // - the member is no longer in the server we're querying (memberInfo == null) DiscordMember memberInfo = null; DiscordUser userInfo = null; if (channel != null) { memberInfo = await channel.Guild.GetMember(msg.Message.Sender); } if (memberInfo != null) { userInfo = memberInfo; // Don't do an extra request if we already have this info from the member lookup } else { userInfo = await client.GetUser(msg.Message.Sender); } // Calculate string displayed under "Sent by" string userStr; if (memberInfo != null && memberInfo.Nickname != null) { userStr = $"**Username:** {memberInfo.NameAndMention()}\n**Nickname:** {memberInfo.Nickname}"; } else if (userInfo != null) { userStr = userInfo.NameAndMention(); } else { userStr = $"*(deleted user {msg.Message.Sender})*"; } // Put it all together var eb = new DiscordEmbedBuilder() .WithAuthor(msg.Member.NameFor(ctx), iconUrl: DiscordUtils.WorkaroundForUrlBug(msg.Member.AvatarFor(ctx))) .WithDescription(serverMsg?.Content?.NormalizeLineEndSpacing() ?? "*(message contents deleted or inaccessible)*") .WithImageUrl(serverMsg?.Attachments?.FirstOrDefault()?.Url) .AddField("System", msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true) .AddField("Member", $"{msg.Member.NameFor(ctx)} (`{msg.Member.Hid}`)", true) .AddField("Sent by", userStr, inline: true) .WithTimestamp(DiscordUtils.SnowflakeToInstant(msg.Message.Mid).ToDateTimeOffset()); var roles = memberInfo?.Roles?.ToList(); if (roles != null && roles.Count > 0) { eb.AddField($"Account roles ({roles.Count})", string.Join(", ", roles.Select(role => role.Name))); } return(eb.Build()); }