Esempio n. 1
0
        private async Task <Message?> GetReferencedMessage(ulong channelId, ulong?referencedMessageId)
        {
            if (referencedMessageId == null)
            {
                return(null);
            }

            var botPermissions = _bot.PermissionsIn(channelId);

            if (!botPermissions.HasFlag(PermissionSet.ReadMessageHistory))
            {
                _logger.Warning("Tried to get referenced message in channel {ChannelId} to reply but bot does not have Read Message History",
                                channelId);
                return(null);
            }

            return(await _rest.GetMessage(channelId, referencedMessageId.Value));
        }
Esempio n. 2
0
        public async Task EditMessage(Context ctx)
        {
            var msg = await GetMessageToEdit(ctx);

            if (!ctx.HasNext())
            {
                throw new PKSyntaxError("You need to include the message to edit in.");
            }

            if (ctx.Author.Id != msg.Sender)
            {
                throw new PKError("Can't edit a message sent from a different account.");
            }

            var newContent = ctx.RemainderOrNull();

            var originalMsg = await _rest.GetMessage(msg.Channel, msg.Mid);

            try
            {
                await _webhookExecutor.EditWebhookMessage(msg.Channel, msg.Mid, newContent);

                if (ctx.Guild == null)
                {
                    await _rest.CreateReaction(ctx.Channel.Id, ctx.Message.Id, new() { Name = Emojis.Success });
                }

                if (ctx.BotPermissions.HasFlag(PermissionSet.ManageMessages))
                {
                    await _rest.DeleteMessage(ctx.Channel.Id, ctx.Message.Id);
                }

                await _logChannel.LogEditedMessage(ctx.MessageContext, msg, ctx.Message, originalMsg !, newContent);
            }
            catch (NotFoundException)
            {
                throw new PKError("Could not edit message.");
            }
        }
Esempio n. 3
0
        public async Task <Embed> CreateMessageInfoEmbed(FullMessage msg)
        {
            var channel = await _cache.GetOrFetchChannel(_rest, msg.Message.Channel);

            var ctx = LookupContext.ByNonOwner;

            Message serverMsg = null;

            try
            {
                serverMsg = await _rest.GetMessage(msg.Message.Channel, msg.Message.Mid);
            }
            catch (ForbiddenException)
            {
                // no permission, couldn't fetch, oh well
            }

            // 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)
            // TODO: optimize ordering here a bit with new cache impl; and figure what happens if bot leaves server -> channel still cached -> hits this bit and 401s?
            GuildMemberPartial memberInfo = null;
            User userInfo = null;

            if (channel != null)
            {
                GuildMember member = null;
                try
                {
                    member = await _rest.GetGuildMember(channel.GuildId !.Value, msg.Message.Sender);
                }
                catch (ForbiddenException)
                {
                    // no permission, couldn't fetch, oh well
                }

                if (member != null)
                {
                    // Don't do an extra request if we already have this info from the member lookup
                    userInfo = member.User;
                }
                memberInfo = member;
            }

            if (userInfo == null)
            {
                userInfo = await _cache.GetOrFetchUser(_rest, msg.Message.Sender);
            }

            // Calculate string displayed under "Sent by"
            string userStr;

            if (memberInfo != null && memberInfo.Nick != null)
            {
                userStr = $"**Username:** {userInfo.NameAndMention()}\n**Nickname:** {memberInfo.Nick}";
            }
            else if (userInfo != null)
            {
                userStr = userInfo.NameAndMention();
            }
            else
            {
                userStr = $"*(deleted user {msg.Message.Sender})*";
            }

            // Put it all together
            var eb = new EmbedBuilder()
                     .Author(new(msg.Member.NameFor(ctx), IconUrl: DiscordUtils.WorkaroundForUrlBug(msg.Member.AvatarFor(ctx))))
                     .Description(serverMsg?.Content?.NormalizeLineEndSpacing() ?? "*(message contents deleted or inaccessible)*")
                     .Image(new(serverMsg?.Attachments?.FirstOrDefault()?.Url))
                     .Field(new("System",
                                msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true))
                     .Field(new("Member", $"{msg.Member.NameFor(ctx)} (`{msg.Member.Hid}`)", true))
                     .Field(new("Sent by", userStr, true))
                     .Timestamp(DiscordUtils.SnowflakeToInstant(msg.Message.Mid).ToDateTimeOffset().ToString("O"));

            var roles = memberInfo?.Roles?.ToList();

            if (roles != null && roles.Count > 0)
            {
                // TODO: what if role isn't in cache? figure out a fallback
                var rolesString = string.Join(", ", roles.Select(id => _cache.GetRole(id))
                                              .OrderByDescending(role => role.Position)
                                              .Select(role => role.Name));
                eb.Field(new($"Account roles ({roles.Count})", rolesString.Truncate(1024)));
            }

            return(eb.Build());
        }