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") {
|
if (row.speedbump_id === "466378653216014359") {
|
||||||
const root = await registerPkUser.fetchMessage(message.id)
|
const root = await registerPkUser.fetchMessage(message.id)
|
||||||
assert(root.member)
|
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.
|
* 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
|
* @returns mxid
|
||||||
*/
|
*/
|
||||||
async function createSim(member) {
|
async function createSim(pkMessage) {
|
||||||
// Choose sim name
|
// Choose sim name
|
||||||
const simName = "_pk_" + member.id
|
const simName = "_pk_" + pkMessage.member.id
|
||||||
const localpart = reg.ooye.namespace_prefix + simName
|
const localpart = reg.ooye.namespace_prefix + simName
|
||||||
const mxid = `@${localpart}:${reg.ooye.server_name}`
|
const mxid = `@${localpart}:${reg.ooye.server_name}`
|
||||||
|
|
||||||
// Save chosen name in the database forever
|
// 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
|
// Register matrix user with that name
|
||||||
try {
|
try {
|
||||||
|
@ -34,7 +34,7 @@ async function createSim(member) {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If user creation fails, manually undo the database change. Still isn't perfect, but should help.
|
// 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.)
|
// (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
|
throw e
|
||||||
}
|
}
|
||||||
return mxid
|
return mxid
|
||||||
|
@ -43,32 +43,32 @@ async function createSim(member) {
|
||||||
/**
|
/**
|
||||||
* Ensure a sim is registered for the user.
|
* 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.
|
* 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
|
* @returns {Promise<string>} mxid
|
||||||
*/
|
*/
|
||||||
async function ensureSim(member) {
|
async function ensureSim(pkMessage) {
|
||||||
let mxid = null
|
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) {
|
if (existing) {
|
||||||
mxid = existing
|
mxid = existing
|
||||||
} else {
|
} else {
|
||||||
mxid = await createSim(member)
|
mxid = await createSim(pkMessage)
|
||||||
}
|
}
|
||||||
return mxid
|
return mxid
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure a sim is registered for the user and is joined to the room.
|
* 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
|
* @param {string} roomID
|
||||||
* @returns {Promise<string>} mxid
|
* @returns {Promise<string>} mxid
|
||||||
*/
|
*/
|
||||||
async function ensureSimJoined(member, roomID) {
|
async function ensureSimJoined(pkMessage, roomID) {
|
||||||
// Ensure room ID is really an ID, not an alias
|
// Ensure room ID is really an ID, not an alias
|
||||||
assert.ok(roomID[0] === "!")
|
assert.ok(roomID[0] === "!")
|
||||||
|
|
||||||
// Ensure user
|
// Ensure user
|
||||||
const mxid = await ensureSim(member)
|
const mxid = await ensureSim(pkMessage)
|
||||||
|
|
||||||
// Ensure joined
|
// Ensure joined
|
||||||
const existing = select("sim_member", "mxid", {room_id: roomID, mxid}).pluck().get()
|
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) {
|
async function memberToStateContent(pkMessage) {
|
||||||
const displayname = member.display_name || member.name
|
const systemname = pkMessage.system.tag || ""
|
||||||
const avatar = member.avatar_url || member.webhook_avatar_url
|
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 = {
|
const content = {
|
||||||
displayname,
|
displayname,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
"moe.cadence.ooye.pk_member": member
|
"moe.cadence.ooye.pk_member": pkMessage.member
|
||||||
}
|
}
|
||||||
if (avatar) content.avatar_url = await file.uploadDiscordFileToMxc(avatar)
|
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
|
* 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
|
* 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
|
* 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
|
* @returns {Promise<string>} mxid of the updated sim
|
||||||
*/
|
*/
|
||||||
async function syncUser(member, roomID) {
|
async function syncUser(pkMessage, roomID) {
|
||||||
const mxid = await ensureSimJoined(member, roomID)
|
const mxid = await ensureSimJoined(pkMessage, roomID)
|
||||||
const content = await memberToStateContent(member)
|
const content = await memberToStateContent(pkMessage)
|
||||||
const currentHash = registerUser._hashProfileContent(content)
|
const currentHash = registerUser._hashProfileContent(content)
|
||||||
const existingHash = select("sim_member", "hashed_profile_content", {room_id: roomID, mxid}).safeIntegers().pluck().get()
|
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
|
// 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
|
return mxid
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {Promise<{member?: Ty.PkMember}>} */
|
/** @returns {Promise<Ty.PkMessage>} */
|
||||||
function fetchMessage(messageID) {
|
function fetchMessage(messageID) {
|
||||||
return fetch(`https://api.pluralkit.me/v2/messages/${messageID}`).then(res => res.json())
|
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
|
// Handle the PluralKit public instance
|
||||||
if (row.speedbump_id === "466378653216014359") {
|
if (row.speedbump_id === "466378653216014359") {
|
||||||
const root = await registerPkUser.fetchMessage(message.id)
|
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.
|
// Member is null if member was deleted. We just got this message, so member surely exists.
|
||||||
senderMxid = await registerPkUser.syncUser(root.member, roomID)
|
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
|
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 = {
|
export type PkMember = {
|
||||||
id: string
|
id: string
|
||||||
uuid: string
|
uuid: string
|
||||||
|
@ -54,6 +67,11 @@ export type PkMember = {
|
||||||
last_message_timestamp: string
|
last_message_timestamp: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type PkMessage = {
|
||||||
|
system: PkSystem
|
||||||
|
member: PkMember
|
||||||
|
}
|
||||||
|
|
||||||
export namespace Event {
|
export namespace Event {
|
||||||
export type Outer<T> = {
|
export type Outer<T> = {
|
||||||
type: string
|
type: string
|
||||||
|
|
Loading…
Reference in a new issue