feat(webhooks): SUCCESSFUL_IMPORT event, better behaviour when creating entities

This commit is contained in:
spiral 2021-11-25 15:33:02 -05:00
parent a05c3cfeed
commit bc7e0df872
No known key found for this signature in database
GPG Key ID: A6059F0CA0E1BD31
11 changed files with 73 additions and 27 deletions

View File

@ -22,12 +22,14 @@ namespace PluralKit.API
protected readonly ApiConfig _config; protected readonly ApiConfig _config;
protected readonly IDatabase _db; protected readonly IDatabase _db;
protected readonly ModelRepository _repo; protected readonly ModelRepository _repo;
protected readonly DispatchService _dispatch;
public PKControllerBase(IServiceProvider svc) public PKControllerBase(IServiceProvider svc)
{ {
_config = svc.GetRequiredService<ApiConfig>(); _config = svc.GetRequiredService<ApiConfig>();
_db = svc.GetRequiredService<IDatabase>(); _db = svc.GetRequiredService<IDatabase>();
_repo = svc.GetRequiredService<ModelRepository>(); _repo = svc.GetRequiredService<ModelRepository>();
_dispatch = svc.GetRequiredService<DispatchService>();
} }
protected Task<PKSystem?> ResolveSystem(string systemRef) protected Task<PKSystem?> ResolveSystem(string systemRef)

View File

@ -69,6 +69,14 @@ namespace PluralKit.API
var newGroup = await _repo.CreateGroup(system.Id, patch.Name.Value, conn); var newGroup = await _repo.CreateGroup(system.Id, patch.Name.Value, conn);
newGroup = await _repo.UpdateGroup(newGroup.Id, patch, conn); newGroup = await _repo.UpdateGroup(newGroup.Id, patch, conn);
_ = _dispatch.Dispatch(newGroup.Id, new UpdateDispatchData()
{
Event = DispatchEvent.CREATE_GROUP,
EventData = patch.ToJson(),
});
await tx.CommitAsync(); await tx.CommitAsync();
return Ok(newGroup.ToJson(LookupContext.ByOwner)); return Ok(newGroup.ToJson(LookupContext.ByOwner));

View File

@ -55,6 +55,12 @@ namespace PluralKit.API
var newMember = await _repo.CreateMember(system.Id, patch.Name.Value, conn); var newMember = await _repo.CreateMember(system.Id, patch.Name.Value, conn);
newMember = await _repo.UpdateMember(newMember.Id, patch, conn); newMember = await _repo.UpdateMember(newMember.Id, patch, conn);
_ = _dispatch.Dispatch(newMember.Id, new()
{
Event = DispatchEvent.CREATE_MEMBER,
EventData = patch.ToJson(),
});
await tx.CommitAsync(); await tx.CommitAsync();
return Ok(newMember.ToJson(LookupContext.ByOwner, v: APIVersion.V2)); return Ok(newMember.ToJson(LookupContext.ByOwner, v: APIVersion.V2));

View File

@ -10,6 +10,8 @@ using Dapper;
using Humanizer; using Humanizer;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Myriad.Builders; using Myriad.Builders;
@ -24,13 +26,15 @@ namespace PluralKit.Bot
private readonly ModelRepository _repo; private readonly ModelRepository _repo;
private readonly EmbedService _embeds; private readonly EmbedService _embeds;
private readonly HttpClient _client; private readonly HttpClient _client;
private readonly DispatchService _dispatch;
public Groups(IDatabase db, ModelRepository repo, EmbedService embeds, HttpClient client) public Groups(IDatabase db, ModelRepository repo, EmbedService embeds, HttpClient client, DispatchService dispatch)
{ {
_db = db; _db = db;
_repo = repo; _repo = repo;
_embeds = embeds; _embeds = embeds;
_client = client; _client = client;
_dispatch = dispatch;
} }
public async Task CreateGroup(Context ctx) public async Task CreateGroup(Context ctx)
@ -59,6 +63,12 @@ namespace PluralKit.Bot
var newGroup = await _repo.CreateGroup(ctx.System.Id, groupName); var newGroup = await _repo.CreateGroup(ctx.System.Id, groupName);
_ = _dispatch.Dispatch(newGroup.Id, new UpdateDispatchData()
{
Event = DispatchEvent.CREATE_GROUP,
EventData = JObject.FromObject(new { name = groupName }),
});
var eb = new EmbedBuilder() var eb = new EmbedBuilder()
.Description($"Your new group, **{groupName}**, has been created, with the group ID **`{newGroup.Hid}`**.\nBelow are a couple of useful commands:") .Description($"Your new group, **{groupName}**, has been created, with the group ID **`{newGroup.Hid}`**.\nBelow are a couple of useful commands:")
.Field(new("View the group card", $"> pk;group **{newGroup.Reference()}**")) .Field(new("View the group card", $"> pk;group **{newGroup.Reference()}**"))

View File

@ -21,13 +21,15 @@ namespace PluralKit.Bot
private readonly ModelRepository _repo; private readonly ModelRepository _repo;
private readonly EmbedService _embeds; private readonly EmbedService _embeds;
private readonly HttpClient _client; private readonly HttpClient _client;
private readonly DispatchService _dispatch;
public Member(EmbedService embeds, IDatabase db, ModelRepository repo, HttpClient client) public Member(EmbedService embeds, IDatabase db, ModelRepository repo, HttpClient client, DispatchService dispatch)
{ {
_embeds = embeds; _embeds = embeds;
_db = db; _db = db;
_repo = repo; _repo = repo;
_client = client; _client = client;
_dispatch = dispatch;
} }
public async Task NewMember(Context ctx) public async Task NewMember(Context ctx)
@ -62,12 +64,20 @@ namespace PluralKit.Bot
// Try to match an image attached to the message // Try to match an image attached to the message
var avatarArg = ctx.Message.Attachments.FirstOrDefault(); var avatarArg = ctx.Message.Attachments.FirstOrDefault();
Exception imageMatchError = null; Exception imageMatchError = null;
bool sentDispatch = false;
if (avatarArg != null) if (avatarArg != null)
{ {
try try
{ {
await AvatarUtils.VerifyAvatarOrThrow(_client, avatarArg.Url); await AvatarUtils.VerifyAvatarOrThrow(_client, avatarArg.Url);
await _repo.UpdateMember(member.Id, new MemberPatch { AvatarUrl = avatarArg.Url }); await _db.Execute(conn => _repo.UpdateMember(member.Id, new MemberPatch { AvatarUrl = avatarArg.Url }, conn));
_ = _dispatch.Dispatch(member.Id, new()
{
Event = DispatchEvent.CREATE_MEMBER,
EventData = JObject.FromObject(new { name = memberName, avatar_url = avatarArg.Url }),
});
sentDispatch = true;
} }
catch (Exception e) catch (Exception e)
{ {
@ -75,6 +85,13 @@ namespace PluralKit.Bot
} }
} }
if (!sentDispatch)
_ = _dispatch.Dispatch(member.Id, new()
{
Event = DispatchEvent.CREATE_MEMBER,
EventData = JObject.FromObject(new { name = memberName }),
});
// Send confirmation and space hint // Send confirmation and space hint
await ctx.Reply($"{Emojis.Success} Member \"{memberName}\" (`{member.Hid}`) registered! Check out the getting started page for how to get a member up and running: https://pluralkit.me/start#create-a-member"); await ctx.Reply($"{Emojis.Success} Member \"{memberName}\" (`{member.Hid}`) registered! Check out the getting started page for how to get a member up and running: https://pluralkit.me/start#create-a-member");
// todo: move this to ModelRepository // todo: move this to ModelRepository

View File

@ -64,11 +64,6 @@ 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;
} }
@ -78,6 +73,8 @@ namespace PluralKit.Core
_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));
var group = await _db.QueryFirst<PKGroup>(conn, query, extraSql: "returning *"); var group = await _db.QueryFirst<PKGroup>(conn, query, extraSql: "returning *");
if (conn == null)
_ = _dispatch.Dispatch(id, new() _ = _dispatch.Dispatch(id, new()
{ {
Event = DispatchEvent.UPDATE_GROUP, Event = DispatchEvent.UPDATE_GROUP,

View File

@ -69,11 +69,6 @@ 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;
} }
@ -81,6 +76,8 @@ 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));
if (conn == null)
_ = _dispatch.Dispatch(id, new() _ = _dispatch.Dispatch(id, new()
{ {
Event = DispatchEvent.UPDATE_MEMBER, Event = DispatchEvent.UPDATE_MEMBER,

View File

@ -33,6 +33,7 @@ namespace PluralKit.Core
UPDATE_SWITCH_MEMBERS, UPDATE_SWITCH_MEMBERS,
DELETE_SWITCH, DELETE_SWITCH,
DELETE_ALL_SWITCHES, DELETE_ALL_SWITCHES,
SUCCESSFUL_IMPORT,
} }
public struct UpdateDispatchData public struct UpdateDispatchData

View File

@ -18,12 +18,14 @@ namespace PluralKit.Core
private readonly IDatabase _db; private readonly IDatabase _db;
private readonly ModelRepository _repo; private readonly ModelRepository _repo;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly DispatchService _dispatch;
public DataFileService(IDatabase db, ModelRepository repo, ILogger logger) public DataFileService(IDatabase db, ModelRepository repo, ILogger logger, DispatchService dispatch)
{ {
_db = db; _db = db;
_repo = repo; _repo = repo;
_logger = logger; _logger = logger;
_dispatch = dispatch;
} }
public async Task<JObject> ExportSystem(PKSystem system) public async Task<JObject> ExportSystem(PKSystem system)
@ -72,7 +74,7 @@ namespace PluralKit.Core
await using var conn = await _db.Obtain(); await using var conn = await _db.Obtain();
await using var tx = await conn.BeginTransactionAsync(); await using var tx = await conn.BeginTransactionAsync();
return await BulkImporter.PerformImport(conn, tx, _repo, _logger, userId, system, importFile, confirmFunc); return await BulkImporter.PerformImport(conn, tx, _repo, _logger, _dispatch, userId, system, importFile, confirmFunc);
} }
} }

View File

@ -34,7 +34,7 @@ namespace PluralKit.Core
private ImportResultNew _result = new(); private ImportResultNew _result = new();
internal static async Task<ImportResultNew> PerformImport(IPKConnection conn, IPKTransaction tx, ModelRepository repo, ILogger logger, internal static async Task<ImportResultNew> PerformImport(IPKConnection conn, IPKTransaction tx, ModelRepository repo, ILogger logger,
ulong userId, PKSystem? system, JObject importFile, Func<string, Task> confirmFunc) DispatchService dispatch, ulong userId, PKSystem? system, JObject importFile, Func<string, Task> confirmFunc)
{ {
await using var importer = new BulkImporter() await using var importer = new BulkImporter()
{ {
@ -82,6 +82,11 @@ namespace PluralKit.Core
throw new ImportException("File type is unknown."); throw new ImportException("File type is unknown.");
importer._result.Success = true; importer._result.Success = true;
await tx.CommitAsync(); await tx.CommitAsync();
_ = dispatch.Dispatch(system.Id, new UpdateDispatchData()
{
Event = DispatchEvent.SUCCESSFUL_IMPORT
});
} }
catch (ImportException e) catch (ImportException e)
{ {

View File

@ -55,3 +55,4 @@ PluralKit will send invalid requests to your endpoint, with `PING` event type, o
|UPDATE_SWITCH_MEMBERS|the member list of a switch was updated|list of member IDs| |UPDATE_SWITCH_MEMBERS|the member list of a switch was updated|list of member IDs|
|DELETE_SWITCH|a switch was deleted|null|old switch ID can be found in top-level `id` key| |DELETE_SWITCH|a switch was deleted|null|old switch ID can be found in top-level `id` key|
|DELETE_ALL_SWITCHES|your system's switches were bulk deleted|null| |DELETE_ALL_SWITCHES|your system's switches were bulk deleted|null|
|SUCCESSFUL_IMPORT|some information was successfully imported through the `pk;import` command to your system|null|