Move calls from getPublicUrlForMxc to getMedia
This commit is contained in:
parent
b45d0f3038
commit
c0d92ea66d
7 changed files with 64 additions and 52 deletions
|
@ -8,6 +8,8 @@ const {sync} = require("../../passthrough")
|
||||||
|
|
||||||
/** @type {import("../converters/emoji-sheet")} */
|
/** @type {import("../converters/emoji-sheet")} */
|
||||||
const emojiSheetConverter = sync.require("../converters/emoji-sheet")
|
const emojiSheetConverter = sync.require("../converters/emoji-sheet")
|
||||||
|
/** @type {import("../../matrix/api")} */
|
||||||
|
const api = sync.require("../../matrix/api")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads the emoji from the web and converts to uncompressed PNG data.
|
* Downloads the emoji from the web and converts to uncompressed PNG data.
|
||||||
|
@ -16,16 +18,12 @@ const emojiSheetConverter = sync.require("../converters/emoji-sheet")
|
||||||
*/
|
*/
|
||||||
async function getAndConvertEmoji(mxc) {
|
async function getAndConvertEmoji(mxc) {
|
||||||
const abortController = new AbortController()
|
const abortController = new AbortController()
|
||||||
|
|
||||||
const url = utils.getPublicUrlForMxc(mxc)
|
|
||||||
assert(url)
|
|
||||||
|
|
||||||
/** @type {import("node-fetch").Response} */
|
/** @type {import("node-fetch").Response} */
|
||||||
// If it turns out to be a GIF, we want to abandon the connection without downloading the whole thing.
|
// If it turns out to be a GIF, we want to abandon the connection without downloading the whole thing.
|
||||||
// If we were using connection pooling, we would be forced to download the entire GIF.
|
// If we were using connection pooling, we would be forced to download the entire GIF.
|
||||||
// So we set no agent to ensure we are not connection pooling.
|
// So we set no agent to ensure we are not connection pooling.
|
||||||
// @ts-ignore the signal is slightly different from the type it wants (still works fine)
|
// @ts-ignore the signal is slightly different from the type it wants (still works fine)
|
||||||
const res = await fetch(url, {agent: false, signal: abortController.signal})
|
const res = await api.getMedia(mxc, {agent: false, signal: abortController.signal})
|
||||||
return emojiSheetConverter.convertImageStream(res.body, () => {
|
return emojiSheetConverter.convertImageStream(res.body, () => {
|
||||||
abortController.abort()
|
abortController.abort()
|
||||||
res.body.pause()
|
res.body.pause()
|
||||||
|
|
|
@ -23,7 +23,7 @@ const editMessage = sync.require("../../d2m/actions/edit-message")
|
||||||
const emojiSheet = sync.require("../actions/emoji-sheet")
|
const emojiSheet = sync.require("../actions/emoji-sheet")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[], pendingFiles?: ({name: string, url: string} | {name: string, url: string, key: string, iv: string} | {name: string, buffer: Buffer | Readable})[]}} message
|
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[], pendingFiles?: ({name: string, mxc: string} | {name: string, mxc: string, key: string, iv: string} | {name: string, buffer: Buffer | Readable})[]}} message
|
||||||
* @returns {Promise<DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[]}>}
|
* @returns {Promise<DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[]}>}
|
||||||
*/
|
*/
|
||||||
async function resolvePendingFiles(message) {
|
async function resolvePendingFiles(message) {
|
||||||
|
@ -39,7 +39,7 @@ async function resolvePendingFiles(message) {
|
||||||
// Encrypted file
|
// Encrypted file
|
||||||
const d = crypto.createDecipheriv("aes-256-ctr", Buffer.from(p.key, "base64url"), Buffer.from(p.iv, "base64url"))
|
const d = crypto.createDecipheriv("aes-256-ctr", Buffer.from(p.key, "base64url"), Buffer.from(p.iv, "base64url"))
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
fetch(p.url).then(res => res.body.pipe(d))
|
await api.getMedia(p.mxc).then(res => res.body.pipe(d))
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
file: d
|
file: d
|
||||||
|
@ -47,7 +47,7 @@ async function resolvePendingFiles(message) {
|
||||||
} else {
|
} else {
|
||||||
// Unencrypted file
|
// Unencrypted file
|
||||||
/** @type {Readable} */ // @ts-ignore
|
/** @type {Readable} */ // @ts-ignore
|
||||||
const body = await fetch(p.url).then(res => res.body)
|
const body = await api.getMedia(p.mxc).then(res => res.body)
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
file: body
|
file: body
|
||||||
|
@ -79,7 +79,7 @@ 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
|
||||||
|
|
||||||
let {messagesToEdit, messagesToSend, messagesToDelete, ensureJoined} = await eventToMessage.eventToMessage(event, guild, {api, snow: discord.snow, fetch, mxcDownloader: emojiSheet.getAndConvertEmoji})
|
let {messagesToEdit, messagesToSend, messagesToDelete, ensureJoined} = await eventToMessage.eventToMessage(event, guild, {api, snow: discord.snow, mxcDownloader: emojiSheet.getAndConvertEmoji})
|
||||||
|
|
||||||
messagesToEdit = await Promise.all(messagesToEdit.map(async e => {
|
messagesToEdit = await Promise.all(messagesToEdit.map(async e => {
|
||||||
e.message = await resolvePendingFiles(e.message)
|
e.message = await resolvePendingFiles(e.message)
|
||||||
|
|
|
@ -305,7 +305,7 @@ function getUserOrProxyOwnerID(mxid) {
|
||||||
* This function will strip them from the content and generate the correct pending file of the sprite sheet.
|
* This function will strip them from the content and generate the correct pending file of the sprite sheet.
|
||||||
* @param {string} content
|
* @param {string} content
|
||||||
* @param {{id: string, name: string}[]} attachments
|
* @param {{id: string, name: string}[]} attachments
|
||||||
* @param {({name: string, url: string} | {name: string, url: string, key: string, iv: string} | {name: string, buffer: Buffer})[]} pendingFiles
|
* @param {({name: string, mxc: string} | {name: string, mxc: string, key: string, iv: string} | {name: string, buffer: Buffer})[]} pendingFiles
|
||||||
* @param {(mxc: string) => Promise<Buffer | undefined>} mxcDownloader function that will download the mxc URLs and convert to uncompressed PNG data. use `getAndConvertEmoji` or a mock.
|
* @param {(mxc: string) => Promise<Buffer | undefined>} mxcDownloader function that will download the mxc URLs and convert to uncompressed PNG data. use `getAndConvertEmoji` or a mock.
|
||||||
*/
|
*/
|
||||||
async function uploadEndOfMessageSpriteSheet(content, attachments, pendingFiles, mxcDownloader) {
|
async function uploadEndOfMessageSpriteSheet(content, attachments, pendingFiles, mxcDownloader) {
|
||||||
|
@ -389,7 +389,7 @@ async function handleRoomOrMessageLinks(input, di) {
|
||||||
* @param {string} senderMxid
|
* @param {string} senderMxid
|
||||||
* @param {string} roomID
|
* @param {string} roomID
|
||||||
* @param {DiscordTypes.APIGuild} guild
|
* @param {DiscordTypes.APIGuild} guild
|
||||||
* @param {{api: import("../../matrix/api"), snow: import("snowtransfer").SnowTransfer, fetch: import("node-fetch")["default"]}} di
|
* @param {{api: import("../../matrix/api"), snow: import("snowtransfer").SnowTransfer}} di
|
||||||
*/
|
*/
|
||||||
async function checkWrittenMentions(content, senderMxid, roomID, guild, di) {
|
async function checkWrittenMentions(content, senderMxid, roomID, guild, di) {
|
||||||
let writtenMentionMatch = content.match(/(?:^|[^"[<>/A-Za-z0-9])@([A-Za-z][A-Za-z0-9._\[\]\(\)-]+):?/d) // /d flag for indices requires node.js 16+
|
let writtenMentionMatch = content.match(/(?:^|[^"[<>/A-Za-z0-9])@([A-Za-z][A-Za-z0-9._\[\]\(\)-]+):?/d) // /d flag for indices requires node.js 16+
|
||||||
|
@ -440,7 +440,7 @@ const attachmentEmojis = new Map([
|
||||||
/**
|
/**
|
||||||
* @param {Ty.Event.Outer_M_Room_Message | Ty.Event.Outer_M_Room_Message_File | Ty.Event.Outer_M_Sticker | Ty.Event.Outer_M_Room_Message_Encrypted_File} event
|
* @param {Ty.Event.Outer_M_Room_Message | Ty.Event.Outer_M_Room_Message_File | Ty.Event.Outer_M_Sticker | Ty.Event.Outer_M_Room_Message_Encrypted_File} event
|
||||||
* @param {import("discord-api-types/v10").APIGuild} guild
|
* @param {import("discord-api-types/v10").APIGuild} guild
|
||||||
* @param {{api: import("../../matrix/api"), snow: import("snowtransfer").SnowTransfer, fetch: import("node-fetch")["default"], mxcDownloader: (mxc: string) => Promise<Buffer | undefined>}} di simple-as-nails dependency injection for the matrix API
|
* @param {{api: import("../../matrix/api"), snow: import("snowtransfer").SnowTransfer, mxcDownloader: (mxc: string) => Promise<Buffer | undefined>}} di simple-as-nails dependency injection for the matrix API
|
||||||
*/
|
*/
|
||||||
async function eventToMessage(event, guild, di) {
|
async function eventToMessage(event, guild, di) {
|
||||||
let displayName = event.sender
|
let displayName = event.sender
|
||||||
|
@ -466,7 +466,7 @@ async function eventToMessage(event, guild, di) {
|
||||||
|
|
||||||
let content = event.content.body // ultimate fallback
|
let content = event.content.body // ultimate fallback
|
||||||
const attachments = []
|
const attachments = []
|
||||||
/** @type {({name: string, url: string} | {name: string, url: string, key: string, iv: string} | {name: string, buffer: Buffer})[]} */
|
/** @type {({name: string, mxc: string} | {name: string, mxc: string, key: string, iv: string} | {name: string, buffer: Buffer})[]} */
|
||||||
const pendingFiles = []
|
const pendingFiles = []
|
||||||
/** @type {DiscordTypes.APIUser[]} */
|
/** @type {DiscordTypes.APIUser[]} */
|
||||||
const ensureJoined = []
|
const ensureJoined = []
|
||||||
|
@ -767,29 +767,23 @@ async function eventToMessage(event, guild, di) {
|
||||||
const description = (event.content.body !== event.content.filename && event.content.filename && event.content.body) || undefined
|
const description = (event.content.body !== event.content.filename && event.content.filename && event.content.body) || undefined
|
||||||
if ("url" in event.content) {
|
if ("url" in event.content) {
|
||||||
// Unencrypted
|
// Unencrypted
|
||||||
const url = mxUtils.getPublicUrlForMxc(event.content.url)
|
|
||||||
assert(url)
|
|
||||||
attachments.push({id: "0", description, filename})
|
attachments.push({id: "0", description, filename})
|
||||||
pendingFiles.push({name: filename, url})
|
pendingFiles.push({name: filename, mxc: event.content.url})
|
||||||
} else {
|
} else {
|
||||||
// Encrypted
|
// Encrypted
|
||||||
const url = mxUtils.getPublicUrlForMxc(event.content.file.url)
|
|
||||||
assert(url)
|
|
||||||
assert.equal(event.content.file.key.alg, "A256CTR")
|
assert.equal(event.content.file.key.alg, "A256CTR")
|
||||||
attachments.push({id: "0", description, filename})
|
attachments.push({id: "0", description, filename})
|
||||||
pendingFiles.push({name: filename, url, key: event.content.file.key.k, iv: event.content.file.iv})
|
pendingFiles.push({name: filename, mxc: event.content.file.url, key: event.content.file.key.k, iv: event.content.file.iv})
|
||||||
}
|
}
|
||||||
} else if (event.type === "m.sticker") {
|
} else if (event.type === "m.sticker") {
|
||||||
content = ""
|
content = ""
|
||||||
const url = mxUtils.getPublicUrlForMxc(event.content.url)
|
|
||||||
assert(url)
|
|
||||||
let filename = event.content.body
|
let filename = event.content.body
|
||||||
if (event.type === "m.sticker") {
|
if (event.type === "m.sticker") {
|
||||||
let mimetype
|
let mimetype
|
||||||
if (event.content.info?.mimetype?.includes("/")) {
|
if (event.content.info?.mimetype?.includes("/")) {
|
||||||
mimetype = event.content.info.mimetype
|
mimetype = event.content.info.mimetype
|
||||||
} else {
|
} else {
|
||||||
const res = await di.fetch(url, {method: "HEAD"})
|
const res = await di.api.getMedia(event.content.url, {method: "HEAD"})
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
mimetype = res.headers.get("content-type")
|
mimetype = res.headers.get("content-type")
|
||||||
}
|
}
|
||||||
|
@ -798,7 +792,7 @@ async function eventToMessage(event, guild, di) {
|
||||||
filename += "." + mimetype.split("/")[1]
|
filename += "." + mimetype.split("/")[1]
|
||||||
}
|
}
|
||||||
attachments.push({id: "0", filename})
|
attachments.push({id: "0", filename})
|
||||||
pendingFiles.push({name: filename, url})
|
pendingFiles.push({name: filename, mxc: event.content.url})
|
||||||
}
|
}
|
||||||
|
|
||||||
content = displayNameRunoff + replyLine + content
|
content = displayNameRunoff + replyLine + content
|
||||||
|
|
|
@ -3550,7 +3550,7 @@ test("event2message: text attachments work", async t => {
|
||||||
content: "",
|
content: "",
|
||||||
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
||||||
attachments: [{id: "0", description: undefined, filename: "chiki-powerups.txt"}],
|
attachments: [{id: "0", description: undefined, filename: "chiki-powerups.txt"}],
|
||||||
pendingFiles: [{name: "chiki-powerups.txt", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/zyThGlYQxvlvBVbVgKDDbiHH"}]
|
pendingFiles: [{name: "chiki-powerups.txt", mxc: "mxc://cadence.moe/zyThGlYQxvlvBVbVgKDDbiHH"}]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -3586,7 +3586,7 @@ test("event2message: image attachments work", async t => {
|
||||||
content: "",
|
content: "",
|
||||||
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
||||||
attachments: [{id: "0", description: undefined, filename: "cool cat.png"}],
|
attachments: [{id: "0", description: undefined, filename: "cool cat.png"}],
|
||||||
pendingFiles: [{name: "cool cat.png", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/IvxVJFLEuksCNnbojdSIeEvn"}]
|
pendingFiles: [{name: "cool cat.png", mxc: "mxc://cadence.moe/IvxVJFLEuksCNnbojdSIeEvn"}]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -3622,7 +3622,7 @@ test("event2message: image attachments can have a custom description", async t =
|
||||||
content: "",
|
content: "",
|
||||||
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
||||||
attachments: [{id: "0", description: "Cat emoji surrounded by pink hearts", filename: "cool cat.png"}],
|
attachments: [{id: "0", description: "Cat emoji surrounded by pink hearts", filename: "cool cat.png"}],
|
||||||
pendingFiles: [{name: "cool cat.png", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/IvxVJFLEuksCNnbojdSIeEvn"}]
|
pendingFiles: [{name: "cool cat.png", url: "mxc://cadence.moe/IvxVJFLEuksCNnbojdSIeEvn"}]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -3674,7 +3674,7 @@ test("event2message: encrypted image attachments work", async t => {
|
||||||
attachments: [{id: "0", description: undefined, filename: "image.png"}],
|
attachments: [{id: "0", description: undefined, filename: "image.png"}],
|
||||||
pendingFiles: [{
|
pendingFiles: [{
|
||||||
name: "image.png",
|
name: "image.png",
|
||||||
url: "https://matrix.cadence.moe/_matrix/media/r0/download/heyquark.com/LOGkUTlVFrqfiExlGZNgCJJX",
|
mxc: "mxc://heyquark.com/LOGkUTlVFrqfiExlGZNgCJJX",
|
||||||
key: "QTo-oMPnN1Rbc7vBFg9WXMgoctscdyxdFEIYm8NYceo",
|
key: "QTo-oMPnN1Rbc7vBFg9WXMgoctscdyxdFEIYm8NYceo",
|
||||||
iv: "Va9SHZpIn5kAAAAAAAAAAA"
|
iv: "Va9SHZpIn5kAAAAAAAAAAA"
|
||||||
}]
|
}]
|
||||||
|
@ -3717,7 +3717,7 @@ test("event2message: stickers work", async t => {
|
||||||
content: "",
|
content: "",
|
||||||
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/azCAhThKTojXSZJRoWwZmhvU",
|
||||||
attachments: [{id: "0", filename: "get_real2.gif"}],
|
attachments: [{id: "0", filename: "get_real2.gif"}],
|
||||||
pendingFiles: [{name: "get_real2.gif", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/NyMXQFAAdniImbHzsygScbmN"}]
|
pendingFiles: [{name: "get_real2.gif", mxc: "mxc://cadence.moe/NyMXQFAAdniImbHzsygScbmN"}]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -3736,15 +3736,17 @@ test("event2message: stickers fetch mimetype from server when mimetype not provi
|
||||||
event_id: "$mL-eEVWCwOvFtoOiivDP7gepvf-fTYH6_ioK82bWDI0",
|
event_id: "$mL-eEVWCwOvFtoOiivDP7gepvf-fTYH6_ioK82bWDI0",
|
||||||
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
||||||
}, {}, {
|
}, {}, {
|
||||||
async fetch(url, options) {
|
api: {
|
||||||
called++
|
async getMedia(mxc, options) {
|
||||||
t.equal(url, "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/ybOWQCaXysnyUGuUCaQlTGJf")
|
called++
|
||||||
t.equal(options.method, "HEAD")
|
t.equal(mxc, "mxc://cadence.moe/ybOWQCaXysnyUGuUCaQlTGJf")
|
||||||
return {
|
t.equal(options.method, "HEAD")
|
||||||
status: 200,
|
return {
|
||||||
headers: new Map([
|
status: 200,
|
||||||
["content-type", "image/gif"]
|
headers: new Map([
|
||||||
])
|
["content-type", "image/gif"]
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -3757,7 +3759,7 @@ test("event2message: stickers fetch mimetype from server when mimetype not provi
|
||||||
content: "",
|
content: "",
|
||||||
avatar_url: undefined,
|
avatar_url: undefined,
|
||||||
attachments: [{id: "0", filename: "YESYESYES.gif"}],
|
attachments: [{id: "0", filename: "YESYESYES.gif"}],
|
||||||
pendingFiles: [{name: "YESYESYES.gif", url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/ybOWQCaXysnyUGuUCaQlTGJf"}]
|
pendingFiles: [{name: "YESYESYES.gif", mxc: "mxc://cadence.moe/ybOWQCaXysnyUGuUCaQlTGJf"}]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -3777,15 +3779,17 @@ test("event2message: stickers with unknown mimetype are not allowed", async t =>
|
||||||
event_id: "$mL-eEVWCwOvFtoOiivDP7gepvf-fTYH6_ioK82bWDI0",
|
event_id: "$mL-eEVWCwOvFtoOiivDP7gepvf-fTYH6_ioK82bWDI0",
|
||||||
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
||||||
}, {}, {
|
}, {}, {
|
||||||
async fetch(url, options) {
|
api: {
|
||||||
called++
|
async getMedia(mxc, options) {
|
||||||
t.equal(url, "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/ybOWQCaXysnyUGuUCaQlTGJe")
|
called++
|
||||||
t.equal(options.method, "HEAD")
|
t.equal(mxc, "mxc://cadence.moe/ybOWQCaXysnyUGuUCaQlTGJe")
|
||||||
return {
|
t.equal(options.method, "HEAD")
|
||||||
status: 404,
|
return {
|
||||||
headers: new Map([
|
status: 404,
|
||||||
["content-type", "application/json"]
|
headers: new Map([
|
||||||
])
|
["content-type", "application/json"]
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -223,10 +223,10 @@ async function getViaServersQuery(roomID, api) {
|
||||||
*/
|
*/
|
||||||
function getPublicUrlForMxc(mxc) {
|
function getPublicUrlForMxc(mxc) {
|
||||||
assert(hasher, "xxhash is not ready yet")
|
assert(hasher, "xxhash is not ready yet")
|
||||||
const avatarURLParts = mxc?.match(/^mxc:\/\/([^/]+)\/(\w+)$/)
|
const mediaParts = mxc?.match(/^mxc:\/\/([^/]+)\/(\w+)$/)
|
||||||
if (!avatarURLParts) return null
|
if (!mediaParts) return null
|
||||||
|
|
||||||
const serverAndMediaID = `${avatarURLParts[1]}/${avatarURLParts[2]}`
|
const serverAndMediaID = `${mediaParts[1]}/${mediaParts[2]}`
|
||||||
const unsignedHash = hasher.h64(serverAndMediaID)
|
const unsignedHash = hasher.h64(serverAndMediaID)
|
||||||
const signedHash = unsignedHash - 0x8000000000000000n // shifting down to signed 64-bit range
|
const signedHash = unsignedHash - 0x8000000000000000n // shifting down to signed 64-bit range
|
||||||
db.prepare("INSERT OR IGNORE INTO media_proxy (permitted_hash) VALUES (?)").run(signedHash)
|
db.prepare("INSERT OR IGNORE INTO media_proxy (permitted_hash) VALUES (?)").run(signedHash)
|
||||||
|
|
|
@ -297,6 +297,7 @@ async function setUserPowerCascade(roomID, mxid, power) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ping() {
|
async function ping() {
|
||||||
|
// not using mreq so that we can read the status code
|
||||||
const res = await fetch(`${mreq.baseUrl}/client/v1/appservice/${reg.id}/ping`, {
|
const res = await fetch(`${mreq.baseUrl}/client/v1/appservice/${reg.id}/ping`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -312,6 +313,21 @@ async function ping() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} mxc
|
||||||
|
* @param {RequestInit} [init]
|
||||||
|
*/
|
||||||
|
function getMedia(mxc, init = {}) {
|
||||||
|
const mediaParts = mxc?.match(/^mxc:\/\/([^/]+)\/(\w+)$/)
|
||||||
|
assert(mediaParts)
|
||||||
|
return fetch(`${mreq.baseUrl}/client/v1/media/download/${mediaParts[1]}/${mediaParts[2]}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${reg.as_token}`
|
||||||
|
},
|
||||||
|
...init
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.path = path
|
module.exports.path = path
|
||||||
module.exports.register = register
|
module.exports.register = register
|
||||||
module.exports.createRoom = createRoom
|
module.exports.createRoom = createRoom
|
||||||
|
@ -336,3 +352,4 @@ module.exports.profileSetAvatarUrl = profileSetAvatarUrl
|
||||||
module.exports.setUserPower = setUserPower
|
module.exports.setUserPower = setUserPower
|
||||||
module.exports.setUserPowerCascade = setUserPowerCascade
|
module.exports.setUserPowerCascade = setUserPowerCascade
|
||||||
module.exports.ping = ping
|
module.exports.ping = ping
|
||||||
|
module.exports.getMedia = getMedia
|
||||||
|
|
|
@ -217,9 +217,8 @@ const commands = [{
|
||||||
} else {
|
} else {
|
||||||
// Upload it to Discord and have the bridge sync it back to Matrix again
|
// Upload it to Discord and have the bridge sync it back to Matrix again
|
||||||
for (const e of toUpload) {
|
for (const e of toUpload) {
|
||||||
const publicUrl = mxUtils.getPublicUrlForMxc(e.url)
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const resizeInput = await fetch(publicUrl, {agent: false}).then(res => res.arrayBuffer())
|
const resizeInput = await api.getMedia(e.url, {agent: false}).then(res => res.arrayBuffer())
|
||||||
const resizeOutput = await sharp(resizeInput)
|
const resizeOutput = await sharp(resizeInput)
|
||||||
.resize(EMOJI_SIZE, EMOJI_SIZE, {fit: "inside", withoutEnlargement: true, background: {r: 0, g: 0, b: 0, alpha: 0}})
|
.resize(EMOJI_SIZE, EMOJI_SIZE, {fit: "inside", withoutEnlargement: true, background: {r: 0, g: 0, b: 0, alpha: 0}})
|
||||||
.png()
|
.png()
|
||||||
|
|
Loading…
Reference in a new issue