Zachary Turner
Zachary Turner

Reputation: 45

Discord.net 1.0 - How to get Messages to delete?

so I am having problems with my command. It doesn't seem to show any problems, but when I go to use the command i get this back from my bot.

"ERROR: The input text has too few parameters."

I don't know if I should be using IUserMessage, or SocketMessage, i've tried both and usually get the same error.

I don't know where I went wrong? I have tried to fix this for a while and i'm at a brick wall in trying to figure this out. Any help would be appreciated.

    [Command("purge")]
    [Summary("deletes set amount of text")]
    [RequireUserPermission(GuildPermission.Administrator)]
    [RequireBotPermission(GuildPermission.Administrator)]
    public async Task PurgeChat(IUserMessage msg, int amount)
    {
        int messagesDeleted = 0;
        var purgeMessage = await msg.Channel.SendMessageAsync("_purging in progress, give me a minute.._");
        var lastMessageID = purgeMessage.Id;


        try
        {
            var stop = false;
            while (amount > messagesDeleted)
            {
                var messages = await msg.Channel.GetMessagesAsync(lastMessageID, Direction.Before, 15).OfType<IUserMessage>().ToList();
                foreach (IUserMessage message in messages)
                {
                    await message.DeleteAsync();
                    messagesToDelete++;
                    if (messagesDeleted >= amount || messages.Count == 0)
                    {
                        stop = true;
                        break;
                    }
                    lastMessageID = messages.Last().Id;
                }
                if (stop || messages.Count == 0)
                {
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            if (ex.Message != "The server responded with error 404 (NotFound): \"Unknown Message\"")
            {
                await Context.Channel.SendMessageAsync("Something fucked up while trying to delete messages, you are going to have to manually Delete them for now. or try again");
            }
        }
        finally
        {
            await purgeMessage.ModifyAsync(x => x.Content = "_Purge Completed, this message will self destruct in 5 seconds_");
            await Task.Factory.StartNew(async () =>
             {
                 await Task.Delay(5000);
                 await purgeMessage.DeleteAsync();
             });
        }
    }

Upvotes: 3

Views: 20152

Answers (4)

Mr. Ds262 Pro
Mr. Ds262 Pro

Reputation: 11

My code to delete max messages without blocking threads.

Well, there you just need to get an array of messages and start deleting the message for each IMessage element.

[Command("clean")]
    public async Task Clean(int max)
    {

        var messages = Context.Channel.GetMessagesAsync(max).Flatten();
        foreach (var h in  await messages.ToArrayAsync())
        {
            await this.Context.Channel.DeleteMessageAsync(h);
        }
    }

Upvotes: 1

Solarcloud
Solarcloud

Reputation: 585

Here are 3 important points for future readers benefit:

1) Deleting many messages individually in a loop will cause a very unpleasant rate limit exception.

var messages = await msg.Channel.GetMessagesAsync();
foreach (IUserMessage message in messages)
{
     await message.DeleteAsync(); //rate limit exception if too many messages!!!
}

2) BULK Delete: You want to use the DeleteMessagesAsync() method that BBell gave in his answer to delete BULK messages. However it recently moved into ITextChannel. Here is an example how to use it now:

var messages = await msg.Channel.GetMessagesAsync(100).FlattenAsync(); //defualt is 100
await (Context.Channel as SocketTextChannel).DeleteMessagesAsync(messages);

Here is another example to access ITextChannel without a cast. Notice the difference?:

Context.Guild.GetTextChannel(id);  //yes, because it implements ITextChannel!
Context.Guild.GetChannel(id);   //no, cant delete messages.

This fooled me for a while.

3) Discord will not let you delete messages older than 2 weeks with DeleteMessagesAsync(). You will have to do each one manually with message.DeleteAsync().

I sincerely hope it helps!

Upvotes: 5

BBell
BBell

Reputation: 23

I see the problem. You took in an IUserMessage called msg as a parameter rather than just declaring it later. This expects the command to have an extra input that wouldn't really make sense for a purge command. Here's what I have:

    [Command("purge")]
    [Name("purge <amount>")]
    [Summary("Deletes a specified amount of messages")]
    [RequireBotPermission(GuildPermission.ManageMessages)]
    [RequireUserPermission(GuildPermission.ManageMessages)]
    public async Task DelMesAsync(int delnum)
    {
        var items = await Context.Channel.GetMessagesAsync(delnum + 1).Flatten();
        await Context.Channel.DeleteMessagesAsync(items);
    }

I took out all of the messaging parts but this should solve your parameter problem.

Upvotes: 1

Jyrka98
Jyrka98

Reputation: 530

[Command("purge", RunMode = RunMode.Async)]
[Summary("Deletes the specified amount of messages.")]
[RequireUserPermission(GuildPermission.Administrator)]
[RequireBotPermission(ChannelPermission.ManageMessages)]
public async Task PurgeChat(uint amount)
{
    var messages = await this.Context.Channel.GetMessagesAsync((int)amount + 1).Flatten();

    await this.Context.Channel.DeleteMessagesAsync(messages);
    const int delay = 5000;
    var m = await this.ReplyAsync($"Purge completed. _This message will be deleted in {delay / 1000} seconds._");
    await Task.Delay(delay);
    await m.DeleteAsync();
}

Upvotes: 5

Related Questions