Include system data on PK profiles
This commit is contained in:
parent
6a06dc14ce
commit
a71c9515ec
4 changed files with 49 additions and 25 deletions
|
@ -24,7 +24,7 @@ async function editMessage(message, guild, row) {
|
|||
if (row.speedbump_id === "466378653216014359") {
|
||||
const root = await registerPkUser.fetchMessage(message.id)
|
||||
assert(root.member)
|
||||
senderMxid = await registerPkUser.ensureSimJoined(root.member, roomID)
|
||||
senderMxid = await registerPkUser.ensureSimJoined(root, roomID)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,17 +16,17 @@ const registerUser = sync.require("./register-user")
|
|||
|
||||
/**
|
||||
* A sim is an account that is being simulated by the bridge to copy events from the other side.
|
||||
* @param {Ty.PkMember} member
|
||||
* @param {Ty.PkMessage} pkMessage
|
||||
* @returns mxid
|
||||
*/
|
||||
async function createSim(member) {
|
||||
async function createSim(pkMessage) {
|
||||
// Choose sim name
|
||||
const simName = "_pk_" + member.id
|
||||
const simName = "_pk_" + pkMessage.member.id
|
||||
const localpart = reg.ooye.namespace_prefix + simName
|
||||
const mxid = `@${localpart}:${reg.ooye.server_name}`
|
||||
|
||||
// Save chosen name in the database forever
|
||||
db.prepare("INSERT INTO sim (user_id, sim_name, localpart, mxid) VALUES (?, ?, ?, ?)").run(member.uuid, simName, localpart, mxid)
|
||||
db.prepare("INSERT INTO sim (user_id, sim_name, localpart, mxid) VALUES (?, ?, ?, ?)").run(pkMessage.member.uuid, simName, localpart, mxid)
|
||||
|
||||
// Register matrix user with that name
|
||||
try {
|
||||
|
@ -34,7 +34,7 @@ async function createSim(member) {
|
|||
} catch (e) {
|
||||
// If user creation fails, manually undo the database change. Still isn't perfect, but should help.
|
||||
// (I would prefer a transaction, but it's not safe to leave transactions open across event loop ticks.)
|
||||
db.prepare("DELETE FROM sim WHERE user_id = ?").run(member.uuid)
|
||||
db.prepare("DELETE FROM sim WHERE user_id = ?").run(pkMessage.member.uuid)
|
||||
throw e
|
||||
}
|
||||
return mxid
|
||||
|
@ -43,32 +43,32 @@ async function createSim(member) {
|
|||
/**
|
||||
* Ensure a sim is registered for the user.
|
||||
* If there is already a sim, use that one. If there isn't one yet, register a new sim.
|
||||
* @param {Ty.PkMember} member
|
||||
* @param {Ty.PkMessage} pkMessage
|
||||
* @returns {Promise<string>} mxid
|
||||
*/
|
||||
async function ensureSim(member) {
|
||||
async function ensureSim(pkMessage) {
|
||||
let mxid = null
|
||||
const existing = select("sim", "mxid", {user_id: member.uuid}).pluck().get()
|
||||
const existing = select("sim", "mxid", {user_id: pkMessage.member.uuid}).pluck().get()
|
||||
if (existing) {
|
||||
mxid = existing
|
||||
} else {
|
||||
mxid = await createSim(member)
|
||||
mxid = await createSim(pkMessage)
|
||||
}
|
||||
return mxid
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a sim is registered for the user and is joined to the room.
|
||||
* @param {Ty.PkMember} member
|
||||
* @param {Ty.PkMessage} pkMessage
|
||||
* @param {string} roomID
|
||||
* @returns {Promise<string>} mxid
|
||||
*/
|
||||
async function ensureSimJoined(member, roomID) {
|
||||
async function ensureSimJoined(pkMessage, roomID) {
|
||||
// Ensure room ID is really an ID, not an alias
|
||||
assert.ok(roomID[0] === "!")
|
||||
|
||||
// Ensure user
|
||||
const mxid = await ensureSim(member)
|
||||
const mxid = await ensureSim(pkMessage)
|
||||
|
||||
// Ensure joined
|
||||
const existing = select("sim_member", "mxid", {room_id: roomID, mxid}).pluck().get()
|
||||
|
@ -89,16 +89,17 @@ async function ensureSimJoined(member, roomID) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Ty.PkMember} member
|
||||
* @param {Ty.PkMessage} pkMessage
|
||||
*/
|
||||
async function memberToStateContent(member) {
|
||||
const displayname = member.display_name || member.name
|
||||
const avatar = member.avatar_url || member.webhook_avatar_url
|
||||
async function memberToStateContent(pkMessage) {
|
||||
const systemname = pkMessage.system.tag || ""
|
||||
const displayname = (pkMessage.member.display_name || pkMessage.member.name) + systemname
|
||||
const avatar = pkMessage.member.avatar_url || pkMessage.member.webhook_avatar_url || pkMessage.system.avatar_url
|
||||
|
||||
const content = {
|
||||
displayname,
|
||||
membership: "join",
|
||||
"moe.cadence.ooye.pk_member": member
|
||||
"moe.cadence.ooye.pk_member": pkMessage.member
|
||||
}
|
||||
if (avatar) content.avatar_url = await file.uploadDiscordFileToMxc(avatar)
|
||||
|
||||
|
@ -111,12 +112,12 @@ async function memberToStateContent(member) {
|
|||
* 2. Make an object of what the new room member state content would be, including uploading the profile picture if it hasn't been done before
|
||||
* 3. Compare against the previously known state content, which is helpfully stored in the database
|
||||
* 4. If the state content has changed, send it to Matrix and update it in the database for next time
|
||||
* @param {Ty.PkMember} member
|
||||
* @param {Ty.PkMessage} pkMessage
|
||||
* @returns {Promise<string>} mxid of the updated sim
|
||||
*/
|
||||
async function syncUser(member, roomID) {
|
||||
const mxid = await ensureSimJoined(member, roomID)
|
||||
const content = await memberToStateContent(member)
|
||||
async function syncUser(pkMessage, roomID) {
|
||||
const mxid = await ensureSimJoined(pkMessage, roomID)
|
||||
const content = await memberToStateContent(pkMessage)
|
||||
const currentHash = registerUser._hashProfileContent(content)
|
||||
const existingHash = select("sim_member", "hashed_profile_content", {room_id: roomID, mxid}).safeIntegers().pluck().get()
|
||||
// only do the actual sync if the hash has changed since we last looked
|
||||
|
@ -127,7 +128,7 @@ async function syncUser(member, roomID) {
|
|||
return mxid
|
||||
}
|
||||
|
||||
/** @returns {Promise<{member?: Ty.PkMember}>} */
|
||||
/** @returns {Promise<Ty.PkMessage>} */
|
||||
function fetchMessage(messageID) {
|
||||
return fetch(`https://api.pluralkit.me/v2/messages/${messageID}`).then(res => res.json())
|
||||
}
|
||||
|
|
|
@ -36,8 +36,13 @@ async function sendMessage(message, guild, row) {
|
|||
// Handle the PluralKit public instance
|
||||
if (row.speedbump_id === "466378653216014359") {
|
||||
const root = await registerPkUser.fetchMessage(message.id)
|
||||
assert(root.member) // Member is null if member was deleted. We just got this message, so member surely exists.
|
||||
senderMxid = await registerPkUser.syncUser(root.member, roomID)
|
||||
// Member is null if member was deleted. We just got this message, so member surely exists.
|
||||
if (!root.member) {
|
||||
const e = new Error("PK API did not return a member")
|
||||
e["response"] = root
|
||||
throw e
|
||||
}
|
||||
senderMxid = await registerPkUser.syncUser(root, roomID)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
types.d.ts
vendored
18
types.d.ts
vendored
|
@ -34,6 +34,19 @@ export type WebhookCreds = {
|
|||
token: string
|
||||
}
|
||||
|
||||
export type PkSystem = {
|
||||
id: string
|
||||
uuid: string
|
||||
name: string | null
|
||||
description: string | null
|
||||
tag: string | null
|
||||
pronouns: string | null
|
||||
avatar_url: string | null
|
||||
banner: string | null
|
||||
color: string | null
|
||||
created: string | null
|
||||
}
|
||||
|
||||
export type PkMember = {
|
||||
id: string
|
||||
uuid: string
|
||||
|
@ -54,6 +67,11 @@ export type PkMember = {
|
|||
last_message_timestamp: string
|
||||
}
|
||||
|
||||
export type PkMessage = {
|
||||
system: PkSystem
|
||||
member: PkMember
|
||||
}
|
||||
|
||||
export namespace Event {
|
||||
export type Outer<T> = {
|
||||
type: string
|
||||
|
|
Loading…
Reference in a new issue