forked from cadence/out-of-your-element
Sync my branches, again #3
3 changed files with 23 additions and 43 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const streamr = require("stream")
|
const {Readable} = require("stream")
|
||||||
const {pipeline} = require("stream").promises
|
const {ReadableStream} = require("stream/web")
|
||||||
|
|
||||||
const {sync} = require("../../passthrough")
|
const {sync} = require("../../passthrough")
|
||||||
const sharp = require("sharp")
|
const sharp = require("sharp")
|
||||||
|
|
@ -16,7 +16,7 @@ const HEIGHT = 160
|
||||||
/**
|
/**
|
||||||
* Downloads the sticker from the web and converts to webp data.
|
* Downloads the sticker from the web and converts to webp data.
|
||||||
* @param {string} mxc a single mxc:// URL
|
* @param {string} mxc a single mxc:// URL
|
||||||
* @returns {Promise<Buffer | undefined>} sticker webp data, or undefined if the downloaded sticker is not valid
|
* @returns {Promise<ReadableStream>} sticker webp data, or undefined if the downloaded sticker is not valid
|
||||||
*/
|
*/
|
||||||
async function getAndResizeSticker(mxc) {
|
async function getAndResizeSticker(mxc) {
|
||||||
const res = await api.getMedia(mxc)
|
const res = await api.getMedia(mxc)
|
||||||
|
|
@ -24,29 +24,16 @@ async function getAndResizeSticker(mxc) {
|
||||||
const root = await res.json()
|
const root = await res.json()
|
||||||
throw new mreq.MatrixServerError(root, {mxc})
|
throw new mreq.MatrixServerError(root, {mxc})
|
||||||
}
|
}
|
||||||
const streamIn = streamr.Readable.fromWeb(res.body)
|
|
||||||
|
|
||||||
|
const streamIn = Readable.fromWeb(res.body)
|
||||||
const { stream, mime } = await streamMimeType.getMimeType(streamIn)
|
const { stream, mime } = await streamMimeType.getMimeType(streamIn)
|
||||||
let animated = false
|
const animated = ["image/gif", "image/webp"].includes(mime)
|
||||||
if (mime === "image/gif" || mime === "image/webp") {
|
|
||||||
animated = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await new Promise((resolve, reject) => {
|
const transformer = sharp({animated: animated})
|
||||||
const transformer = sharp({animated: animated})
|
.resize(WIDTH, HEIGHT, {fit: "inside", background: {r: 0, g: 0, b: 0, alpha: 0}})
|
||||||
.resize(WIDTH, HEIGHT, {fit: "inside", background: {r: 0, g: 0, b: 0, alpha: 0}})
|
.webp()
|
||||||
.webp()
|
stream.pipe(transformer)
|
||||||
.toBuffer((err, buffer, info) => {
|
return Readable.toWeb(transformer)
|
||||||
/* c8 ignore next */
|
|
||||||
if (err) return reject(err)
|
|
||||||
resolve({info, buffer})
|
|
||||||
})
|
|
||||||
pipeline(
|
|
||||||
stream,
|
|
||||||
transformer
|
|
||||||
)
|
|
||||||
})
|
|
||||||
return result.buffer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -631,17 +631,11 @@ async function eventToMessage(event, guild, channel, di) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type === "m.sticker") {
|
if (event.type === "m.sticker") {
|
||||||
content = ""
|
|
||||||
content += `[${event.content.body}](` // sticker title for fallback if the url preview fails
|
|
||||||
const afterLink = ")"
|
|
||||||
|
|
||||||
// Make sticker URL params
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
const withoutMxc = mxUtils.makeMxcPublic(event.content.url)
|
const withoutMxc = mxUtils.makeMxcPublic(event.content.url)
|
||||||
assert(withoutMxc)
|
assert(withoutMxc)
|
||||||
params.append("mxc", withoutMxc)
|
const url = `${reg.ooye.bridge_origin}/download/sticker/${withoutMxc}/_.webp`
|
||||||
const url = `${reg.ooye.bridge_origin}/download/sticker.webp?${params.toString()}`
|
content = `[${event.content.body || "\u2800"}](${url})`
|
||||||
content += url + afterLink
|
|
||||||
} else if (event.type === "org.matrix.msc3381.poll.start") {
|
} else if (event.type === "org.matrix.msc3381.poll.start") {
|
||||||
const pollContent = event.content["org.matrix.msc3381.poll.start"] // just for convenience
|
const pollContent = event.content["org.matrix.msc3381.poll.start"] // just for convenience
|
||||||
const isClosed = false;
|
const isClosed = false;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ const schema = {
|
||||||
e: z.array(z.string()).or(z.string())
|
e: z.array(z.string()).or(z.string())
|
||||||
}),
|
}),
|
||||||
sticker: z.object({
|
sticker: z.object({
|
||||||
mxc: z.string()
|
server_name: z.string().regex(/^[^/]+$/),
|
||||||
|
media_id: z.string().regex(/^[A-Za-z0-9_-]+$/)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,15 +98,13 @@ as.router.get(`/download/sheet`, defineEventHandler(async event => {
|
||||||
return buffer
|
return buffer
|
||||||
}))
|
}))
|
||||||
|
|
||||||
as.router.get(`/download/sticker.webp`, defineEventHandler(async event => {
|
as.router.get(`/download/sticker/:server_name/:media_id/_.webp`, defineEventHandler(async event => {
|
||||||
const query = await getValidatedQuery(event, schema.sticker.parse)
|
const {server_name, media_id} = await getValidatedRouterParams(event, schema.sticker.parse)
|
||||||
|
/** remember that this has no mxc:// protocol in the string */
|
||||||
|
const mxc = server_name + "/" + media_id
|
||||||
|
verifyMediaHash(mxc)
|
||||||
|
|
||||||
/** remember that these have no mxc:// protocol in the string */
|
const stream = await sticker.getAndResizeSticker(`mxc://${mxc}`)
|
||||||
verifyMediaHash(query.mxc)
|
setResponseHeader(event, "Content-Type", "image/webp")
|
||||||
const mxc = `mxc://${query.mxc}`
|
return stream
|
||||||
|
|
||||||
setResponseHeader(event, "Content-Type", 'image/webp')
|
|
||||||
const buffer = await sticker.getAndResizeSticker(mxc)
|
|
||||||
return buffer
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue