internal static async Task UpdatePinsAsync(DateTimeOffset lastPinTimestamp, DiscordChannel channel, GuildData d, DiscordClient client) { if (d.Webhook != null) { if (!WebhookClient.Webhooks.Any(w => w.Id == d.Webhook.Id)) { d.Webhook = await client.GetWebhookWithTokenAsync(d.Webhook.Id, d.Webhook.Token); WebhookClient.AddWebhook(d.Webhook); } DiscordChannel pinsChannel = await client.GetChannelAsync(d.Webhook.ChannelId); if (lastPinTimestamp > d.LastPinTimestamp) { List <DiscordMessage> pins = new List <DiscordMessage>(); DiscordMember currentMember = channel.Guild.CurrentMember; if (!d.HasUpdatedPins) { var channels = channel.Guild.Channels.Where(c => c.Type == ChannelType.Text && !c.IsPrivate && c.PermissionsFor(currentMember).HasPermission(Permissions.AccessChannels)); if (!pinsChannel.IsNSFW) { channels = channels.Where(c => !c.IsNSFW); } foreach (DiscordChannel c in channels) { pins.AddRange(await c.GetPinnedMessagesAsync()); await Task.Delay(6000); } d.HasUpdatedPins = true; } else { pins.AddRange(await channel.GetPinnedMessagesAsync()); } foreach (var pin in pins.OrderBy(p => p.CreationTimestamp).Where(p => p.Id > d.LastPinnedMessage)) { try { var embeds = new List <DiscordEmbed>(); foreach (var attachment in pin.Attachments) { var builder = new DiscordEmbedBuilder() .WithAuthor(pin.Author?.Username ?? "Okay what the f**k?", null, pin.Author?.AvatarUrl) .WithTitle(attachment.FileName) .WithFooter($"In #{pin.Channel.Name}") .WithTimestamp(pin.CreationTimestamp); if (attachment.Width != 0) { builder = builder.WithImageUrl(attachment.Url); } else { builder = builder.WithUrl(attachment.Url); builder.AddField("Attachment URL", attachment.Url); } embeds.Add(builder.Build()); } string content = pin.Content .Replace("@everyone", "@ everyone") .Replace("@here", "@ here"); foreach (var user in pin.MentionedUsers) { content = content.Replace($"<@{user.Id}>", $"@{user.Username}") .Replace($"<@!{user.Id}>", $"@{user.Username}"); } foreach (var role in pin.MentionedRoles) { content = content.Replace(role.Mention, $"@{role.Name}"); } if (embeds.Any() || !string.IsNullOrWhiteSpace(content)) { await d.Webhook.ExecuteAsync(content, $"{(pin.Author?.Username ?? "Okay what the f**k?")} - in #{pin.Channel.Name}", pin.Author?.AvatarUrl ?? currentMember.DefaultAvatarUrl, false, embeds); await Task.Delay(1000); d.LastPinnedMessage = pin.Id; } } catch (Exception ex) { Debug.WriteLine(ex); } } } d.LastPinTimestamp = lastPinTimestamp; } }
public async Task SetupAsync(CommandContext ctx, [Description("Channel to direct pinned messages to")] DiscordChannel channel, [Description("The URL of the webhook to use, including a token (optional)")] Uri webhookUrl = null) { if (!ctx.Guild.Channels.ContainsKey(channel.Id)) { await ctx.RespondAsync("Are you trying to migrate pins across servers?? That ain't gonna fly, kid."); return; } var info = await _database.FindAsync <GuildInfo>((long)ctx.Guild.Id); if (info != null) { // TODO: prompt to reconfigure/setup _logger.LogError("Unable to setup pins in {0} because it is already setup.", ctx.Guild); await ctx.RespondAsync("Pinned message redireciton is already enabled in this server!"); return; } var perms = channel.PermissionsFor(ctx.Guild.CurrentMember); if (!perms.HasPermission(Permissions.ManageWebhooks) && webhookUrl == null) { _logger.LogError("Unable to setup pins in {0} due to lack of permissions.", ctx.Guild); await ctx.RespondAsync("I can't setup pins without a Webhook URL or permission to manage webhooks! Sorry!"); return; } DiscordWebhook hook; if (webhookUrl != null) { try { hook = await _webhookClient.AddWebhookAsync(webhookUrl); } catch (Exception ex) { _logger.LogError(ex, "Failed to fetch webhook from URL."); await ctx.RespondAsync("The Webhook URL you specified was invalid!"); return; } } else { hook = await channel.CreateWebhookAsync("GAiA Pins", reason : $"Pinned Message redirection setup by @{ctx.User.Username}#{ctx.User.Discriminator} ({ctx.User.Id})"); _webhookClient.AddWebhook(hook); } var guild = new GuildInfo() { Id = (long)ctx.Guild.Id, WebhookId = (long)hook.Id, WebhookToken = hook.Token, PinsChannelId = (long)channel.Id }; _database.Add(guild); await _database.SaveChangesAsync(); await ctx.RespondAsync( "Pinned messages are now setup for this server!\n" + "To migrate pins, use `p;migrate`, and to configure further, use `p;configure`.\n" + "Disable at any time with `p;disable`."); }