getting edits closer to working
This commit is contained in:
		
							parent
							
								
									cae591e5fd
								
							
						
					
					
						commit
						b1ca71f37c
					
				
					 10 changed files with 259 additions and 51 deletions
				
			
		
							
								
								
									
										2
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -59,6 +59,7 @@ async function ensureSim(user) {
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 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 {import("discord-api-types/v10").APIUser} user
 | 
					 * @param {import("discord-api-types/v10").APIUser} user
 | 
				
			||||||
 | 
					 * @param {string} roomID
 | 
				
			||||||
 * @returns mxid
 | 
					 * @returns mxid
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function ensureSimJoined(user, roomID) {
 | 
					async function ensureSimJoined(user, roomID) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ const messageToEvent = sync.require("../converters/message-to-event")
 | 
				
			||||||
/** @type {import("../../matrix/api")} */
 | 
					/** @type {import("../../matrix/api")} */
 | 
				
			||||||
const api = sync.require("../../matrix/api")
 | 
					const api = sync.require("../../matrix/api")
 | 
				
			||||||
/** @type {import("../actions/register-user")} */
 | 
					/** @type {import("../actions/register-user")} */
 | 
				
			||||||
const registerUser = sync.require("./register-user")
 | 
					const registerUser = sync.require("../actions/register-user")
 | 
				
			||||||
/** @type {import("../actions/create-room")} */
 | 
					/** @type {import("../actions/create-room")} */
 | 
				
			||||||
const createRoom = sync.require("../actions/create-room")
 | 
					const createRoom = sync.require("../actions/create-room")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ const createRoom = sync.require("../actions/create-room")
 | 
				
			||||||
async function editToChanges(message, guild) {
 | 
					async function editToChanges(message, guild) {
 | 
				
			||||||
	// Figure out what events we will be replacing
 | 
						// Figure out what events we will be replacing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").get(message.channel_id)
 | 
						const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(message.channel_id)
 | 
				
			||||||
	const senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
 | 
						const senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
 | 
				
			||||||
	/** @type {{event_id: string, event_type: string, event_subtype: string?, part: number}[]} */
 | 
						/** @type {{event_id: string, event_type: string, event_subtype: string?, part: number}[]} */
 | 
				
			||||||
   const oldEventRows = db.prepare("SELECT event_id, event_type, event_subtype, part FROM event_message WHERE message_id = ?").all(message.id)
 | 
					   const oldEventRows = db.prepare("SELECT event_id, event_type, event_subtype, part FROM event_message WHERE message_id = ?").all(message.id)
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@ async function editToChanges(message, guild) {
 | 
				
			||||||
		Rules:
 | 
							Rules:
 | 
				
			||||||
			+ The events must have the same type.
 | 
								+ The events must have the same type.
 | 
				
			||||||
			+ The events must have the same subtype.
 | 
								+ The events must have the same subtype.
 | 
				
			||||||
		Events will therefore be divided into three categories:
 | 
							Events will therefore be divided into four categories:
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	/** 1. Events that are matched, and should be edited by sending another m.replace event */
 | 
						/** 1. Events that are matched, and should be edited by sending another m.replace event */
 | 
				
			||||||
	let eventsToReplace = []
 | 
						let eventsToReplace = []
 | 
				
			||||||
| 
						 | 
					@ -45,12 +45,12 @@ async function editToChanges(message, guild) {
 | 
				
			||||||
	let eventsToRedact = []
 | 
						let eventsToRedact = []
 | 
				
			||||||
	/** 3. Events that are present in the new version only, and should be sent as new, with references back to the context */
 | 
						/** 3. Events that are present in the new version only, and should be sent as new, with references back to the context */
 | 
				
			||||||
	let eventsToSend = []
 | 
						let eventsToSend = []
 | 
				
			||||||
 | 
						//  4. Events that are matched and have definitely not changed, so they don't need to be edited or replaced at all. This is represented as nothing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// For each old event...
 | 
						// For each old event...
 | 
				
			||||||
	outer: while (newEvents.length) {
 | 
						outer: while (newEvents.length) {
 | 
				
			||||||
		const newe = newEvents[0]
 | 
							const newe = newEvents[0]
 | 
				
			||||||
		// Find a new event to pair it with...
 | 
							// Find a new event to pair it with...
 | 
				
			||||||
		let handled = false
 | 
					 | 
				
			||||||
		for (let i = 0; i < oldEventRows.length; i++) {
 | 
							for (let i = 0; i < oldEventRows.length; i++) {
 | 
				
			||||||
			const olde = oldEventRows[i]
 | 
								const olde = oldEventRows[i]
 | 
				
			||||||
			if (olde.event_type === newe.$type && olde.event_subtype === (newe.msgtype || null)) {
 | 
								if (olde.event_type === newe.$type && olde.event_subtype === (newe.msgtype || null)) {
 | 
				
			||||||
| 
						 | 
					@ -76,7 +76,7 @@ async function editToChanges(message, guild) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Now, everything in eventsToSend and eventsToRedact is a real change, but everything in eventsToReplace might not have actually changed!
 | 
						// Now, everything in eventsToSend and eventsToRedact is a real change, but everything in eventsToReplace might not have actually changed!
 | 
				
			||||||
	// (Consider a MESSAGE_UPDATE for a text+image message - Discord does not allow the image to be changed, but the text might have been.)
 | 
						// (Consider a MESSAGE_UPDATE for a text+image message - Discord does not allow the image to be changed, but the text might have been.)
 | 
				
			||||||
	// So we'll remove entries from eventsToReplace that *definitely* cannot have changed. Everything remaining *may* have changed.
 | 
						// So we'll remove entries from eventsToReplace that *definitely* cannot have changed. (This is category 4 mentioned above.) Everything remaining *may* have changed.
 | 
				
			||||||
	eventsToReplace = eventsToReplace.filter(ev => {
 | 
						eventsToReplace = eventsToReplace.filter(ev => {
 | 
				
			||||||
		// Discord does not allow files, images, attachments, or videos to be edited.
 | 
							// Discord does not allow files, images, attachments, or videos to be edited.
 | 
				
			||||||
		if (ev.old.event_type === "m.room.message" && ev.old.event_subtype !== "m.text" && ev.old.event_subtype !== "m.emote") {
 | 
							if (ev.old.event_type === "m.room.message" && ev.old.event_subtype !== "m.text" && ev.old.event_subtype !== "m.emote") {
 | 
				
			||||||
| 
						 | 
					@ -90,7 +90,42 @@ async function editToChanges(message, guild) {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Removing unnecessary properties before returning
 | 
				
			||||||
 | 
						eventsToRedact = eventsToRedact.map(e => e.event_id)
 | 
				
			||||||
 | 
						eventsToReplace = eventsToReplace.map(e => ({oldID: e.old.event_id, new: eventToReplacementEvent(e.old.event_id, e.new)}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return {eventsToReplace, eventsToRedact, eventsToSend}
 | 
						return {eventsToReplace, eventsToRedact, eventsToSend}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports.editMessage = editMessage
 | 
					/**
 | 
				
			||||||
 | 
					 * @template T
 | 
				
			||||||
 | 
					 * @param {string} oldID
 | 
				
			||||||
 | 
					 * @param {T} content
 | 
				
			||||||
 | 
					 * @returns {import("../../types").Event.ReplacementContent<T>} content
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function eventToReplacementEvent(oldID, content) {
 | 
				
			||||||
 | 
						const newContent = {
 | 
				
			||||||
 | 
							...content,
 | 
				
			||||||
 | 
							"m.mentions": {},
 | 
				
			||||||
 | 
							"m.new_content": {
 | 
				
			||||||
 | 
								...content
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"m.relates_to": {
 | 
				
			||||||
 | 
								rel_type: "m.replace",
 | 
				
			||||||
 | 
								event_id: oldID
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (typeof newContent.body === "string") {
 | 
				
			||||||
 | 
							newContent.body = "* " + newContent.body
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (typeof newContent.formatted_body === "string") {
 | 
				
			||||||
 | 
							newContent.formatted_body = "* " + newContent.formatted_body
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						delete newContent["m.new_content"]["$type"]
 | 
				
			||||||
 | 
						// Client-Server API spec 11.37.3: Any m.relates_to property within m.new_content is ignored.
 | 
				
			||||||
 | 
						delete newContent["m.new_content"]["m.relates_to"]
 | 
				
			||||||
 | 
						return newContent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.editToChanges = editToChanges
 | 
				
			||||||
 | 
					module.exports.eventToReplacementEvent = eventToReplacementEvent
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										66
									
								
								d2m/converters/edit-to-changes.test.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								d2m/converters/edit-to-changes.test.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,66 @@
 | 
				
			||||||
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const {test} = require("supertape")
 | 
				
			||||||
 | 
					const {editToChanges} = require("./edit-to-changes")
 | 
				
			||||||
 | 
					const data = require("../../test/data")
 | 
				
			||||||
 | 
					const Ty = require("../../types")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("edit2changes: bot response", async t => {
 | 
				
			||||||
 | 
					   const {eventsToRedact, eventsToReplace, eventsToSend} = await editToChanges(data.message_update.bot_response, data.guild.general)
 | 
				
			||||||
 | 
					   t.deepEqual(eventsToRedact, [])
 | 
				
			||||||
 | 
					   t.deepEqual(eventsToSend, [])
 | 
				
			||||||
 | 
					   t.deepEqual(eventsToReplace, [{
 | 
				
			||||||
 | 
					      oldID: "$fdD9OZ55xg3EAsfvLZza5tMhtjUO91Wg3Otuo96TplY",
 | 
				
			||||||
 | 
					      new: {
 | 
				
			||||||
 | 
					         $type: "m.room.message",
 | 
				
			||||||
 | 
					         msgtype: "m.text",
 | 
				
			||||||
 | 
					         body: "* :ae_botrac4r: @cadence asked ````, I respond: Stop drinking paint. (No)\n\nHit :bn_re: to reroll.",
 | 
				
			||||||
 | 
					         format: "org.matrix.custom.html",
 | 
				
			||||||
 | 
					         formatted_body: '* <img src="mxc://cadence.moe/551636841284108289" data-mx-emoticon alt=":ae_botrac4r:" title=":ae_botrac4r:" height="24"> @cadence asked <code></code>, I respond: Stop drinking paint. (No)<br><br>Hit <img src="mxc://cadence.moe/362741439211503616" data-mx-emoticon alt=":bn_re:" title=":bn_re:" height="24"> to reroll.',
 | 
				
			||||||
 | 
					         "m.mentions": {
 | 
				
			||||||
 | 
					            // Client-Server API spec 11.37.7: Copy Discord's behaviour by not re-notifying anyone that an *edit occurred*
 | 
				
			||||||
 | 
					         },
 | 
				
			||||||
 | 
					         // *** Replaced With: ***
 | 
				
			||||||
 | 
					         "m.new_content": {
 | 
				
			||||||
 | 
					            msgtype: "m.text",
 | 
				
			||||||
 | 
					            body: ":ae_botrac4r: @cadence asked ````, I respond: Stop drinking paint. (No)\n\nHit :bn_re: to reroll.",
 | 
				
			||||||
 | 
					            format: "org.matrix.custom.html",
 | 
				
			||||||
 | 
					            formatted_body: '<img src="mxc://cadence.moe/551636841284108289" data-mx-emoticon alt=":ae_botrac4r:" title=":ae_botrac4r:" height="24"> @cadence asked <code></code>, I respond: Stop drinking paint. (No)<br><br>Hit <img src="mxc://cadence.moe/362741439211503616" data-mx-emoticon alt=":bn_re:" title=":bn_re:" height="24"> to reroll.',
 | 
				
			||||||
 | 
					            "m.mentions": {
 | 
				
			||||||
 | 
					               // Client-Server API spec 11.37.7: This should contain the mentions for the final version of the event
 | 
				
			||||||
 | 
					               "user_ids": ["@cadence:cadence.moe"]
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					         },
 | 
				
			||||||
 | 
					         "m.relates_to": {
 | 
				
			||||||
 | 
					            rel_type: "m.replace",
 | 
				
			||||||
 | 
					            event_id: "$fdD9OZ55xg3EAsfvLZza5tMhtjUO91Wg3Otuo96TplY"
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					   }])
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("edit2changes: edit of reply to skull webp attachment with content", async t => {
 | 
				
			||||||
 | 
					   const {eventsToRedact, eventsToReplace, eventsToSend} = await editToChanges(data.message_update.edit_of_reply_to_skull_webp_attachment_with_content, data.guild.general)
 | 
				
			||||||
 | 
						t.deepEqual(eventsToRedact, [])
 | 
				
			||||||
 | 
					   t.deepEqual(eventsToSend, [])
 | 
				
			||||||
 | 
					   t.deepEqual(eventsToReplace, [{
 | 
				
			||||||
 | 
					      oldID: "$vgTKOR5ZTYNMKaS7XvgEIDaOWZtVCEyzLLi5Pc5Gz4M",
 | 
				
			||||||
 | 
					      new: {
 | 
				
			||||||
 | 
					         $type: "m.room.message",
 | 
				
			||||||
 | 
					         // TODO: read "edits of replies" in the spec!!!
 | 
				
			||||||
 | 
					         msgtype: "m.text",
 | 
				
			||||||
 | 
					         body: "* Edit",
 | 
				
			||||||
 | 
					         "m.mentions": {},
 | 
				
			||||||
 | 
					         "m.new_content": {
 | 
				
			||||||
 | 
					            msgtype: "m.text",
 | 
				
			||||||
 | 
					            body: "Edit",
 | 
				
			||||||
 | 
					            "m.mentions": {}
 | 
				
			||||||
 | 
					         },
 | 
				
			||||||
 | 
					         "m.relates_to": {
 | 
				
			||||||
 | 
					            rel_type: "m.replace",
 | 
				
			||||||
 | 
					            event_id: "$vgTKOR5ZTYNMKaS7XvgEIDaOWZtVCEyzLLi5Pc5Gz4M"
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					         // TODO: read "edits of replies" in the spec!!!
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					   }])
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getDiscordParseCallbacks(message, useHTML) {
 | 
					function getDiscordParseCallbacks(message, useHTML) {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
 | 
							/** @param {{id: string, type: "discordUser"}} node */
 | 
				
			||||||
		user: node => {
 | 
							user: node => {
 | 
				
			||||||
			const mxid = db.prepare("SELECT mxid FROM sim WHERE discord_id = ?").pluck().get(node.id)
 | 
								const mxid = db.prepare("SELECT mxid FROM sim WHERE discord_id = ?").pluck().get(node.id)
 | 
				
			||||||
			const username = message.mentions.find(ment => ment.id === node.id)?.username || node.id
 | 
								const username = message.mentions.find(ment => ment.id === node.id)?.username || node.id
 | 
				
			||||||
| 
						 | 
					@ -24,6 +25,7 @@ function getDiscordParseCallbacks(message, useHTML) {
 | 
				
			||||||
				return `@${username}:`
 | 
									return `@${username}:`
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							/** @param {{id: string, type: "discordChannel"}} node */
 | 
				
			||||||
		channel: node => {
 | 
							channel: node => {
 | 
				
			||||||
			const {room_id, name, nick} = db.prepare("SELECT room_id, name, nick FROM channel_room WHERE channel_id = ?").get(node.id)
 | 
								const {room_id, name, nick} = db.prepare("SELECT room_id, name, nick FROM channel_room WHERE channel_id = ?").get(node.id)
 | 
				
			||||||
			if (room_id && useHTML) {
 | 
								if (room_id && useHTML) {
 | 
				
			||||||
| 
						 | 
					@ -32,6 +34,15 @@ function getDiscordParseCallbacks(message, useHTML) {
 | 
				
			||||||
				return `#${nick || name}`
 | 
									return `#${nick || name}`
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							/** @param {{animated: boolean, name: string, id: string, type: "discordEmoji"}} node */
 | 
				
			||||||
 | 
							emoji: node => {
 | 
				
			||||||
 | 
								if (useHTML) {
 | 
				
			||||||
 | 
									// TODO: upload the emoji and actually use the right mxc!!
 | 
				
			||||||
 | 
									return `<img src="mxc://cadence.moe/${node.id}" data-mx-emoticon alt=":${node.name}:" title=":${node.name}:" height="24">`
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return `:${node.name}:`
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		role: node =>
 | 
							role: node =>
 | 
				
			||||||
			"@&" + node.id,
 | 
								"@&" + node.id,
 | 
				
			||||||
		everyone: node =>
 | 
							everyone: node =>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -27,6 +27,7 @@
 | 
				
			||||||
        "@types/node-fetch": "^2.6.3",
 | 
					        "@types/node-fetch": "^2.6.3",
 | 
				
			||||||
        "c8": "^8.0.1",
 | 
					        "c8": "^8.0.1",
 | 
				
			||||||
        "cross-env": "^7.0.3",
 | 
					        "cross-env": "^7.0.3",
 | 
				
			||||||
 | 
					        "discord-api-types": "^0.37.53",
 | 
				
			||||||
        "supertape": "^8.3.0",
 | 
					        "supertape": "^8.3.0",
 | 
				
			||||||
        "tap-dot": "github:cloudrac3r/tap-dot#223a4e67a6f7daf015506a12a7af74605f06c7f4"
 | 
					        "tap-dot": "github:cloudrac3r/tap-dot#223a4e67a6f7daf015506a12a7af74605f06c7f4"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -1044,9 +1045,9 @@
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/discord-api-types": {
 | 
					    "node_modules/discord-api-types": {
 | 
				
			||||||
      "version": "0.37.47",
 | 
					      "version": "0.37.53",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.47.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.53.tgz",
 | 
				
			||||||
      "integrity": "sha512-rNif8IAv6duS2z47BMXq/V9kkrLfkAoiwpFY3sLxxbyKprk065zqf3HLTg4bEoxRSmi+Lhc7yqGDrG8C3j8GFA=="
 | 
					      "integrity": "sha512-N6uUgv50OyP981Mfxrrt0uxcqiaNr0BDaQIoqfk+3zM2JpZtwU9v7ce1uaFAP53b2xSDvcbrk80Kneui6XJgGg=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/discord-markdown": {
 | 
					    "node_modules/discord-markdown": {
 | 
				
			||||||
      "version": "2.4.1",
 | 
					      "version": "2.4.1",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@
 | 
				
			||||||
    "@types/node-fetch": "^2.6.3",
 | 
					    "@types/node-fetch": "^2.6.3",
 | 
				
			||||||
    "c8": "^8.0.1",
 | 
					    "c8": "^8.0.1",
 | 
				
			||||||
    "cross-env": "^7.0.3",
 | 
					    "cross-env": "^7.0.3",
 | 
				
			||||||
 | 
					    "discord-api-types": "^0.37.53",
 | 
				
			||||||
    "supertape": "^8.3.0",
 | 
					    "supertape": "^8.3.0",
 | 
				
			||||||
    "tap-dot": "github:cloudrac3r/tap-dot#223a4e67a6f7daf015506a12a7af74605f06c7f4"
 | 
					    "tap-dot": "github:cloudrac3r/tap-dot#223a4e67a6f7daf015506a12a7af74605f06c7f4"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										166
									
								
								test/data.js
									
										
									
									
									
								
							
							
						
						
									
										166
									
								
								test/data.js
									
										
									
									
									
								
							| 
						 | 
					@ -88,7 +88,8 @@ module.exports = {
 | 
				
			||||||
			rules_channel_id: null,
 | 
								rules_channel_id: null,
 | 
				
			||||||
			name: "Psychonauts 3",
 | 
								name: "Psychonauts 3",
 | 
				
			||||||
			max_stage_video_channel_users: 300,
 | 
								max_stage_video_channel_users: 300,
 | 
				
			||||||
			system_channel_flags: 0|0
 | 
								system_channel_flags: 0|0,
 | 
				
			||||||
 | 
								safety_alerts_channel_id: null
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	member: {
 | 
						member: {
 | 
				
			||||||
| 
						 | 
					@ -744,6 +745,128 @@ module.exports = {
 | 
				
			||||||
			attachments: [],
 | 
								attachments: [],
 | 
				
			||||||
			guild_id: "112760669178241024"
 | 
								guild_id: "112760669178241024"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							sticker: {
 | 
				
			||||||
 | 
								id: "1106366167788044450",
 | 
				
			||||||
 | 
								type: 0,
 | 
				
			||||||
 | 
								content: "can have attachments too",
 | 
				
			||||||
 | 
								channel_id: "122155380120748034",
 | 
				
			||||||
 | 
								author: {
 | 
				
			||||||
 | 
									id: "113340068197859328",
 | 
				
			||||||
 | 
									username: "Cookie 🍪",
 | 
				
			||||||
 | 
									global_name: null,
 | 
				
			||||||
 | 
									display_name: null,
 | 
				
			||||||
 | 
									avatar: "b48302623a12bc7c59a71328f72ccb39",
 | 
				
			||||||
 | 
									discriminator: "7766",
 | 
				
			||||||
 | 
									public_flags: 128,
 | 
				
			||||||
 | 
									avatar_decoration: null
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								attachments: [{
 | 
				
			||||||
 | 
									id: "1106366167486038016",
 | 
				
			||||||
 | 
									filename: "image.png",
 | 
				
			||||||
 | 
									size: 127373,
 | 
				
			||||||
 | 
									url: "https://cdn.discordapp.com/attachments/122155380120748034/1106366167486038016/image.png",
 | 
				
			||||||
 | 
									proxy_url: "https://media.discordapp.net/attachments/122155380120748034/1106366167486038016/image.png",
 | 
				
			||||||
 | 
									width: 333,
 | 
				
			||||||
 | 
									height: 287,
 | 
				
			||||||
 | 
									content_type: "image/png"
 | 
				
			||||||
 | 
								}],
 | 
				
			||||||
 | 
								embeds: [],
 | 
				
			||||||
 | 
								mentions: [],
 | 
				
			||||||
 | 
								mention_roles: [],
 | 
				
			||||||
 | 
								pinned: false,
 | 
				
			||||||
 | 
								mention_everyone: false,
 | 
				
			||||||
 | 
								tts: false,
 | 
				
			||||||
 | 
								timestamp: "2023-05-11T23:44:09.690000+00:00",
 | 
				
			||||||
 | 
								edited_timestamp: null,
 | 
				
			||||||
 | 
								flags: 0,
 | 
				
			||||||
 | 
								components: [],
 | 
				
			||||||
 | 
								sticker_items: [{
 | 
				
			||||||
 | 
									id: "1106323941183717586",
 | 
				
			||||||
 | 
									format_type: 1,
 | 
				
			||||||
 | 
									name: "pomu puff"
 | 
				
			||||||
 | 
								}]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						message_update: {
 | 
				
			||||||
 | 
							bot_response: {
 | 
				
			||||||
 | 
								attachments: [],
 | 
				
			||||||
 | 
								author: {
 | 
				
			||||||
 | 
									avatar: "d14f47194b6ebe4da2e18a56fc6dacfd",
 | 
				
			||||||
 | 
									avatar_decoration: null,
 | 
				
			||||||
 | 
									bot: true,
 | 
				
			||||||
 | 
									discriminator: "9703",
 | 
				
			||||||
 | 
									global_name: null,
 | 
				
			||||||
 | 
									id: "771520384671416320",
 | 
				
			||||||
 | 
									public_flags: 0,
 | 
				
			||||||
 | 
									username: "Bojack Horseman"
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								channel_id: "160197704226439168",
 | 
				
			||||||
 | 
								components: [],
 | 
				
			||||||
 | 
								content: "<:ae_botrac4r:551636841284108289> @cadence asked ````, I respond: Stop drinking paint. (No)\n\nHit <:bn_re:362741439211503616> to reroll.",
 | 
				
			||||||
 | 
								edited_timestamp: "2023-08-16T03:06:07.128980+00:00",
 | 
				
			||||||
 | 
								embeds: [],
 | 
				
			||||||
 | 
								flags: 0,
 | 
				
			||||||
 | 
								guild_id: "112760669178241024",
 | 
				
			||||||
 | 
								id: "1141206225632112650",
 | 
				
			||||||
 | 
								member: {
 | 
				
			||||||
 | 
									avatar: null,
 | 
				
			||||||
 | 
									communication_disabled_until: null,
 | 
				
			||||||
 | 
									deaf: false,
 | 
				
			||||||
 | 
									flags: 0,
 | 
				
			||||||
 | 
									joined_at: "2020-10-29T23:55:31.277000+00:00",
 | 
				
			||||||
 | 
									mute: false,
 | 
				
			||||||
 | 
									nick: "Olmec",
 | 
				
			||||||
 | 
									pending: false,
 | 
				
			||||||
 | 
									premium_since: null,
 | 
				
			||||||
 | 
									roles: [
 | 
				
			||||||
 | 
										"112767366235959296",
 | 
				
			||||||
 | 
										"118924814567211009",
 | 
				
			||||||
 | 
										"392141548932038658",
 | 
				
			||||||
 | 
										"1123460940935991296",
 | 
				
			||||||
 | 
										"326409028601249793",
 | 
				
			||||||
 | 
										"114526764860047367",
 | 
				
			||||||
 | 
										"323966487763353610",
 | 
				
			||||||
 | 
										"1107404526870335629",
 | 
				
			||||||
 | 
										"1040735082610167858"
 | 
				
			||||||
 | 
									]
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								mention_everyone: false,
 | 
				
			||||||
 | 
								mention_roles: [],
 | 
				
			||||||
 | 
								mentions: [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										avatar: "8757ad3edee9541427edd7f817ae2f5c",
 | 
				
			||||||
 | 
										avatar_decoration: null,
 | 
				
			||||||
 | 
										bot: true,
 | 
				
			||||||
 | 
										discriminator: "8559",
 | 
				
			||||||
 | 
										global_name: null,
 | 
				
			||||||
 | 
										id: "353703396483661824",
 | 
				
			||||||
 | 
										member: {
 | 
				
			||||||
 | 
											avatar: null,
 | 
				
			||||||
 | 
											communication_disabled_until: null,
 | 
				
			||||||
 | 
											deaf: false,
 | 
				
			||||||
 | 
											flags: 0,
 | 
				
			||||||
 | 
											joined_at: "2017-11-30T04:27:20.749000+00:00",
 | 
				
			||||||
 | 
											mute: false,
 | 
				
			||||||
 | 
											nick: null,
 | 
				
			||||||
 | 
											pending: false,
 | 
				
			||||||
 | 
											premium_since: null,
 | 
				
			||||||
 | 
											roles: [
 | 
				
			||||||
 | 
												"112767366235959296",
 | 
				
			||||||
 | 
												"118924814567211009",
 | 
				
			||||||
 | 
												"289671295359254529",
 | 
				
			||||||
 | 
												"114526764860047367",
 | 
				
			||||||
 | 
												"1040735082610167858"
 | 
				
			||||||
 | 
											]
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										public_flags: 0,
 | 
				
			||||||
 | 
										username: "botrac4r"
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								pinned: false,
 | 
				
			||||||
 | 
								timestamp: "2023-08-16T03:06:06.777000+00:00",
 | 
				
			||||||
 | 
								tts: false,
 | 
				
			||||||
 | 
								type: 0
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		edit_of_reply_to_skull_webp_attachment_with_content: {
 | 
							edit_of_reply_to_skull_webp_attachment_with_content: {
 | 
				
			||||||
			type: 19,
 | 
								type: 19,
 | 
				
			||||||
			tts: false,
 | 
								tts: false,
 | 
				
			||||||
| 
						 | 
					@ -881,47 +1004,6 @@ module.exports = {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
			guild_id: "112760669178241024"
 | 
								guild_id: "112760669178241024"
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		sticker: {
 | 
					 | 
				
			||||||
			id: "1106366167788044450",
 | 
					 | 
				
			||||||
			type: 0,
 | 
					 | 
				
			||||||
			content: "can have attachments too",
 | 
					 | 
				
			||||||
			channel_id: "122155380120748034",
 | 
					 | 
				
			||||||
			author: {
 | 
					 | 
				
			||||||
				id: "113340068197859328",
 | 
					 | 
				
			||||||
				username: "Cookie 🍪",
 | 
					 | 
				
			||||||
				global_name: null,
 | 
					 | 
				
			||||||
				display_name: null,
 | 
					 | 
				
			||||||
				avatar: "b48302623a12bc7c59a71328f72ccb39",
 | 
					 | 
				
			||||||
				discriminator: "7766",
 | 
					 | 
				
			||||||
				public_flags: 128,
 | 
					 | 
				
			||||||
				avatar_decoration: null
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			attachments: [{
 | 
					 | 
				
			||||||
				id: "1106366167486038016",
 | 
					 | 
				
			||||||
				filename: "image.png",
 | 
					 | 
				
			||||||
				size: 127373,
 | 
					 | 
				
			||||||
				url: "https://cdn.discordapp.com/attachments/122155380120748034/1106366167486038016/image.png",
 | 
					 | 
				
			||||||
				proxy_url: "https://media.discordapp.net/attachments/122155380120748034/1106366167486038016/image.png",
 | 
					 | 
				
			||||||
				width: 333,
 | 
					 | 
				
			||||||
				height: 287,
 | 
					 | 
				
			||||||
				content_type: "image/png"
 | 
					 | 
				
			||||||
			}],
 | 
					 | 
				
			||||||
			embeds: [],
 | 
					 | 
				
			||||||
			mentions: [],
 | 
					 | 
				
			||||||
			mention_roles: [],
 | 
					 | 
				
			||||||
			pinned: false,
 | 
					 | 
				
			||||||
			mention_everyone: false,
 | 
					 | 
				
			||||||
			tts: false,
 | 
					 | 
				
			||||||
			timestamp: "2023-05-11T23:44:09.690000+00:00",
 | 
					 | 
				
			||||||
			edited_timestamp: null,
 | 
					 | 
				
			||||||
			flags: 0,
 | 
					 | 
				
			||||||
			components: [],
 | 
					 | 
				
			||||||
			sticker_items: [{
 | 
					 | 
				
			||||||
				id: "1106323941183717586",
 | 
					 | 
				
			||||||
				format_type: 1,
 | 
					 | 
				
			||||||
				name: "pomu puff"
 | 
					 | 
				
			||||||
			}]
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ require("../matrix/kstate.test")
 | 
				
			||||||
require("../matrix/api.test")
 | 
					require("../matrix/api.test")
 | 
				
			||||||
require("../matrix/read-registration.test")
 | 
					require("../matrix/read-registration.test")
 | 
				
			||||||
require("../d2m/converters/message-to-event.test")
 | 
					require("../d2m/converters/message-to-event.test")
 | 
				
			||||||
 | 
					require("../d2m/converters/edit-to-changes.test")
 | 
				
			||||||
require("../d2m/actions/create-room.test")
 | 
					require("../d2m/actions/create-room.test")
 | 
				
			||||||
require("../d2m/converters/user-to-mxid.test")
 | 
					require("../d2m/converters/user-to-mxid.test")
 | 
				
			||||||
require("../d2m/actions/register-user.test")
 | 
					require("../d2m/actions/register-user.test")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -38,6 +38,14 @@ namespace Event {
 | 
				
			||||||
		event_id: string
 | 
							event_id: string
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type ReplacementContent<T> = T & {
 | 
				
			||||||
 | 
							"m.new_content": T
 | 
				
			||||||
 | 
							"m.relates_to": {
 | 
				
			||||||
 | 
								rel_type: string // "m.replace"
 | 
				
			||||||
 | 
								event_id: string
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	export type BaseStateEvent = {
 | 
						export type BaseStateEvent = {
 | 
				
			||||||
		type: string
 | 
							type: string
 | 
				
			||||||
		room_id: string
 | 
							room_id: string
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue