feat(webhooks): add all events except group member events
This commit is contained in:
parent
f071485a82
commit
7b9d2a4e5e
@ -10,6 +10,7 @@ namespace PluralKit.Core
|
|||||||
{
|
{
|
||||||
_logger.Information("Updated account {accountId}: {@AccountPatch}", id, patch);
|
_logger.Information("Updated account {accountId}: {@AccountPatch}", id, patch);
|
||||||
var query = patch.Apply(new Query("accounts").Where("uid", id));
|
var query = patch.Apply(new Query("accounts").Where("uid", id));
|
||||||
|
_ = _dispatch.Dispatch(id, patch);
|
||||||
await _db.ExecuteQuery(query, extraSql: "returning *");
|
await _db.ExecuteQuery(query, extraSql: "returning *");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
using SqlKata;
|
using SqlKata;
|
||||||
|
|
||||||
namespace PluralKit.Core
|
namespace PluralKit.Core
|
||||||
@ -62,22 +64,38 @@ namespace PluralKit.Core
|
|||||||
name = name
|
name = name
|
||||||
});
|
});
|
||||||
var group = await _db.QueryFirst<PKGroup>(conn, query, extraSql: "returning *");
|
var group = await _db.QueryFirst<PKGroup>(conn, query, extraSql: "returning *");
|
||||||
|
_ = _dispatch.Dispatch(group.Id, new UpdateDispatchData()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.CREATE_GROUP,
|
||||||
|
EventData = JObject.FromObject(new { name = name }),
|
||||||
|
});
|
||||||
_logger.Information("Created group {GroupId} in system {SystemId}: {GroupName}", group.Id, system, name);
|
_logger.Information("Created group {GroupId} in system {SystemId}: {GroupName}", group.Id, system, name);
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<PKGroup> UpdateGroup(GroupId id, GroupPatch patch, IPKConnection? conn = null)
|
public async Task<PKGroup> UpdateGroup(GroupId id, GroupPatch patch, IPKConnection? conn = null)
|
||||||
{
|
{
|
||||||
_logger.Information("Updated {GroupId}: {@GroupPatch}", id, patch);
|
_logger.Information("Updated {GroupId}: {@GroupPatch}", id, patch);
|
||||||
var query = patch.Apply(new Query("groups").Where("id", id));
|
var query = patch.Apply(new Query("groups").Where("id", id));
|
||||||
return _db.QueryFirst<PKGroup>(conn, query, extraSql: "returning *");
|
var group = await _db.QueryFirst<PKGroup>(conn, query, extraSql: "returning *");
|
||||||
|
_ = _dispatch.Dispatch(id, new()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.UPDATE_GROUP,
|
||||||
|
EventData = patch.ToJson(),
|
||||||
|
});
|
||||||
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task DeleteGroup(GroupId group)
|
public async Task DeleteGroup(GroupId group)
|
||||||
{
|
{
|
||||||
|
var oldGroup = await GetGroup(group);
|
||||||
|
|
||||||
_logger.Information("Deleted {GroupId}", group);
|
_logger.Information("Deleted {GroupId}", group);
|
||||||
var query = new Query("groups").AsDelete().Where("id", group);
|
var query = new Query("groups").AsDelete().Where("id", group);
|
||||||
return _db.ExecuteQuery(query);
|
await _db.ExecuteQuery(query);
|
||||||
|
|
||||||
|
if (oldGroup != null)
|
||||||
|
_ = _dispatch.Dispatch(oldGroup.System, oldGroup.Uuid, DispatchEvent.DELETE_GROUP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -39,14 +39,15 @@ namespace PluralKit.Core
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<SystemGuildSettings> UpdateSystemGuild(SystemId system, ulong guild, SystemGuildPatch patch)
|
public async Task<SystemGuildSettings> UpdateSystemGuild(SystemId system, ulong guild, SystemGuildPatch patch)
|
||||||
{
|
{
|
||||||
_logger.Information("Updated {SystemId} in guild {GuildId}: {@SystemGuildPatch}", system, guild, patch);
|
_logger.Information("Updated {SystemId} in guild {GuildId}: {@SystemGuildPatch}", system, guild, patch);
|
||||||
var query = patch.Apply(new Query("system_guild").Where("system", system).Where("guild", guild));
|
var query = patch.Apply(new Query("system_guild").Where("system", system).Where("guild", guild));
|
||||||
return _db.QueryFirst<SystemGuildSettings>(query, extraSql: "returning *");
|
var settings = await _db.QueryFirst<SystemGuildSettings>(query, extraSql: "returning *");
|
||||||
|
_ = _dispatch.Dispatch(system, guild, patch);
|
||||||
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Task<MemberGuildSettings> GetMemberGuild(ulong guild, MemberId member, bool defaultInsert = true)
|
public Task<MemberGuildSettings> GetMemberGuild(ulong guild, MemberId member, bool defaultInsert = true)
|
||||||
{
|
{
|
||||||
if (!defaultInsert)
|
if (!defaultInsert)
|
||||||
@ -69,6 +70,7 @@ namespace PluralKit.Core
|
|||||||
{
|
{
|
||||||
_logger.Information("Updated {MemberId} in guild {GuildId}: {@MemberGuildPatch}", member, guild, patch);
|
_logger.Information("Updated {MemberId} in guild {GuildId}: {@MemberGuildPatch}", member, guild, patch);
|
||||||
var query = patch.Apply(new Query("member_guild").Where("member", member).Where("guild", guild));
|
var query = patch.Apply(new Query("member_guild").Where("member", member).Where("guild", guild));
|
||||||
|
_ = _dispatch.Dispatch(member, guild, patch);
|
||||||
return _db.QueryFirst<MemberGuildSettings>(query, extraSql: "returning *");
|
return _db.QueryFirst<MemberGuildSettings>(query, extraSql: "returning *");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
using SqlKata;
|
using SqlKata;
|
||||||
|
|
||||||
namespace PluralKit.Core
|
namespace PluralKit.Core
|
||||||
@ -46,6 +49,15 @@ namespace PluralKit.Core
|
|||||||
return _db.QueryFirst<PKMember?>(query);
|
return _db.QueryFirst<PKMember?>(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<IEnumerable<Guid>> GetMemberGuids(IEnumerable<MemberId> ids)
|
||||||
|
{
|
||||||
|
var query = new Query("members")
|
||||||
|
.Select("uuid")
|
||||||
|
.WhereIn("id", ids);
|
||||||
|
|
||||||
|
return _db.Query<Guid>(query);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<PKMember> CreateMember(SystemId systemId, string memberName, IPKConnection? conn = null)
|
public async Task<PKMember> CreateMember(SystemId systemId, string memberName, IPKConnection? conn = null)
|
||||||
{
|
{
|
||||||
var query = new Query("members").AsInsert(new
|
var query = new Query("members").AsInsert(new
|
||||||
@ -57,6 +69,11 @@ namespace PluralKit.Core
|
|||||||
var member = await _db.QueryFirst<PKMember>(conn, query, "returning *");
|
var member = await _db.QueryFirst<PKMember>(conn, query, "returning *");
|
||||||
_logger.Information("Created {MemberId} in {SystemId}: {MemberName}",
|
_logger.Information("Created {MemberId} in {SystemId}: {MemberName}",
|
||||||
member.Id, systemId, memberName);
|
member.Id, systemId, memberName);
|
||||||
|
_ = _dispatch.Dispatch(member.Id, new()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.CREATE_MEMBER,
|
||||||
|
EventData = JObject.FromObject(new { name = memberName }),
|
||||||
|
});
|
||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,14 +81,25 @@ namespace PluralKit.Core
|
|||||||
{
|
{
|
||||||
_logger.Information("Updated {MemberId}: {@MemberPatch}", id, patch);
|
_logger.Information("Updated {MemberId}: {@MemberPatch}", id, patch);
|
||||||
var query = patch.Apply(new Query("members").Where("id", id));
|
var query = patch.Apply(new Query("members").Where("id", id));
|
||||||
|
_ = _dispatch.Dispatch(id, new()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.UPDATE_MEMBER,
|
||||||
|
EventData = patch.ToJson(),
|
||||||
|
});
|
||||||
return _db.QueryFirst<PKMember>(conn, query, extraSql: "returning *");
|
return _db.QueryFirst<PKMember>(conn, query, extraSql: "returning *");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task DeleteMember(MemberId id)
|
public async Task DeleteMember(MemberId id)
|
||||||
{
|
{
|
||||||
|
var oldMember = await GetMember(id);
|
||||||
|
|
||||||
_logger.Information("Deleted {MemberId}", id);
|
_logger.Information("Deleted {MemberId}", id);
|
||||||
var query = new Query("members").AsDelete().Where("id", id);
|
var query = new Query("members").AsDelete().Where("id", id);
|
||||||
return _db.ExecuteQuery(query);
|
await _db.ExecuteQuery(query);
|
||||||
|
|
||||||
|
// shh, compiler
|
||||||
|
if (oldMember != null)
|
||||||
|
_ = _dispatch.Dispatch(oldMember.System, oldMember.Uuid, DispatchEvent.DELETE_MEMBER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,8 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
using Dapper;
|
using Dapper;
|
||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
|
|
||||||
using NpgsqlTypes;
|
using NpgsqlTypes;
|
||||||
@ -42,8 +44,19 @@ namespace PluralKit.Core
|
|||||||
await tx.CommitAsync();
|
await tx.CommitAsync();
|
||||||
|
|
||||||
_logger.Information("Created {SwitchId} in {SystemId}: {Members}", sw.Id, system, members);
|
_logger.Information("Created {SwitchId} in {SystemId}: {Members}", sw.Id, system, members);
|
||||||
|
_ = _dispatch.Dispatch(sw.Id, new()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.CREATE_SWITCH,
|
||||||
|
EventData = JObject.FromObject(new
|
||||||
|
{
|
||||||
|
id = sw.Uuid.ToString(),
|
||||||
|
timestamp = sw.Timestamp.FormatExport(),
|
||||||
|
members = await GetMemberGuids(members),
|
||||||
|
}),
|
||||||
|
});
|
||||||
return sw;
|
return sw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EditSwitch(IPKConnection conn, SwitchId switchId, IReadOnlyCollection<MemberId> members)
|
public async Task EditSwitch(IPKConnection conn, SwitchId switchId, IReadOnlyCollection<MemberId> members)
|
||||||
{
|
{
|
||||||
// Use a transaction here since we're doing multiple executed commands in one
|
// Use a transaction here since we're doing multiple executed commands in one
|
||||||
@ -69,28 +82,52 @@ namespace PluralKit.Core
|
|||||||
// Finally we commit the tx, since the using block will otherwise rollback it
|
// Finally we commit the tx, since the using block will otherwise rollback it
|
||||||
await tx.CommitAsync();
|
await tx.CommitAsync();
|
||||||
|
|
||||||
|
_ = _dispatch.Dispatch(switchId, new()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.UPDATE_SWITCH_MEMBERS,
|
||||||
|
EventData = JObject.FromObject(new
|
||||||
|
{
|
||||||
|
members = await GetMemberGuids(members),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
_logger.Information("Updated {SwitchId} members: {Members}", switchId, members);
|
_logger.Information("Updated {SwitchId} members: {Members}", switchId, members);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task MoveSwitch(SwitchId id, Instant time)
|
public async Task MoveSwitch(SwitchId id, Instant time)
|
||||||
{
|
{
|
||||||
_logger.Information("Updated {SwitchId} timestamp: {SwitchTimestamp}", id, time);
|
_logger.Information("Updated {SwitchId} timestamp: {SwitchTimestamp}", id, time);
|
||||||
var query = new Query("switches").AsUpdate(new { timestamp = time }).Where("id", id);
|
var query = new Query("switches").AsUpdate(new { timestamp = time }).Where("id", id);
|
||||||
return _db.ExecuteQuery(query);
|
await _db.ExecuteQuery(query);
|
||||||
|
_ = _dispatch.Dispatch(id, new()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.UPDATE_SWITCH,
|
||||||
|
EventData = JObject.FromObject(new
|
||||||
|
{
|
||||||
|
timestamp = time.FormatExport(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task DeleteSwitch(SwitchId id)
|
public async Task DeleteSwitch(SwitchId id)
|
||||||
{
|
{
|
||||||
_logger.Information("Deleted {Switch}", id);
|
var existingSwitch = await GetSwitch(id);
|
||||||
|
|
||||||
var query = new Query("switches").AsDelete().Where("id", id);
|
var query = new Query("switches").AsDelete().Where("id", id);
|
||||||
return _db.ExecuteQuery(query);
|
await _db.ExecuteQuery(query);
|
||||||
|
_logger.Information("Deleted {Switch}", id);
|
||||||
|
_ = _dispatch.Dispatch(existingSwitch.System, existingSwitch.Uuid, DispatchEvent.DELETE_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task DeleteAllSwitches(SystemId system)
|
public async Task DeleteAllSwitches(SystemId system)
|
||||||
{
|
{
|
||||||
_logger.Information("Deleted all switches in {SystemId}", system);
|
_logger.Information("Deleted all switches in {SystemId}", system);
|
||||||
var query = new Query("switches").AsDelete().Where("system", system);
|
var query = new Query("switches").AsDelete().Where("system", system);
|
||||||
return _db.ExecuteQuery(query);
|
await _db.ExecuteQuery(query);
|
||||||
|
_ = _dispatch.Dispatch(system, new UpdateDispatchData()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.DELETE_ALL_SWITCHES
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAsyncEnumerable<PKSwitch> GetSwitches(SystemId system)
|
public IAsyncEnumerable<PKSwitch> GetSwitches(SystemId system)
|
||||||
|
@ -78,17 +78,27 @@ namespace PluralKit.Core
|
|||||||
});
|
});
|
||||||
var system = await _db.QueryFirst<PKSystem>(conn, query, extraSql: "returning *");
|
var system = await _db.QueryFirst<PKSystem>(conn, query, extraSql: "returning *");
|
||||||
_logger.Information("Created {SystemId}", system.Id);
|
_logger.Information("Created {SystemId}", system.Id);
|
||||||
|
|
||||||
|
// no dispatch call here - system was just created, we don't have a webhook URL
|
||||||
return system;
|
return system;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<PKSystem> UpdateSystem(SystemId id, SystemPatch patch, IPKConnection? conn = null)
|
public async Task<PKSystem> UpdateSystem(SystemId id, SystemPatch patch, IPKConnection? conn = null)
|
||||||
{
|
{
|
||||||
_logger.Information("Updated {SystemId}: {@SystemPatch}", id, patch);
|
_logger.Information("Updated {SystemId}: {@SystemPatch}", id, patch);
|
||||||
var query = patch.Apply(new Query("systems").Where("id", id));
|
var query = patch.Apply(new Query("systems").Where("id", id));
|
||||||
return _db.QueryFirst<PKSystem>(conn, query, extraSql: "returning *");
|
var res = await _db.QueryFirst<PKSystem>(conn, query, extraSql: "returning *");
|
||||||
|
|
||||||
|
_ = _dispatch.Dispatch(id, new UpdateDispatchData()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.UPDATE_SYSTEM,
|
||||||
|
EventData = patch.ToJson(),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task AddAccount(SystemId system, ulong accountId, IPKConnection? conn = null)
|
public async Task AddAccount(SystemId system, ulong accountId, IPKConnection? conn = null)
|
||||||
{
|
{
|
||||||
// We have "on conflict do nothing" since linking an account when it's already linked to the same system is idempotent
|
// We have "on conflict do nothing" since linking an account when it's already linked to the same system is idempotent
|
||||||
// This is used in import/export, although the pk;link command checks for this case beforehand
|
// This is used in import/export, although the pk;link command checks for this case beforehand
|
||||||
@ -100,7 +110,13 @@ namespace PluralKit.Core
|
|||||||
});
|
});
|
||||||
|
|
||||||
_logger.Information("Linked account {UserId} to {SystemId}", accountId, system);
|
_logger.Information("Linked account {UserId} to {SystemId}", accountId, system);
|
||||||
return _db.ExecuteQuery(conn, query, extraSql: "on conflict do nothing");
|
await _db.ExecuteQuery(conn, query, extraSql: "on conflict do nothing");
|
||||||
|
|
||||||
|
_ = _dispatch.Dispatch(system, new UpdateDispatchData()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.LINK_ACCOUNT,
|
||||||
|
EntityId = accountId.ToString(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RemoveAccount(SystemId system, ulong accountId)
|
public async Task RemoveAccount(SystemId system, ulong accountId)
|
||||||
@ -108,6 +124,11 @@ namespace PluralKit.Core
|
|||||||
var query = new Query("accounts").AsDelete().Where("uid", accountId).Where("system", system);
|
var query = new Query("accounts").AsDelete().Where("uid", accountId).Where("system", system);
|
||||||
await _db.ExecuteQuery(query);
|
await _db.ExecuteQuery(query);
|
||||||
_logger.Information("Unlinked account {UserId} from {SystemId}", accountId, system);
|
_logger.Information("Unlinked account {UserId} from {SystemId}", accountId, system);
|
||||||
|
_ = _dispatch.Dispatch(system, new UpdateDispatchData()
|
||||||
|
{
|
||||||
|
Event = DispatchEvent.UNLINK_ACCOUNT,
|
||||||
|
EntityId = accountId.ToString(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task DeleteSystem(SystemId id)
|
public Task DeleteSystem(SystemId id)
|
||||||
|
@ -191,6 +191,23 @@ namespace PluralKit.Core
|
|||||||
await DoPostRequest(system.Id, system.WebhookUrl, data.GetPayloadBody());
|
await DoPostRequest(system.Id, system.WebhookUrl, data.GetPayloadBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Dispatch(ulong accountId, AccountPatch patch)
|
||||||
|
{
|
||||||
|
var repo = _provider.Resolve<ModelRepository>();
|
||||||
|
var system = await repo.GetSystemByAccount(accountId);
|
||||||
|
if (system.WebhookUrl == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var data = new UpdateDispatchData();
|
||||||
|
data.Event = DispatchEvent.UPDATE_MEMBER_GUILD;
|
||||||
|
data.SigningToken = system.WebhookToken;
|
||||||
|
data.EntityId = accountId.ToString();
|
||||||
|
data.EventData = patch.ToJson();
|
||||||
|
|
||||||
|
_logger.Debug("Dispatching webhook for account {AccountId} (system {SystemId})", accountId, system.Id);
|
||||||
|
await DoPostRequest(system.Id, system.WebhookUrl, data.GetPayloadBody());
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Dispatch(SystemId systemId, Guid uuid, DispatchEvent evt)
|
public async Task Dispatch(SystemId systemId, Guid uuid, DispatchEvent evt)
|
||||||
{
|
{
|
||||||
var repo = _provider.Resolve<ModelRepository>();
|
var repo = _provider.Resolve<ModelRepository>();
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using SqlKata;
|
using SqlKata;
|
||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace PluralKit.Core
|
namespace PluralKit.Core
|
||||||
{
|
{
|
||||||
public class AccountPatch: PatchObject
|
public class AccountPatch: PatchObject
|
||||||
@ -9,5 +11,15 @@ namespace PluralKit.Core
|
|||||||
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
|
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
|
||||||
.With("allow_autoproxy", AllowAutoproxy)
|
.With("allow_autoproxy", AllowAutoproxy)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public JObject ToJson()
|
||||||
|
{
|
||||||
|
var o = new JObject();
|
||||||
|
|
||||||
|
if (AllowAutoproxy.IsPresent)
|
||||||
|
o.Add("allow_autoproxy", AllowAutoproxy.Value);
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user