// , // /| __ // / | ,-~ / // 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)); }
public async Task ExecuteAsync(DiscordRestClient rest, PartnerSenderArguments senderArguments) { if (senderArguments.DevelopmentStressTest) { await ExecuteStressTestMessage(rest); return; } bool vanity = this.Match.VanityInvite is not null && this.Match.DonorRank >= DonorService.VANITY_LIMIT; bool attachEmbeds = this.Match.DonorRank >= DonorService.EMBED_LIMIT; DiscordWebhookBuilder?hook = new DiscordWebhookBuilder() .WithContent($"{this.Match.Message}\n\n" + $"https://discord.gg/" + $"{(vanity ? this.Match.VanityInvite : this.Match.Invite)}") .WithUsername($"{this.Match.GuildName} | Partner Bot"); if (attachEmbeds) { if (this.Match.DonorRank >= DonorService.HIGHEST_RANK) { hook.AddEmbeds(this.Match.MessageEmbeds); } else if (this.Match.MessageEmbeds.Count > 0) { hook.AddEmbed(this.Match.MessageEmbeds[0]); } } hook.AddEmbed(new DiscordEmbedBuilder() .WithColor(DiscordColor.Gray) .WithTitle("Partner Bot Advertisment") .WithDescription($"**ID:** {this.Match.GuildId}") .WithFooter($"pb-advert{(this.Match.NSFW ? " | NSFW" : "")}", rest.CurrentApplication.GetAvatarUrl(ImageFormat.Png)) .WithImageUrl(this.Match.Banner)); if (!string.IsNullOrWhiteSpace(this.Match.GuildIcon)) { hook.WithAvatarUrl(this.Match.GuildIcon); } await rest.ExecuteWebhookAsync(this.WebhookId, this.WebhookToken, hook); if (this.ExtraMessage is not null) { var eDat = new PartnerData(this, this.ExtraMessage); await eDat.ExecuteAsync(rest, senderArguments); } }
private async Task <DiscordMessage> ExecuteWebhookInner( DiscordChannel channel, DiscordWebhook webhook, string name, string avatarUrl, string content, IReadOnlyList <DiscordAttachment> attachments, IReadOnlyList <DiscordEmbed> embeds, 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); } dwb.AddEmbeds(embeds); 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 webhookMessage; using (_metrics.Measure.Timer.Time(BotMetrics.WebhookResponseTime)) { try { webhookMessage = 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, embeds, 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(webhookMessage); }