api: Add event logging via webhook.

This commit is contained in:
2025-06-13 23:47:51 +10:00
parent 2bf95beaae
commit 092e818990
5 changed files with 254 additions and 7 deletions

View File

@@ -11,14 +11,16 @@ import logging
from datetime import datetime
from typing import Any, Literal, NamedTuple, Optional, Self, TypedDict, Unpack, overload, reveal_type, List
from aiohttp import web
import discord
from data import Condition, condition
from data.conditions import NULL
from data.queries import JOINTYPE
from datamodels import DataModel
from modules.profiles.data import ProfileData
from utils.lib import MessageArgs, tabulate
from .lib import ModelField, datamodelsv, dbvar, profiledatav
from .lib import ModelField, datamodelsv, dbvar, event_log, profiledatav
from .specimens import Specimen, SpecimenPayload
routes = web.RouteTableDef()
@@ -141,6 +143,7 @@ class User:
raise web.HTTPBadRequest(text="Invalid 'twitch_id' passed to user creation!")
# First check if the profile already exists by querying the Dreamer database
edited = 0 # 0 means not edited, 1 means created, 2 means modified
rows = await data.Dreamer.fetch_where(twitch_id=twitch_id)
if rows:
logger.debug(f"Updating Dreamer for {twitch_id=} with {kwargs}")
@@ -150,6 +153,7 @@ class User:
if dreamer.preferences is None and dreamer.name is None:
await data.UserPreferences.fetch_or_create(dreamer.user_id, twitch_name=name, preferences=prefs)
dreamer = await dreamer.refresh()
edited = 2
# Now compare the existing data against the provided data and update if needed
if name != dreamer.name:
@@ -159,6 +163,7 @@ class User:
q.set(preferences=prefs)
await q
dreamer = await dreamer.refresh()
edited = 2
else:
# Create from scratch
logger.info(f"Creating Dreamer for {twitch_id=} with {kwargs}")
@@ -176,8 +181,16 @@ class User:
)
dreamer = await data.Dreamer.fetch(user_profile.profileid)
assert dreamer is not None
edited = 1
return cls(app, dreamer)
self = cls(app, dreamer)
if edited == 1:
args = await self.event_log_args(title=f"User #{dreamer.user_id} created!")
await event_log(**args.send_args)
elif edited == 2:
args = await self.event_log_args(title=f"User #{dreamer.user_id} updated!")
await event_log(**args.send_args)
return self
async def edit(self, **kwargs: Unpack[UserEditParams]):
data = self.data
@@ -193,6 +206,9 @@ class User:
logger.info(f"Updating dreamer {self.row=} with {kwargs}")
await prefs.update(**update_args)
args = await self.event_log_args(title=f"User #{self.row.user_id} updated!")
await event_log(**args.send_args)
async def delete(self) -> UserDetailsPayload:
payload = await self.prepare(details=True)
# This will cascade to all other data the user has
@@ -225,6 +241,28 @@ class User:
async def get_inventory(self):
return []
async def event_log_args(self, **kwargs) -> MessageArgs:
desc = '\n'.join(await self.tabulate())
embed = discord.Embed(description=desc, timestamp=self.row.created_at, **kwargs)
embed.set_footer(text='Created At')
# TODO: We could add wallet, specimen, and inventory info here too
return MessageArgs(embed=embed)
async def tabulate(self):
"""
Present the User as a discord-readable table.
"""
table = {
'user_id': f"`{self.row.user_id}`",
'twitch_id': f"`{self.row.twitch_id}`" if self.row.twitch_id else 'No Twitch linked',
'name': f"`{self.row.name}`",
'preferences': f"`{self.row.preferences}`",
'created_at': discord.utils.format_dt(self.row.created_at, 'F'),
}
return tabulate(*table.items())
@overload
async def prepare(self, details: Literal[True]=True) -> UserDetailsPayload:
...