From a81ffc3399053f9dbf122c4df1d41ec091936c57 Mon Sep 17 00:00:00 2001 From: spiral Date: Wed, 3 Nov 2021 02:01:35 -0400 Subject: [PATCH] feat(webhooks): add basic commands --- .../CommandSystem/ContextChecksExt.cs | 6 ++ PluralKit.Bot/Commands/Api.cs | 55 ++++++++++++++++++- PluralKit.Bot/Commands/CommandTree.cs | 2 + PluralKit.Core/Models/Patch/SystemPatch.cs | 4 ++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/PluralKit.Bot/CommandSystem/ContextChecksExt.cs b/PluralKit.Bot/CommandSystem/ContextChecksExt.cs index 25355837..8be4d24f 100644 --- a/PluralKit.Bot/CommandSystem/ContextChecksExt.cs +++ b/PluralKit.Bot/CommandSystem/ContextChecksExt.cs @@ -16,6 +16,12 @@ namespace PluralKit.Bot throw new PKError("This command can not be run in a DM."); } + public static Context CheckDMContext(this Context ctx) + { + if (ctx.Channel.GuildId == null) return ctx; + throw new PKError("This command must be run in a DM."); + } + public static Context CheckSystemPrivacy(this Context ctx, PKSystem target, PrivacyLevel level) { if (level.CanAccess(ctx.LookupContextFor(target))) return ctx; diff --git a/PluralKit.Bot/Commands/Api.cs b/PluralKit.Bot/Commands/Api.cs index c34ec9e3..ac276976 100644 --- a/PluralKit.Bot/Commands/Api.cs +++ b/PluralKit.Bot/Commands/Api.cs @@ -11,12 +11,12 @@ namespace PluralKit.Bot { public class Api { - private readonly IDatabase _db; private readonly ModelRepository _repo; - public Api(IDatabase db, ModelRepository repo) + private readonly DispatchService _dispatch; + public Api(ModelRepository repo, DispatchService dispatch) { - _db = db; _repo = repo; + _dispatch = dispatch; } public async Task GetToken(Context ctx) @@ -91,5 +91,54 @@ namespace PluralKit.Bot await ctx.Reply($"{Emojis.Error} Could not send token in DMs. Are your DMs closed?"); } } + + public async Task SystemWebhook(Context ctx) + { + ctx.CheckDMContext(); + + if (!ctx.HasNext(false)) + { + if (ctx.System.WebhookUrl == null) + await ctx.Reply("Your system does not have a webhook URL set. Set one with `pk;system webhook `!"); + else + await ctx.Reply($"Your system's webhook URL is <{ctx.System.WebhookUrl}>."); + return; + } + + if (await ctx.MatchClear("your system's webhook URL")) + { + await _repo.UpdateSystem(ctx.System.Id, new() + { + WebhookUrl = null, + Token = null, + }); + + await ctx.Reply($"{Emojis.Success} System webhook URL removed."); + return; + } + + var newUrl = ctx.RemainderOrNull(); + if (!await DispatchExt.ValidateUri(newUrl)) + { + await ctx.Reply($"New URL '{newUrl}' is invalid. Are you sure this is a valid, publicly accessible URL?"); + return; + } + + var newToken = StringUtils.GenerateToken(); + + await _repo.UpdateSystem(ctx.System.Id, new() + { + WebhookUrl = newUrl, + Token = newToken, + }); + + await ctx.Reply($"{Emojis.Success} Successfully the new webhook URL for your system." + + $"\n\n{Emojis.Warn} The following token is used to authenticate requests from PluralKit to you." + + " If it leaks, you should clear and re-set the webhook URL to get a new token." + + "\ntodo: add link to docs or something" + ); + + await ctx.Reply(newToken); + } } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/CommandTree.cs b/PluralKit.Bot/Commands/CommandTree.cs index e484be8e..e274858a 100644 --- a/PluralKit.Bot/Commands/CommandTree.cs +++ b/PluralKit.Bot/Commands/CommandTree.cs @@ -286,6 +286,8 @@ namespace PluralKit.Bot await ctx.Execute(SystemAvatar, m => m.Avatar(ctx)); else if (ctx.Match("delete", "remove", "destroy", "erase", "yeet")) await ctx.Execute(SystemDelete, m => m.Delete(ctx)); + else if (ctx.Match("webhook", "hook")) + await ctx.Execute(null, m => m.SystemWebhook(ctx)); else if (ctx.Match("timezone", "tz")) await ctx.Execute(SystemTimezone, m => m.SystemTimezone(ctx)); else if (ctx.Match("proxy")) diff --git a/PluralKit.Core/Models/Patch/SystemPatch.cs b/PluralKit.Core/Models/Patch/SystemPatch.cs index 40eff765..3e015ab7 100644 --- a/PluralKit.Core/Models/Patch/SystemPatch.cs +++ b/PluralKit.Core/Models/Patch/SystemPatch.cs @@ -20,6 +20,8 @@ namespace PluralKit.Core public Partial BannerImage { get; set; } public Partial Color { get; set; } public Partial Token { get; set; } + public Partial WebhookUrl { get; set; } + public Partial WebhookToken { get; set; } public Partial UiTz { get; set; } public Partial DescriptionPrivacy { get; set; } public Partial MemberListPrivacy { get; set; } @@ -40,6 +42,8 @@ namespace PluralKit.Core .With("banner_image", BannerImage) .With("color", Color) .With("token", Token) + .With("webhook_url", WebhookUrl) + .With("webhook_token", WebhookToken) .With("ui_tz", UiTz) .With("description_privacy", DescriptionPrivacy) .With("member_list_privacy", MemberListPrivacy)