feat(api): add autoproxy endpoints
This commit is contained in:
parent
67ce371e7e
commit
c87979ef03
77
PluralKit.API/Controllers/v2/AutoproxyControllerV2.cs
Normal file
77
PluralKit.API/Controllers/v2/AutoproxyControllerV2.cs
Normal file
@ -0,0 +1,77 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using PluralKit.Core;
|
||||
|
||||
namespace PluralKit.API;
|
||||
|
||||
[ApiController]
|
||||
[Route("v2")]
|
||||
public class AutoproxyControllerV2: PKControllerBase
|
||||
{
|
||||
public AutoproxyControllerV2(IServiceProvider svc) : base(svc) { }
|
||||
|
||||
// asp.net why
|
||||
|
||||
[HttpGet("systems/{systemRef}/autoproxy")]
|
||||
public Task<IActionResult> GetWrapper([FromRoute] string systemRef, [FromQuery] ulong? guild_id, [FromQuery] ulong? channel_id)
|
||||
=> Entrypoint(systemRef, guild_id, channel_id, null);
|
||||
|
||||
[HttpPatch("systems/{systemRef}/autoproxy")]
|
||||
public Task<IActionResult> PatchWrapper([FromRoute] string systemRef, [FromQuery] ulong? guild_id, [FromQuery] ulong? channel_id, [FromBody] JObject? data)
|
||||
=> Entrypoint(systemRef, guild_id, channel_id, data);
|
||||
|
||||
public async Task<IActionResult> Entrypoint(string systemRef, ulong? guild_id, ulong? channel_id, JObject? data)
|
||||
{
|
||||
var system = await ResolveSystem(systemRef);
|
||||
if (ContextFor(system) != LookupContext.ByOwner)
|
||||
throw Errors.GenericMissingPermissions;
|
||||
|
||||
if (guild_id == null || channel_id != null)
|
||||
throw Errors.Unimplemented;
|
||||
|
||||
var settings = await _repo.GetAutoproxySettings(system.Id, guild_id, channel_id);
|
||||
if (settings == null)
|
||||
return NotFound();
|
||||
|
||||
if (HttpContext.Request.Method == "GET")
|
||||
return await Get(settings);
|
||||
else if (HttpContext.Request.Method == "PATCH")
|
||||
return await Patch(system, guild_id, channel_id, data, settings);
|
||||
else return StatusCode(415);
|
||||
}
|
||||
|
||||
private async Task<IActionResult> Get(AutoproxySettings settings)
|
||||
{
|
||||
string hid = null;
|
||||
if (settings.AutoproxyMember != null)
|
||||
hid = (await _repo.GetMember(settings.AutoproxyMember.Value))?.Hid;
|
||||
|
||||
return Ok(settings.ToJson(hid));
|
||||
}
|
||||
|
||||
private async Task<IActionResult> Patch(PKSystem system, ulong? guildId, ulong? channelId, JObject data, AutoproxySettings oldData)
|
||||
{
|
||||
var updateMember = data.ContainsKey("autoproxy_member");
|
||||
|
||||
PKMember? member = null;
|
||||
if (updateMember)
|
||||
member = await ResolveMember(data.Value<string>("autoproxy_member"));
|
||||
|
||||
var patch = AutoproxyPatch.FromJson(data, member?.Id);
|
||||
|
||||
patch.AssertIsValid();
|
||||
if (updateMember && member == null)
|
||||
patch.Errors.Add(new("autoproxy_member", "Member not found."));
|
||||
if (updateMember && ((patch.AutoproxyMode.IsPresent && patch.AutoproxyMode.Value == AutoproxyMode.Latch) || oldData.AutoproxyMode == AutoproxyMode.Latch))
|
||||
patch.Errors.Add(new("autoproxy_member", "Cannot update autoproxy member if autoproxy mode is set to latch"));
|
||||
if (patch.Errors.Count > 0)
|
||||
throw new ModelParseError(patch.Errors);
|
||||
|
||||
var res = await _repo.UpdateAutoproxy(system.Id, guildId, channelId, patch);
|
||||
if (!updateMember && oldData.AutoproxyMember != null)
|
||||
member = await _repo.GetMember(oldData.AutoproxyMember.Value);
|
||||
return Ok(res.ToJson(member?.Hid));
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ namespace PluralKit.Core;
|
||||
|
||||
public partial class ModelRepository
|
||||
{
|
||||
public async Task UpdateAutoproxy(SystemId system, ulong? guildId, ulong? channelId, AutoproxyPatch patch)
|
||||
public Task<AutoproxySettings> UpdateAutoproxy(SystemId system, ulong? guildId, ulong? channelId, AutoproxyPatch patch)
|
||||
{
|
||||
var locationStr = guildId != null ? "guild" : (channelId != null ? "channel" : "global");
|
||||
_logger.Information("Updated autoproxy for {SystemId} in location {location}: {@AutoproxyPatch}", system, locationStr, patch);
|
||||
@ -17,7 +17,7 @@ public partial class ModelRepository
|
||||
.Where("channel_id", channelId ?? 0)
|
||||
);
|
||||
_ = _dispatch.Dispatch(system, guildId, channelId, patch);
|
||||
await _db.ExecuteQuery(query);
|
||||
return _db.QueryFirst<AutoproxySettings>(query, "returning *");
|
||||
}
|
||||
|
||||
// todo: this might break with differently scoped autoproxy
|
||||
|
@ -16,7 +16,7 @@ public class AutoproxySettings
|
||||
{
|
||||
public AutoproxyMode AutoproxyMode { get; }
|
||||
public MemberId? AutoproxyMember { get; }
|
||||
public Instant LastLatchTimestamp { get; }
|
||||
public Instant? LastLatchTimestamp { get; }
|
||||
}
|
||||
|
||||
public static class AutoproxyExt
|
||||
@ -27,7 +27,8 @@ public static class AutoproxyExt
|
||||
|
||||
// tbd
|
||||
o.Add("autoproxy_mode", settings.AutoproxyMode.ToString().ToLower());
|
||||
o.Add("autoproxy_member", memberHid);
|
||||
o.Add("autoproxy_member", settings.AutoproxyMode == AutoproxyMode.Front ? null : memberHid);
|
||||
o.Add("last_latch_timestamp", settings.LastLatchTimestamp?.FormatExport());
|
||||
|
||||
return o;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using NodaTime;
|
||||
|
||||
using SqlKata;
|
||||
@ -16,4 +18,30 @@ public class AutoproxyPatch: PatchObject
|
||||
.With("autoproxy_member", AutoproxyMember)
|
||||
.With("last_latch_timestamp", LastLatchTimestamp)
|
||||
);
|
||||
|
||||
public new void AssertIsValid()
|
||||
{
|
||||
// this is checked in FromJson
|
||||
// not really the best way to do this, maybe fix at some point?
|
||||
if ((int?)AutoproxyMode.Value == -1)
|
||||
Errors.Add(new("autoproxy_mode"));
|
||||
}
|
||||
|
||||
public static AutoproxyPatch FromJson(JObject o, MemberId? autoproxyMember = null)
|
||||
{
|
||||
var p = new AutoproxyPatch();
|
||||
|
||||
if (o.ContainsKey("autoproxy_mode"))
|
||||
{
|
||||
var (autoproxyMode, error) = o.Value<JToken>("autoproxy_mode").ParseAutoproxyMode();
|
||||
if (error != null)
|
||||
p.AutoproxyMode = Partial<AutoproxyMode>.Present((AutoproxyMode)(-1));
|
||||
else
|
||||
p.AutoproxyMode = autoproxyMode.Value;
|
||||
}
|
||||
|
||||
p.AutoproxyMember = autoproxyMember ?? Partial<MemberId?>.Absent;
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
@ -60,6 +60,40 @@ Takes a partial [system guild settings](/api/models#system-guild-settings-model)
|
||||
|
||||
Returns a [system guild settings](/api/models#system-guild-settings-model) object on success.
|
||||
|
||||
### Get System Autoproxy Settings
|
||||
|
||||
GET `/systems/@me/autoproxy`
|
||||
|
||||
Query String Parameters
|
||||
|name|type|
|
||||
|---|---|
|
||||
|guild_id?|snowflake|
|
||||
|channel_id?|snowflake|
|
||||
|
||||
Returns an [autoproxy settings](/api/models/#autoproxy-settings-model) object on success.
|
||||
|
||||
::: warning
|
||||
Currently, only autoproxy with `guild_id` is supported. The API will return an error message if you specify `channel_id`, or do not specify a `guild_id`.
|
||||
:::
|
||||
|
||||
### Update System Autoproxy Settings
|
||||
|
||||
PATCH `/systems/@me/autoproxy`
|
||||
|
||||
Query String Parameters
|
||||
|name|type|
|
||||
|---|---|
|
||||
|guild_id?|snowflake|
|
||||
|channel_id?|snowflake|
|
||||
|
||||
Takes a partial [autoproxy settings](/api/models/#autoproxy-settings-model) object.
|
||||
|
||||
Returns an [autoproxy settings](/api/models/#autoproxy-settings-model) object on success.
|
||||
|
||||
::: warning
|
||||
Currently, only autoproxy with `guild_id` is supported. The API will return an error message if you specify `channel_id`, or do not specify a `guild_id`.
|
||||
:::
|
||||
|
||||
---
|
||||
## Members
|
||||
|
||||
|
@ -124,7 +124,14 @@ Every PluralKit entity has two IDs: a short (5-character) ID and a longer UUID.
|
||||
|tag|?string|79-character limit|
|
||||
|tag_enabled|boolean||
|
||||
|
||||
<!--
|
||||
|
||||
### Autoproxy settings model
|
||||
|key|type|notes|
|
||||
|---|---|---|
|
||||
|autoproxy_mode|[autoproxy mode](#autoproxy-mode-enum)||
|
||||
|autoproxy_member|?member id|must be `null` if autoproxy_mode is set to `front`|
|
||||
|last_latch_timestamp|?datetime|read-only|
|
||||
|
||||
#### Autoproxy mode enum
|
||||
|
||||
|key|description|
|
||||
@ -133,7 +140,6 @@ Every PluralKit entity has two IDs: a short (5-character) ID and a longer UUID.
|
||||
|front|autoproxy is set to the first member in the current fronters list, or disabled if the current switch contains no members|
|
||||
|latch|autoproxy is set to the last member who sent a proxied message in the server|
|
||||
|member|autoproxy is set to a specific member (see `autoproxy_member` key)|
|
||||
-->
|
||||
|
||||
### Member guild settings model
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user