Copy Discord emojis/stickers to Matrix
This commit is contained in:
parent
d81aa51787
commit
807ab899be
4 changed files with 121 additions and 3 deletions
|
@ -12,6 +12,8 @@ const api = sync.require("../../matrix/api")
|
|||
const file = sync.require("../../matrix/file")
|
||||
/** @type {import("./create-room")} */
|
||||
const createRoom = sync.require("./create-room")
|
||||
/** @type {import("../converters/expression")} */
|
||||
const expression = sync.require("../converters/expression")
|
||||
/** @type {import("../../matrix/kstate")} */
|
||||
const ks = sync.require("../../matrix/kstate")
|
||||
|
||||
|
@ -186,8 +188,29 @@ async function syncSpaceFully(guildID) {
|
|||
return spaceID
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("discord-api-types/v10").GatewayGuildEmojisUpdateDispatchData | import("discord-api-types/v10").GatewayGuildStickersUpdateDispatchData} data
|
||||
*/
|
||||
async function syncSpaceExpressions(data) {
|
||||
// No need for kstate here. Each of these maps to a single state event, which will always overwrite what was there before. I can just send the state event.
|
||||
|
||||
const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(data.guild_id)
|
||||
if (!spaceID) return
|
||||
|
||||
if ("emojis" in data && data.emojis.length) {
|
||||
const content = await expression.emojisToState(data.emojis)
|
||||
api.sendState(spaceID, "im.ponies.room_emotes", "moe.cadence.ooye.pack.emojis", content)
|
||||
}
|
||||
|
||||
if ("stickers" in data && data.stickers.length) {
|
||||
const content = await expression.stickersToState(data.stickers)
|
||||
api.sendState(spaceID, "im.ponies.room_emotes", "moe.cadence.ooye.pack.stickers", content)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.createSpace = createSpace
|
||||
module.exports.ensureSpace = ensureSpace
|
||||
module.exports.syncSpace = syncSpace
|
||||
module.exports.syncSpaceFully = syncSpaceFully
|
||||
module.exports.guildToKState = guildToKState
|
||||
module.exports.syncSpaceExpressions = syncSpaceExpressions
|
||||
|
|
82
d2m/converters/expression.js
Normal file
82
d2m/converters/expression.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
// @ts-check
|
||||
|
||||
const assert = require("assert").strict
|
||||
const DiscordTypes = require("discord-api-types/v10")
|
||||
|
||||
const passthrough = require("../../passthrough")
|
||||
const {discord, sync, db, select} = passthrough
|
||||
/** @type {import("../../matrix/file")} */
|
||||
const file = sync.require("../../matrix/file")
|
||||
|
||||
/**
|
||||
* @param {DiscordTypes.APIEmoji[]} emojis
|
||||
*/
|
||||
async function emojisToState(emojis) {
|
||||
const result = {
|
||||
pack: {
|
||||
display_name: "Discord Emojis",
|
||||
usage: ["emoticon"] // we'll see...
|
||||
},
|
||||
images: {
|
||||
}
|
||||
}
|
||||
await Promise.all(emojis.map(emoji =>
|
||||
// the homeserver can probably cope with doing this in parallel
|
||||
file.uploadDiscordFileToMxc(file.emoji(emoji.id, emoji.animated)).then(url => {
|
||||
result.images[emoji.name] = {
|
||||
info: {
|
||||
mimetype: emoji.animated ? "image/gif" : "image/png"
|
||||
},
|
||||
url
|
||||
}
|
||||
}).catch(e => {
|
||||
if (e.data.errcode === "M_TOO_LARGE") { // Lol.
|
||||
return
|
||||
}
|
||||
console.error(`Trying to handle emoji ${emoji.name} (${emoji.id}), but...`)
|
||||
throw e
|
||||
})
|
||||
))
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DiscordTypes.APISticker[]} stickers
|
||||
*/
|
||||
async function stickersToState(stickers) {
|
||||
const result = {
|
||||
pack: {
|
||||
display_name: "Discord Stickers",
|
||||
usage: ["sticker"] // we'll see...
|
||||
},
|
||||
images: {
|
||||
}
|
||||
}
|
||||
const shortcodes = []
|
||||
await Promise.all(stickers.map(sticker =>
|
||||
// the homeserver can probably cope with doing this in parallel
|
||||
file.uploadDiscordFileToMxc(file.sticker(sticker)).then(url => {
|
||||
|
||||
/** @type {string | undefined} */
|
||||
let body = sticker.name
|
||||
if (sticker && sticker.description) body += ` - ${sticker.description}`
|
||||
if (!body) body = undefined
|
||||
|
||||
let shortcode = sticker.name.toLowerCase().replace(/[^a-zA-Z0-9-_]/g, "-").replace(/^-|-$/g, "").replace(/--+/g, "-")
|
||||
while (shortcodes.includes(shortcode)) shortcode = shortcode + "~"
|
||||
shortcodes.push(shortcode)
|
||||
|
||||
result.images[shortcodes] = {
|
||||
info: {
|
||||
mimetype: file.stickerFormat.get(sticker.format_type)?.mime || "image/png"
|
||||
},
|
||||
body,
|
||||
url
|
||||
}
|
||||
})
|
||||
))
|
||||
return result
|
||||
}
|
||||
|
||||
module.exports.emojisToState = emojisToState
|
||||
module.exports.stickersToState = stickersToState
|
|
@ -56,6 +56,18 @@ const utils = {
|
|||
}
|
||||
}
|
||||
|
||||
} else if (message.t === "GUILD_EMOJIS_UPDATE") {
|
||||
const guild = client.guilds.get(message.d.guild_id)
|
||||
if (guild) {
|
||||
guild.emojis = message.d.emojis
|
||||
}
|
||||
|
||||
} else if (message.t === "GUILD_STICKERS_UPDATE") {
|
||||
const guild = client.guilds.get(message.d.guild_id)
|
||||
if (guild) {
|
||||
guild.stickers = message.d.stickers
|
||||
}
|
||||
|
||||
} else if (message.t === "THREAD_CREATE") {
|
||||
client.channels.set(message.d.id, message.d)
|
||||
|
||||
|
@ -98,6 +110,9 @@ const utils = {
|
|||
if (message.t === "GUILD_UPDATE") {
|
||||
await eventDispatcher.onGuildUpdate(client, message.d)
|
||||
|
||||
} else if (message.t === "GUILD_EMOJIS_UPDATE" || message.t === "GUILD_STICKERS_UPDATE") {
|
||||
await eventDispatcher.onExpressionsUpdate(client, message.d)
|
||||
|
||||
} else if (message.t === "CHANNEL_UPDATE") {
|
||||
await eventDispatcher.onChannelOrThreadUpdate(client, message.d, false)
|
||||
|
||||
|
|
|
@ -239,8 +239,6 @@ module.exports = {
|
|||
* @param {import("discord-api-types/v10").GatewayGuildEmojisUpdateDispatchData | import("discord-api-types/v10").GatewayGuildStickersUpdateDispatchData} data
|
||||
*/
|
||||
async onExpressionsUpdate(client, data) {
|
||||
const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(guild.id)
|
||||
if (!spaceID) return
|
||||
await createSpace.syncSpaceExpressions(spaceID, data)
|
||||
await createSpace.syncSpaceExpressions(data)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue