Delete proxied message if the trigger message gets deleted by other means
This commit is contained in:
parent
8c12b3f037
commit
27c9e54f17
@ -96,45 +96,69 @@ namespace PluralKit.Bot
|
|||||||
// Send the webhook
|
// Send the webhook
|
||||||
var content = match.ProxyContent;
|
var content = match.ProxyContent;
|
||||||
if (!allowEmbeds) content = content.BreakLinkEmbeds();
|
if (!allowEmbeds) content = content.BreakLinkEmbeds();
|
||||||
var id = await _webhookExecutor.ExecuteWebhook(trigger.Channel, match.Member.ProxyName(ctx),
|
var proxyMessage = await _webhookExecutor.ExecuteWebhook(trigger.Channel, match.Member.ProxyName(ctx),
|
||||||
match.Member.ProxyAvatar(ctx),
|
match.Member.ProxyAvatar(ctx),
|
||||||
content, trigger.Attachments, allowEveryone);
|
content, trigger.Attachments, allowEveryone);
|
||||||
|
|
||||||
Task SaveMessage() => _repo.AddMessage(conn, new PKMessage
|
await HandleProxyExecutedActions(conn, ctx, trigger, proxyMessage, match);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleProxyExecutedActions(IPKConnection conn, MessageContext ctx,
|
||||||
|
DiscordMessage triggerMessage, DiscordMessage proxyMessage,
|
||||||
|
ProxyMatch match)
|
||||||
|
{
|
||||||
|
Task SaveMessageInDatabase() => _repo.AddMessage(conn, new PKMessage
|
||||||
{
|
{
|
||||||
Channel = trigger.ChannelId,
|
Channel = triggerMessage.ChannelId,
|
||||||
Guild = trigger.Channel.GuildId,
|
Guild = triggerMessage.Channel.GuildId,
|
||||||
Member = match.Member.Id,
|
Member = match.Member.Id,
|
||||||
Mid = id,
|
Mid = proxyMessage.Id,
|
||||||
OriginalMid = trigger.Id,
|
OriginalMid = triggerMessage.Id,
|
||||||
Sender = trigger.Author.Id
|
Sender = triggerMessage.Author.Id
|
||||||
});
|
});
|
||||||
|
|
||||||
Task LogMessage() => _logChannel.LogMessage(ctx, match, trigger, id).AsTask();
|
Task LogMessageToChannel() => _logChannel.LogMessage(ctx, match, triggerMessage, proxyMessage.Id).AsTask();
|
||||||
async Task DeleteMessage()
|
|
||||||
|
async Task DeleteProxyTriggerMessage()
|
||||||
{
|
{
|
||||||
// Wait a second or so before deleting the original message
|
// Wait a second or so before deleting the original message
|
||||||
await Task.Delay(MessageDeletionDelay);
|
await Task.Delay(MessageDeletionDelay);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await trigger.DeleteAsync();
|
await triggerMessage.DeleteAsync();
|
||||||
}
|
}
|
||||||
catch (NotFoundException)
|
catch (NotFoundException)
|
||||||
{
|
{
|
||||||
// If it's already deleted, we just log and swallow the exception
|
_logger.Debug("Trigger message {TriggerMessageId} was already deleted when we attempted to; deleting proxy message {ProxyMessageId} also",
|
||||||
_logger.Warning("Attempted to delete already deleted proxy trigger message {Message}", trigger.Id);
|
triggerMessage.Id, proxyMessage.Id);
|
||||||
|
await HandleTriggerAlreadyDeleted(proxyMessage);
|
||||||
|
// Swallow the exception, we don't need it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run post-proxy actions (simultaneously; order doesn't matter)
|
// Run post-proxy actions (simultaneously; order doesn't matter)
|
||||||
// Note that only AddMessage is using our passed-in connection, careful not to pass it elsewhere and run into conflicts
|
// Note that only AddMessage is using our passed-in connection, careful not to pass it elsewhere and run into conflicts
|
||||||
await Task.WhenAll(
|
await Task.WhenAll(
|
||||||
DeleteMessage(),
|
DeleteProxyTriggerMessage(),
|
||||||
SaveMessage(),
|
SaveMessageInDatabase(),
|
||||||
LogMessage()
|
LogMessageToChannel()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task HandleTriggerAlreadyDeleted(DiscordMessage proxyMessage)
|
||||||
|
{
|
||||||
|
// If a trigger message is deleted before we get to delete it, we can assume a mod bot or similar got to it
|
||||||
|
// In this case we should also delete the now-proxied message.
|
||||||
|
// This is going to hit the message delete event handler also, so that'll do the cleanup for us
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await proxyMessage.DeleteAsync();
|
||||||
|
}
|
||||||
|
catch (NotFoundException) { }
|
||||||
|
catch (UnauthorizedException) { }
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> CheckBotPermissionsOrError(DiscordChannel channel)
|
private async Task<bool> CheckBotPermissionsOrError(DiscordChannel channel)
|
||||||
{
|
{
|
||||||
var permissions = channel.BotPermissions();
|
var permissions = channel.BotPermissions();
|
||||||
|
@ -42,23 +42,23 @@ namespace PluralKit.Bot
|
|||||||
_logger = logger.ForContext<WebhookExecutorService>();
|
_logger = logger.ForContext<WebhookExecutorService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ulong> ExecuteWebhook(DiscordChannel channel, string name, string avatarUrl, string content, IReadOnlyList<DiscordAttachment> attachments, bool allowEveryone)
|
public async Task<DiscordMessage> ExecuteWebhook(DiscordChannel channel, string name, string avatarUrl, string content, IReadOnlyList<DiscordAttachment> attachments, bool allowEveryone)
|
||||||
{
|
{
|
||||||
_logger.Verbose("Invoking webhook in channel {Channel}", channel.Id);
|
_logger.Verbose("Invoking webhook in channel {Channel}", channel.Id);
|
||||||
|
|
||||||
// Get a webhook, execute it
|
// Get a webhook, execute it
|
||||||
var webhook = await _webhookCache.GetWebhook(channel);
|
var webhook = await _webhookCache.GetWebhook(channel);
|
||||||
var id = await ExecuteWebhookInner(channel, webhook, name, avatarUrl, content, attachments, allowEveryone);
|
var webhookMessage = await ExecuteWebhookInner(channel, webhook, name, avatarUrl, content, attachments, allowEveryone);
|
||||||
|
|
||||||
// Log the relevant metrics
|
// Log the relevant metrics
|
||||||
_metrics.Measure.Meter.Mark(BotMetrics.MessagesProxied);
|
_metrics.Measure.Meter.Mark(BotMetrics.MessagesProxied);
|
||||||
_logger.Information("Invoked webhook {Webhook} in channel {Channel}", webhook.Id,
|
_logger.Information("Invoked webhook {Webhook} in channel {Channel}", webhook.Id,
|
||||||
channel.Id);
|
channel.Id);
|
||||||
|
|
||||||
return id;
|
return webhookMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ulong> ExecuteWebhookInner(DiscordChannel channel, DiscordWebhook webhook, string name, string avatarUrl, string content,
|
private async Task<DiscordMessage> ExecuteWebhookInner(DiscordChannel channel, DiscordWebhook webhook, string name, string avatarUrl, string content,
|
||||||
IReadOnlyList<DiscordAttachment> attachments, bool allowEveryone, bool hasRetried = false)
|
IReadOnlyList<DiscordAttachment> attachments, bool allowEveryone, bool hasRetried = false)
|
||||||
{
|
{
|
||||||
content = content.Truncate(2000);
|
content = content.Truncate(2000);
|
||||||
@ -77,11 +77,11 @@ namespace PluralKit.Bot
|
|||||||
await AddAttachmentsToBuilder(dwb, attachmentChunks[0]);
|
await AddAttachmentsToBuilder(dwb, attachmentChunks[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscordMessage response;
|
DiscordMessage webhookMessage;
|
||||||
using (_metrics.Measure.Timer.Time(BotMetrics.WebhookResponseTime)) {
|
using (_metrics.Measure.Timer.Time(BotMetrics.WebhookResponseTime)) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
response = await webhook.ExecuteAsync(dwb);
|
webhookMessage = await webhook.ExecuteAsync(dwb);
|
||||||
}
|
}
|
||||||
catch (JsonReaderException)
|
catch (JsonReaderException)
|
||||||
{
|
{
|
||||||
@ -109,7 +109,7 @@ namespace PluralKit.Bot
|
|||||||
// We don't care about whether the sending succeeds, and we don't want to *wait* for it, so we just fork it off
|
// 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);
|
var _ = TrySendRemainingAttachments(webhook, name, avatarUrl, attachmentChunks);
|
||||||
|
|
||||||
return response.Id;
|
return webhookMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TrySendRemainingAttachments(DiscordWebhook webhook, string name, string avatarUrl, IReadOnlyList<IReadOnlyCollection<DiscordAttachment>> attachmentChunks)
|
private async Task TrySendRemainingAttachments(DiscordWebhook webhook, string name, string avatarUrl, IReadOnlyList<IReadOnlyCollection<DiscordAttachment>> attachmentChunks)
|
||||||
|
Loading…
Reference in New Issue
Block a user