0

I want to start off with saying this is a small server between me and my friends, and all of us have consented to the use of something like this, therefore I don't think it breaks any discord guidelines.

I first wrote some test code to test the bot being able to DM all users on the server, shown here:

[Command("dm")]
        public async Task DmAsync()
        {
            var guild = Program._client.GetGuild(Context.Guild.Id) as IGuild;
            await Context.Guild.DownloadUsersAsync();
            await Task.Delay(500);
            var users = await guild.GetUsersAsync();

            foreach (var user in users)
            {
                var u = user as IGuildUser;

                if (!u.IsBot && !u.IsWebhook)
                {
                    IUserMessage dm = await u.SendMessageAsync("Mass dm test", false);

                    if (dm == null)
                    {
                        continue;
                    }
                }
            }
        }

I was aware one of my friends has my bot blocked, so hence why I am checking if the dm is null. I thought that this would move past the error of The server responded with error 50007: Cannot send messages to this user, however I was wrong.

How would I go about continuing the foreach loop after this error is given, as it just completely stops the process and I would like the bot to just ignore it and keep sending DMs.

  • 1
    What is your question? – John Wu Jan 27 '19 at 02:57
  • How would I go about continuing the foreach loop after this error is given, as it just completely stops the process and I would like the bot to just ignore it and keep sending DMs. Editing into OP as well. – Praise Allah Jan 27 '19 at 03:07
  • Do you know how to use [try and catch](https://stackoverflow.com/questions/14973642/how-using-try-catch-for-exception-handling-is-best-practice) to handle exceptions? – John Wu Jan 27 '19 at 04:27
  • I would like to add that `Context.Client` is available at your disposal; avoid having your client as a global static variable. Additionally, `DownloadUsersAsync` can be omitted by setting `AlwaysDownloadUsers` within the client config. Still, this design and idea in general is not recommended due to mass spam on the API. – Still Jan 27 '19 at 05:45

2 Answers2

0

Ok, so I ended up figuring it out on my own after some additional googling and messing around in Visual Studio.

foreach (var user in users)
            {
                var u = user as IGuildUser;

                if (!u.IsBot && !u.IsWebhook)
                {
                    try
                    {
                        await u.SendMessageAsync("Hi");
                    }
                    catch (Exception e)
                    {
                        var useless = e;
                    }
                }
            }

I have Exception e set as a useless var because I quite frankly don't care what it is, I just wanted the foreach loop to continue to send DMs.

  • 1
    This is a bad design in the Discord API and should be prohibited; instead of mass messaging the user and spamming the API, one should instead mention a role which the users share and possess. – Still Jan 27 '19 at 05:43
0

For fun I wrote a version, that will actually run the tasks in parallel. Yours just waits for each one then moves on to the next.

var recipients = users
    .OfType<IGuildUser>()
    .Where
    (
        u => !u.IsBot && !u.IsWebhook
    );
var tasks = recipients
    .Select
    (
        r => r.SendMessageAsync("Hi")
    );
try
{
    await Task.WhenAll( tasks );
}
catch
{
    var exceptions = tasks.Where(t => t.Exception != null)
                          .Select(t => t.Exception);
}
Twenty
  • 5,234
  • 4
  • 32
  • 67
John Wu
  • 50,556
  • 8
  • 44
  • 80