Пример #1
0
        //        ,
        //        /|      __
        //       / |   ,-~ /
        //      Y :|  //  /
        //      | jj /( .^
        //      >-"~"-v"
        //     /       Y
        //    jo  o    |
        //   ( ~T~j
        //    >._-' _./
        //   /   "~"  |
        //  Y _,  |
        // /| ;-"~ _  l
        /// l/ ,-"~    \
        //\//\/      .- \
        // Y        /    Y    -Row
        // l       I     !
        // ]\      _\    /"\
        //(" ~----( ~   Y.  )
        #endregion bunny


        public async Task <DiscordMessage> SendWebhookMessage(string content        = null,
                                                              DiscordEmbed[] embeds = null,
                                                              FileStream fileStream = null,
                                                              string fileName       = null)

        {
            var dwb = new DiscordWebhookBuilder();

            if (!(embeds is null))
            {
                if (embeds.Length > 10)
                {
                    throw new ArgumentException("More than 10 embeds provided.");
                }

                dwb.AddEmbeds(embeds);
            }

            if (!(content is null))
            {
                dwb.WithContent(content);
            }

            if (!(fileStream is null) && !(fileName is null))
            {
                dwb.AddFile(Path.GetFileName(fileName), fileStream);
            }

            if (embeds is null && content is null && fileStream is null)
            {
                throw new ArgumentException("Cannot send an empty message.");
            }

            return(await webhook.ExecuteAsync(dwb));
        }
        private async Task <ulong> ExecuteWebhookInner(DiscordChannel channel, DiscordWebhook webhook, string name, string avatarUrl, string content,
                                                       IReadOnlyList <DiscordAttachment> attachments, bool allowEveryone, bool hasRetried = false)
        {
            content = content.Truncate(2000);

            var dwb = new DiscordWebhookBuilder();

            dwb.WithUsername(FixClyde(name).Truncate(80));
            dwb.WithContent(content);
            dwb.AddMentions(content.ParseAllMentions(allowEveryone, channel.Guild));
            if (!string.IsNullOrWhiteSpace(avatarUrl))
            {
                dwb.WithAvatarUrl(avatarUrl);
            }

            var attachmentChunks = ChunkAttachmentsOrThrow(attachments, 8 * 1024 * 1024);

            if (attachmentChunks.Count > 0)
            {
                _logger.Information("Invoking webhook with {AttachmentCount} attachments totalling {AttachmentSize} MiB in {AttachmentChunks} chunks", attachments.Count, attachments.Select(a => a.FileSize).Sum() / 1024 / 1024, attachmentChunks.Count);
                await AddAttachmentsToBuilder(dwb, attachmentChunks[0]);
            }

            DiscordMessage response;

            using (_metrics.Measure.Timer.Time(BotMetrics.WebhookResponseTime)) {
                try
                {
                    response = await webhook.ExecuteAsync(dwb);
                }
                catch (JsonReaderException)
                {
                    // This happens sometimes when we hit a CloudFlare error (or similar) on Discord's end
                    // Nothing we can do about this - happens sometimes under server load, so just drop the message and give up
                    throw new WebhookExecutionErrorOnDiscordsEnd();
                }
                catch (NotFoundException e)
                {
                    var errorText = e.WebResponse?.Response;
                    if (errorText != null && errorText.Contains("10015") && !hasRetried)
                    {
                        // Error 10015 = "Unknown Webhook" - this likely means the webhook was deleted
                        // but is still in our cache. Invalidate, refresh, try again
                        _logger.Warning("Error invoking webhook {Webhook} in channel {Channel}", webhook.Id, webhook.ChannelId);

                        var newWebhook = await _webhookCache.InvalidateAndRefreshWebhook(channel, webhook);

                        return(await ExecuteWebhookInner(channel, newWebhook, name, avatarUrl, content, attachments, allowEveryone, hasRetried : true));
                    }

                    throw;
                }
            }

            // We don't care about whether the sending succeeds, and we don't want to *wait* for it, so we just fork it off
            var _ = TrySendRemainingAttachments(webhook, name, avatarUrl, attachmentChunks);

            return(response.Id);
        }
Пример #3
0
        public async Task SpoilCommand(CommandContext ctx, [Description("The message text"), RemainingText] string content)
        {
            var message = new DiscordWebhookBuilder();

            foreach (var attachment in ctx.Message.Attachments)
            {
                message.AddFile("SPOILER_" + attachment.FileName, GetStreamFromUrl(attachment.Url));
            }
            message.WithContent(content);
            message.WithAvatarUrl(ctx.Member.GetAvatarUrl(ImageFormat.Auto));
            message.WithUsername(ctx.Member.DisplayName);
            var webhook = (await ctx.Channel.GetWebhooksAsync()).FirstOrDefault();

            if (webhook == null)
            {
                webhook = await ctx.Channel.CreateWebhookAsync("SpoilHook");
            }
            await webhook.ExecuteAsync(message);
        }
Пример #4
0
        public async Task SendWebhookFilesAsync(CommandContext ctx)
        {
            var webhook = await ctx.Channel.CreateWebhookAsync("webhook-test");

            using (var fs = new FileStream("ADumbFile.txt", FileMode.Open, FileAccess.Read))
            {
                // Verify that the lib resets the position when asked
                var builder = new DiscordWebhookBuilder()
                              .WithContent("Testing the `AddFile(Dictionary<string, stream>)` Overload with resetting the postion turned on.")
                              .AddFiles(new Dictionary <string, Stream>()
                {
                    { "ADumbFile1.txt", fs }
                }, true);

                await builder.SendAsync(webhook);

                await builder.SendAsync(webhook);

                builder.Clear();

                //Verify the lib doesnt reset the position.  THe file sent should have 0 bytes.
                builder.WithContent("Testing the `AddFile(Dictionary<string, stream> files)` Overload with resetting the postion turned off  The 2nd file sent should have 0 bytes.")
                .AddFiles(new Dictionary <string, Stream>()
                {
                    { "ADumbFile1.txt", fs }
                }, false);

                await builder.SendAsync(webhook);

                await builder.SendAsync(webhook);

                builder.Clear();

                fs.Position = 0;

                // Verify that the lib resets the position when asked
                builder.WithContent("Testing the `AddFile(Stream stream)` Overload with resetting the postion turned on.")
                .AddFile(fs, true);

                await builder.SendAsync(webhook);

                await builder.SendAsync(webhook);

                builder.Clear();

                //Verify the lib doesnt reset the position.  THe file sent should have 0 bytes.
                builder.WithContent("Testing the `AddFile(Stream stream)` Overload with resetting the postion turned off.  The 2nd file sent should have 0 bytes.")
                .AddFile(fs, false);

                await builder.SendAsync(webhook);

                await builder.SendAsync(webhook);

                builder.Clear();
                fs.Position = 0;


                // Verify that the lib resets the position when asked
                builder.WithContent("Testing the `AddFile(string fileName, Stream stream)` Overload with resetting the postion turned on.")
                .AddFile("ADumbFile2.txt", fs, true);

                await builder.SendAsync(webhook);

                await builder.SendAsync(webhook);

                builder.Clear();

                //Verify the lib doesnt reset the position.  THe file sent should have 0 bytes.
                builder.WithContent("Testing the `AddFile(string fileName, Stream stream)` Overload with resetting the postion turned off.  The 2nd file sent should have 0 bytes.")
                .AddFile("ADumbFile2.txt", fs, false);

                await builder.SendAsync(webhook);

                await builder.SendAsync(webhook);
            }

            await webhook.DeleteAsync();
        }