m->d files and stickers
This commit is contained in:
		
							parent
							
								
									a1be84cb60
								
							
						
					
					
						commit
						6803b156bc
					
				
					 5 changed files with 219 additions and 9 deletions
				
			
		| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
// @ts-check
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const assert = require("assert").strict
 | 
					const assert = require("assert").strict
 | 
				
			||||||
 | 
					const Ty = require("../../types")
 | 
				
			||||||
const DiscordTypes = require("discord-api-types/v10")
 | 
					const DiscordTypes = require("discord-api-types/v10")
 | 
				
			||||||
const passthrough = require("../../passthrough")
 | 
					const passthrough = require("../../passthrough")
 | 
				
			||||||
const {sync, discord, db} = passthrough
 | 
					const {sync, discord, db} = passthrough
 | 
				
			||||||
| 
						 | 
					@ -12,9 +13,30 @@ const eventToMessage = sync.require("../converters/event-to-message")
 | 
				
			||||||
/** @type {import("../../matrix/api")}) */
 | 
					/** @type {import("../../matrix/api")}) */
 | 
				
			||||||
const api = sync.require("../../matrix/api")
 | 
					const api = sync.require("../../matrix/api")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @param {import("../../types").Event.Outer<any>} event */
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {pendingFiles?: {name: string, url: string}[]}} message
 | 
				
			||||||
 | 
					 * @returns {Promise<DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]}>}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async function resolvePendingFiles(message) {
 | 
				
			||||||
 | 
						if (!message.pendingFiles) return message
 | 
				
			||||||
 | 
						const files = await Promise.all(message.pendingFiles.map(async p => {
 | 
				
			||||||
 | 
							const file = await fetch(p.url).then(res => res.arrayBuffer()).then(x => Buffer.from(x))
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								name: p.name,
 | 
				
			||||||
 | 
								file
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
						const newMessage = {
 | 
				
			||||||
 | 
							...message,
 | 
				
			||||||
 | 
							files
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						delete newMessage.pendingFiles
 | 
				
			||||||
 | 
						return newMessage
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @param {Ty.Event.M_Outer_M_Room_Message | Ty.Event.M_Outer_M_Room_Message_File | Ty.Event.M_Outer_M_Sticker} event */
 | 
				
			||||||
async function sendEvent(event) {
 | 
					async function sendEvent(event) {
 | 
				
			||||||
	// TODO: we just assume the bridge has already been created
 | 
						// TODO: we just assume the bridge has already been created, is that really ok?
 | 
				
			||||||
	const row = db.prepare("SELECT channel_id, thread_parent FROM channel_room WHERE room_id = ?").get(event.room_id)
 | 
						const row = db.prepare("SELECT channel_id, thread_parent FROM channel_room WHERE room_id = ?").get(event.room_id)
 | 
				
			||||||
	let channelID = row.channel_id
 | 
						let channelID = row.channel_id
 | 
				
			||||||
	let threadID = undefined
 | 
						let threadID = undefined
 | 
				
			||||||
| 
						 | 
					@ -29,7 +51,15 @@ async function sendEvent(event) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// no need to sync the matrix member to the other side. but if I did need to, this is where I'd do it
 | 
						// no need to sync the matrix member to the other side. but if I did need to, this is where I'd do it
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const {messagesToEdit, messagesToSend, messagesToDelete} = await eventToMessage.eventToMessage(event, guild, {api})
 | 
						let {messagesToEdit, messagesToSend, messagesToDelete} = await eventToMessage.eventToMessage(event, guild, {api})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						messagesToEdit = await Promise.all(messagesToEdit.map(async e => {
 | 
				
			||||||
 | 
							e.message = await resolvePendingFiles(e.message)
 | 
				
			||||||
 | 
							return e
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
						messagesToSend = await Promise.all(messagesToSend.map(message => {
 | 
				
			||||||
 | 
							return resolvePendingFiles(message)
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let eventPart = 0 // 0 is primary, 1 is supporting
 | 
						let eventPart = 0 // 0 is primary, 1 is supporting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +78,7 @@ async function sendEvent(event) {
 | 
				
			||||||
	for (const message of messagesToSend) {
 | 
						for (const message of messagesToSend) {
 | 
				
			||||||
		const messageResponse = await channelWebhook.sendMessageWithWebhook(channelID, message, threadID)
 | 
							const messageResponse = await channelWebhook.sendMessageWithWebhook(channelID, message, threadID)
 | 
				
			||||||
		db.prepare("REPLACE INTO message_channel (message_id, channel_id) VALUES (?, ?)").run(messageResponse.id, channelID)
 | 
							db.prepare("REPLACE INTO message_channel (message_id, channel_id) VALUES (?, ?)").run(messageResponse.id, channelID)
 | 
				
			||||||
		db.prepare("INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, source) VALUES (?, ?, ?, ?, ?, 0)").run(event.event_id, event.type, event.content.msgtype || null, messageResponse.id, eventPart) // source 0 = matrix
 | 
							db.prepare("INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, source) VALUES (?, ?, ?, ?, ?, 0)").run(event.event_id, event.type, event.content["msgtype"] || null, messageResponse.id, eventPart) // source 0 = matrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		eventPart = 1
 | 
							eventPart = 1
 | 
				
			||||||
		messageResponses.push(messageResponse)
 | 
							messageResponses.push(messageResponse)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ const Ty = require("../../types")
 | 
				
			||||||
const DiscordTypes = require("discord-api-types/v10")
 | 
					const DiscordTypes = require("discord-api-types/v10")
 | 
				
			||||||
const chunk = require("chunk-text")
 | 
					const chunk = require("chunk-text")
 | 
				
			||||||
const TurndownService = require("turndown")
 | 
					const TurndownService = require("turndown")
 | 
				
			||||||
 | 
					const assert = require("assert").strict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const passthrough = require("../../passthrough")
 | 
					const passthrough = require("../../passthrough")
 | 
				
			||||||
const { sync, db, discord } = passthrough
 | 
					const { sync, db, discord } = passthrough
 | 
				
			||||||
| 
						 | 
					@ -124,7 +125,7 @@ async function getMemberFromCacheOrHomeserver(roomID, mxid, api) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {Ty.Event.Outer<Ty.Event.M_Room_Message>} event
 | 
					 * @param {Ty.Event.M_Outer_M_Room_Message | Ty.Event.M_Outer_M_Room_Message_File | Ty.Event.M_Outer_M_Sticker} event
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuild} guild
 | 
					 * @param {import("discord-api-types/v10").APIGuild} guild
 | 
				
			||||||
 * @param {{api: import("../../matrix/api")}} di simple-as-nails dependency injection for the matrix API
 | 
					 * @param {{api: import("../../matrix/api")}} di simple-as-nails dependency injection for the matrix API
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -143,12 +144,15 @@ async function eventToMessage(event, guild, di) {
 | 
				
			||||||
	// Try to extract an accurate display name and avatar URL from the member event
 | 
						// Try to extract an accurate display name and avatar URL from the member event
 | 
				
			||||||
	const member = await getMemberFromCacheOrHomeserver(event.room_id, event.sender, di?.api)
 | 
						const member = await getMemberFromCacheOrHomeserver(event.room_id, event.sender, di?.api)
 | 
				
			||||||
	if (member.displayname) displayName = member.displayname
 | 
						if (member.displayname) displayName = member.displayname
 | 
				
			||||||
	if (member.avatar_url) avatarURL = utils.getPublicUrlForMxc(member.avatar_url)
 | 
						if (member.avatar_url) avatarURL = utils.getPublicUrlForMxc(member.avatar_url) || undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let content = event.content.body // ultimate fallback
 | 
						let content = event.content.body // ultimate fallback
 | 
				
			||||||
 | 
						const attachments = []
 | 
				
			||||||
 | 
						/** @type {{name: string, url: string}[]} */
 | 
				
			||||||
 | 
						const pendingFiles = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Convert content depending on what the message is
 | 
						// Convert content depending on what the message is
 | 
				
			||||||
	if (event.content.msgtype === "m.text" || event.content.msgtype === "m.emote") {
 | 
						if (event.type === "m.room.message" && (event.content.msgtype === "m.text" || event.content.msgtype === "m.emote")) {
 | 
				
			||||||
		// Handling edits. If the edit was an edit of a reply, edits do not include the reply reference, so we need to fetch up to 2 more events.
 | 
							// Handling edits. If the edit was an edit of a reply, edits do not include the reply reference, so we need to fetch up to 2 more events.
 | 
				
			||||||
		// this event ---is an edit of--> original event ---is a reply to--> past event
 | 
							// this event ---is an edit of--> original event ---is a reply to--> past event
 | 
				
			||||||
		await (async () => {
 | 
							await (async () => {
 | 
				
			||||||
| 
						 | 
					@ -261,7 +265,7 @@ async function eventToMessage(event, guild, di) {
 | 
				
			||||||
			// @ts-ignore bad type from turndown
 | 
								// @ts-ignore bad type from turndown
 | 
				
			||||||
			content = turndownService.turndown(input)
 | 
								content = turndownService.turndown(input)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// It's optimised for commonmark, we need to replace the space-space-newline with just newline
 | 
								// It's designed for commonmark, we need to replace the space-space-newline with just newline
 | 
				
			||||||
			content = content.replace(/  \n/g, "\n")
 | 
								content = content.replace(/  \n/g, "\n")
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// Looks like we're using the plaintext body!
 | 
								// Looks like we're using the plaintext body!
 | 
				
			||||||
| 
						 | 
					@ -274,6 +278,23 @@ async function eventToMessage(event, guild, di) {
 | 
				
			||||||
			// Markdown needs to be escaped
 | 
								// Markdown needs to be escaped
 | 
				
			||||||
			content = content.replace(/([*_~`#])/g, `\\$1`)
 | 
								content = content.replace(/([*_~`#])/g, `\\$1`)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else if (event.type === "m.room.message" && (event.content.msgtype === "m.file" || event.content.msgtype === "m.video" || event.content.msgtype === "m.audio" || event.content.msgtype === "m.image")) {
 | 
				
			||||||
 | 
							content = ""
 | 
				
			||||||
 | 
							const filename = event.content.body
 | 
				
			||||||
 | 
							const url = utils.getPublicUrlForMxc(event.content.url)
 | 
				
			||||||
 | 
							assert(url)
 | 
				
			||||||
 | 
							attachments.push({id: "0", filename})
 | 
				
			||||||
 | 
							pendingFiles.push({name: filename, url})
 | 
				
			||||||
 | 
						} else if (event.type === "m.sticker") {
 | 
				
			||||||
 | 
							content = ""
 | 
				
			||||||
 | 
							let filename = event.content.body
 | 
				
			||||||
 | 
							if (event.type === "m.sticker" && event.content.info.mimetype.includes("/")) {
 | 
				
			||||||
 | 
								filename += "." + event.content.info.mimetype.split("/")[1]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							const url = utils.getPublicUrlForMxc(event.content.url)
 | 
				
			||||||
 | 
							assert(url)
 | 
				
			||||||
 | 
							attachments.push({id: "0", filename})
 | 
				
			||||||
 | 
							pendingFiles.push({name: filename, url})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	content = replyLine + content
 | 
						content = replyLine + content
 | 
				
			||||||
| 
						 | 
					@ -286,6 +307,19 @@ async function eventToMessage(event, guild, di) {
 | 
				
			||||||
		avatar_url: avatarURL
 | 
							avatar_url: avatarURL
 | 
				
			||||||
	})))
 | 
						})))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (attachments.length) {
 | 
				
			||||||
 | 
							// If content is empty (should be the case when uploading a file) then chunk-text will create 0 messages.
 | 
				
			||||||
 | 
							// There needs to be a message to add attachments to.
 | 
				
			||||||
 | 
							if (!messages.length) messages.push({
 | 
				
			||||||
 | 
								content,
 | 
				
			||||||
 | 
								username: displayName,
 | 
				
			||||||
 | 
								avatar_url: avatarURL
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							messages[0].attachments = attachments
 | 
				
			||||||
 | 
							// @ts-ignore these will be converted to real files when the message is about to be sent
 | 
				
			||||||
 | 
							messages[0].pendingFiles = pendingFiles
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const messagesToEdit = []
 | 
						const messagesToEdit = []
 | 
				
			||||||
	const messagesToSend = []
 | 
						const messagesToSend = []
 | 
				
			||||||
	for (let i = 0; i < messages.length; i++) {
 | 
						for (let i = 0; i < messages.length; i++) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1110,3 +1110,107 @@ test("event2message: skips caching the member if the member does not exist, some
 | 
				
			||||||
	t.deepEqual(db.prepare("SELECT avatar_url, displayname, mxid FROM member_cache WHERE room_id = '!not_real:cadence.moe'").all(), [])
 | 
						t.deepEqual(db.prepare("SELECT avatar_url, displayname, mxid FROM member_cache WHERE room_id = '!not_real:cadence.moe'").all(), [])
 | 
				
			||||||
	t.equal(called, 1, "getStateEvent should be called once")
 | 
						t.equal(called, 1, "getStateEvent should be called once")
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("event2message: text attachments work", async t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							await eventToMessage({
 | 
				
			||||||
 | 
								type: "m.room.message",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									body: "chiki-powerups.txt",
 | 
				
			||||||
 | 
									info: {
 | 
				
			||||||
 | 
										size: 971,
 | 
				
			||||||
 | 
										mimetype: "text/plain"
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									msgtype: "m.file",
 | 
				
			||||||
 | 
									url: "mxc://cadence.moe/zyThGlYQxvlvBVbVgKDDbiHH"
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								sender: "@cadence:cadence.moe",
 | 
				
			||||||
 | 
								event_id: "$c2WVyP6KcfAqh5imOa8e0xzt2C8JTR-cWbEd3GargEQ",
 | 
				
			||||||
 | 
								room_id: "!PnyBKvUBOhjuCucEfk:cadence.moe"
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								messagesToDelete: [],
 | 
				
			||||||
 | 
								messagesToEdit: [],
 | 
				
			||||||
 | 
								messagesToSend: [{
 | 
				
			||||||
 | 
									username: "cadence [they]",
 | 
				
			||||||
 | 
									content: "",
 | 
				
			||||||
 | 
									avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
 | 
				
			||||||
 | 
									attachments: [{id: "0", filename: "chiki-powerups.txt"}],
 | 
				
			||||||
 | 
									pendingFiles: [{name: "chiki-powerups.txt", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/zyThGlYQxvlvBVbVgKDDbiHH"}]
 | 
				
			||||||
 | 
								}]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("event2message: image attachments work", async t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							await eventToMessage({
 | 
				
			||||||
 | 
								type: "m.room.message",
 | 
				
			||||||
 | 
								sender: "@cadence:cadence.moe",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									body: "cool cat.png",
 | 
				
			||||||
 | 
									info: {
 | 
				
			||||||
 | 
										size: 43170,
 | 
				
			||||||
 | 
										mimetype: "image/png",
 | 
				
			||||||
 | 
										w: 480,
 | 
				
			||||||
 | 
										h: 480,
 | 
				
			||||||
 | 
										"xyz.amorgan.blurhash": "URTHsVaTpdj2eKZgkkkXp{pHl7feo@lSl9Z$"
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									msgtype: "m.image",
 | 
				
			||||||
 | 
									url: "mxc://cadence.moe/IvxVJFLEuksCNnbojdSIeEvn"
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								event_id: "$CXQy3Wmg1A-gL_xAesC1HQcQTEXwICLdSwwUx55FBTI",
 | 
				
			||||||
 | 
								room_id: "!PnyBKvUBOhjuCucEfk:cadence.moe"
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								messagesToDelete: [],
 | 
				
			||||||
 | 
								messagesToEdit: [],
 | 
				
			||||||
 | 
								messagesToSend: [{
 | 
				
			||||||
 | 
									username: "cadence [they]",
 | 
				
			||||||
 | 
									content: "",
 | 
				
			||||||
 | 
									avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
 | 
				
			||||||
 | 
									attachments: [{id: "0", filename: "cool cat.png"}],
 | 
				
			||||||
 | 
									pendingFiles: [{name: "cool cat.png", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/IvxVJFLEuksCNnbojdSIeEvn"}]
 | 
				
			||||||
 | 
								}]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("event2message: stickers work", async t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							await eventToMessage({
 | 
				
			||||||
 | 
								type: "m.sticker",
 | 
				
			||||||
 | 
								sender: "@cadence:cadence.moe",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									body: "get_real2",
 | 
				
			||||||
 | 
									url: "mxc://cadence.moe/NyMXQFAAdniImbHzsygScbmN",
 | 
				
			||||||
 | 
									info: {
 | 
				
			||||||
 | 
										w: 320,
 | 
				
			||||||
 | 
										h: 298,
 | 
				
			||||||
 | 
										mimetype: "image/gif",
 | 
				
			||||||
 | 
										size: 331394,
 | 
				
			||||||
 | 
										thumbnail_info: {
 | 
				
			||||||
 | 
											w: 320,
 | 
				
			||||||
 | 
											h: 298,
 | 
				
			||||||
 | 
											mimetype: "image/gif",
 | 
				
			||||||
 | 
											size: 331394
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										thumbnail_url: "mxc://cadence.moe/NyMXQFAAdniImbHzsygScbmN"
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								event_id: "$PdI-KjdQ8Z_Tb4x9_7wKRPZCsrrXym4BXtbAPekypuM",
 | 
				
			||||||
 | 
								room_id: "!PnyBKvUBOhjuCucEfk:cadence.moe"
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								messagesToDelete: [],
 | 
				
			||||||
 | 
								messagesToEdit: [],
 | 
				
			||||||
 | 
								messagesToSend: [{
 | 
				
			||||||
 | 
									username: "cadence [they]",
 | 
				
			||||||
 | 
									content: "",
 | 
				
			||||||
 | 
									avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
 | 
				
			||||||
 | 
									attachments: [{id: "0", filename: "get_real2.gif"}],
 | 
				
			||||||
 | 
									pendingFiles: [{name: "get_real2.gif", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/NyMXQFAAdniImbHzsygScbmN"}]
 | 
				
			||||||
 | 
								}]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,16 @@ function guard(type, fn) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sync.addTemporaryListener(as, "type:m.room.message", guard("m.room.message",
 | 
					sync.addTemporaryListener(as, "type:m.room.message", guard("m.room.message",
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {Ty.Event.Outer<Ty.Event.M_Room_Message>} event it is a m.room.message because that's what this listener is filtering for
 | 
					 * @param {Ty.Event.M_Outer_M_Room_Message | Ty.Event.M_Outer_M_Room_Message_File} event it is a m.room.message because that's what this listener is filtering for
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async event => {
 | 
				
			||||||
 | 
						if (utils.eventSenderIsFromDiscord(event.sender)) return
 | 
				
			||||||
 | 
						const messageResponses = await sendEvent.sendEvent(event)
 | 
				
			||||||
 | 
					}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sync.addTemporaryListener(as, "type:m.sticker", guard("m.sticker",
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {Ty.Event.M_Outer_M_Sticker} event it is a m.sticker because that's what this listener is filtering for
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async event => {
 | 
					async event => {
 | 
				
			||||||
	if (utils.eventSenderIsFromDiscord(event.sender)) return
 | 
						if (utils.eventSenderIsFromDiscord(event.sender)) return
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										33
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -80,6 +80,39 @@ export namespace Event {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type M_Outer_M_Room_Message = Outer<M_Room_Message> & {type: "m.room.message"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type M_Room_Message_File = {
 | 
				
			||||||
 | 
							msgtype: "m.file" | "m.image" | "m.video" | "m.audio"
 | 
				
			||||||
 | 
							body: string
 | 
				
			||||||
 | 
							url: string
 | 
				
			||||||
 | 
							info?: any
 | 
				
			||||||
 | 
							"m.relates_to"?: {
 | 
				
			||||||
 | 
								"m.in_reply_to": {
 | 
				
			||||||
 | 
									event_id: string
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								rel_type?: "m.replace"
 | 
				
			||||||
 | 
								event_id?: string
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type M_Outer_M_Room_Message_File = Outer<M_Room_Message_File> & {type: "m.room.message"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type M_Sticker = {
 | 
				
			||||||
 | 
							body: string
 | 
				
			||||||
 | 
							url: string
 | 
				
			||||||
 | 
							info: {
 | 
				
			||||||
 | 
								mimetype: string
 | 
				
			||||||
 | 
								w?: number
 | 
				
			||||||
 | 
								h?: number
 | 
				
			||||||
 | 
								size?: number
 | 
				
			||||||
 | 
								thumbnail_info?: any
 | 
				
			||||||
 | 
								thumbnail_url?: string
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type M_Outer_M_Sticker = Outer<M_Sticker> & {type: "m.sticker"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	export type M_Room_Member = {
 | 
						export type M_Room_Member = {
 | 
				
			||||||
		membership: string
 | 
							membership: string
 | 
				
			||||||
		displayname?: string
 | 
							displayname?: string
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue