Compare commits
No commits in common. "5b15f710d7c811c7c1f4f684234b85f87bab10bd" and "ae640a8fde8f38c3d5bd7f4242fca4c4f4b7cd38" have entirely different histories.
5b15f710d7
...
ae640a8fde
10 changed files with 29 additions and 80 deletions
|
@ -32,13 +32,12 @@ function applyKStateDiffToRoom(roomID, kstate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DiscordTypes.APIGuildTextChannel} channel
|
* @param {import("discord-api-types/v10").APIGuildTextChannel} channel
|
||||||
* @param {DiscordTypes.APIGuild} guild
|
* @param {import("discord-api-types/v10").APIGuild} guild
|
||||||
*/
|
*/
|
||||||
async function channelToKState(channel, guild) {
|
async function channelToKState(channel, guild) {
|
||||||
const spaceID = db.prepare("SELECT space_id FROM guild_space WHERE guild_id = ?").pluck().get(guild.id)
|
const spaceID = db.prepare("SELECT space_id FROM guild_space WHERE guild_id = ?").pluck().get(guild.id)
|
||||||
assert.ok(typeof spaceID === "string")
|
assert.ok(typeof spaceID === "string")
|
||||||
const customName = db.prepare("SELECT nick FROM channel_room WHERE channel_id = ?").pluck().get(channel.id)
|
|
||||||
|
|
||||||
const avatarEventContent = {}
|
const avatarEventContent = {}
|
||||||
if (guild.icon) {
|
if (guild.icon) {
|
||||||
|
@ -46,27 +45,9 @@ async function channelToKState(channel, guild) {
|
||||||
avatarEventContent.url = await file.uploadDiscordFileToMxc(avatarEventContent.discord_path) // TODO: somehow represent future values in kstate (callbacks?), while still allowing for diffing, so test cases don't need to touch the media API
|
avatarEventContent.url = await file.uploadDiscordFileToMxc(avatarEventContent.discord_path) // TODO: somehow represent future values in kstate (callbacks?), while still allowing for diffing, so test cases don't need to touch the media API
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Improve nasty nested ifs
|
|
||||||
let convertedName, convertedTopic
|
|
||||||
if (customName) {
|
|
||||||
convertedName = customName
|
|
||||||
if (channel.topic) {
|
|
||||||
convertedTopic = `${channel.name} | ${channel.topic}\n\nChannel ID: ${channel.id}\nGuild ID: ${guild.id}`
|
|
||||||
} else {
|
|
||||||
convertedTopic = `${channel.name}\n\nChannel ID: ${channel.id}\nGuild ID: ${guild.id}`
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
convertedName = channel.name
|
|
||||||
if (channel.topic) {
|
|
||||||
convertedTopic = `${channel.topic}\n\nChannel ID: ${channel.id}\nGuild ID: ${guild.id}`
|
|
||||||
} else {
|
|
||||||
convertedTopic = `Channel ID: ${channel.id}\nGuild ID: ${guild.id}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const channelKState = {
|
const channelKState = {
|
||||||
"m.room.name/": {name: convertedName},
|
"m.room.name/": {name: channel.name},
|
||||||
"m.room.topic/": {topic: convertedTopic},
|
"m.room.topic/": {$if: channel.topic, topic: channel.topic},
|
||||||
"m.room.avatar/": avatarEventContent,
|
"m.room.avatar/": avatarEventContent,
|
||||||
"m.room.guest_access/": {guest_access: "can_join"},
|
"m.room.guest_access/": {guest_access: "can_join"},
|
||||||
"m.room.history_visibility/": {history_visibility: "invited"},
|
"m.room.history_visibility/": {history_visibility: "invited"},
|
||||||
|
@ -77,7 +58,7 @@ async function channelToKState(channel, guild) {
|
||||||
"m.room.join_rules/": {
|
"m.room.join_rules/": {
|
||||||
join_rule: "restricted",
|
join_rule: "restricted",
|
||||||
allow: [{
|
allow: [{
|
||||||
type: "m.room_membership",
|
type: "m.room.membership",
|
||||||
room_id: spaceID
|
room_id: spaceID
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
@ -88,7 +69,7 @@ async function channelToKState(channel, guild) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a bridge room, store the relationship in the database, and add it to the guild's space.
|
* Create a bridge room, store the relationship in the database, and add it to the guild's space.
|
||||||
* @param {DiscordTypes.APIGuildTextChannel} channel
|
* @param {import("discord-api-types/v10").APIGuildTextChannel} channel
|
||||||
* @param guild
|
* @param guild
|
||||||
* @param {string} spaceID
|
* @param {string} spaceID
|
||||||
* @param {any} kstate
|
* @param {any} kstate
|
||||||
|
@ -115,7 +96,7 @@ async function createRoom(channel, guild, spaceID, kstate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DiscordTypes.APIGuildChannel} channel
|
* @param {import("discord-api-types/v10").APIGuildChannel} channel
|
||||||
*/
|
*/
|
||||||
function channelToGuild(channel) {
|
function channelToGuild(channel) {
|
||||||
const guildID = channel.guild_id
|
const guildID = channel.guild_id
|
||||||
|
@ -148,7 +129,7 @@ function channelToGuild(channel) {
|
||||||
* @returns {Promise<string>} room ID
|
* @returns {Promise<string>} room ID
|
||||||
*/
|
*/
|
||||||
async function _syncRoom(channelID, shouldActuallySync) {
|
async function _syncRoom(channelID, shouldActuallySync) {
|
||||||
/** @ts-ignore @type {DiscordTypes.APIGuildChannel} */
|
/** @ts-ignore @type {import("discord-api-types/v10").APIGuildChannel} */
|
||||||
const channel = discord.channels.get(channelID)
|
const channel = discord.channels.get(channelID)
|
||||||
assert.ok(channel)
|
assert.ok(channel)
|
||||||
const guild = channelToGuild(channel)
|
const guild = channelToGuild(channel)
|
||||||
|
@ -198,10 +179,8 @@ async function createAllForGuild(guildID) {
|
||||||
const channelIDs = discord.guildChannelMap.get(guildID)
|
const channelIDs = discord.guildChannelMap.get(guildID)
|
||||||
assert.ok(channelIDs)
|
assert.ok(channelIDs)
|
||||||
for (const channelID of channelIDs) {
|
for (const channelID of channelIDs) {
|
||||||
if (discord.channels.get(channelID)?.type === DiscordTypes.ChannelType.GuildText) { // TODO: guild sync thread channels and such. maybe make a helper function to check if a given channel is syncable?
|
|
||||||
await syncRoom(channelID).then(r => console.log(`synced ${channelID}:`, r))
|
await syncRoom(channelID).then(r => console.log(`synced ${channelID}:`, r))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.createRoom = createRoom
|
module.exports.createRoom = createRoom
|
||||||
|
|
|
@ -15,19 +15,19 @@ const createRoom = sync.require("../actions/create-room")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
|
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
|
||||||
* @param {import("discord-api-types/v10").APIGuild} guild
|
|
||||||
*/
|
*/
|
||||||
async function sendMessage(message, guild) {
|
async function sendMessage(message) {
|
||||||
|
assert.ok(message.member)
|
||||||
|
|
||||||
const roomID = await createRoom.ensureRoom(message.channel_id)
|
const roomID = await createRoom.ensureRoom(message.channel_id)
|
||||||
|
|
||||||
let senderMxid = null
|
let senderMxid = null
|
||||||
if (!message.webhook_id) {
|
if (!message.webhook_id) {
|
||||||
assert(message.member)
|
|
||||||
senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
|
senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
|
||||||
await registerUser.syncUser(message.author, message.member, message.guild_id, roomID)
|
await registerUser.syncUser(message.author, message.member, message.guild_id, roomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
const events = await messageToEvent.messageToEvent(message, guild)
|
const events = await messageToEvent.messageToEvent(message)
|
||||||
const eventIDs = []
|
const eventIDs = []
|
||||||
let eventPart = 0 // 0 is primary, 1 is supporting
|
let eventPart = 0 // 0 is primary, 1 is supporting
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const assert = require("assert").strict
|
|
||||||
const markdown = require("discord-markdown")
|
const markdown = require("discord-markdown")
|
||||||
|
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const { sync, db, discord } = passthrough
|
const { sync, db } = passthrough
|
||||||
/** @type {import("../../matrix/file")} */
|
/** @type {import("../../matrix/file")} */
|
||||||
const file = sync.require("../../matrix/file")
|
const file = sync.require("../../matrix/file")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("discord-api-types/v10").APIMessage} message
|
* @param {import("discord-api-types/v10").APIMessage} message
|
||||||
* @param {import("discord-api-types/v10").APIGuild} guild
|
|
||||||
*/
|
*/
|
||||||
async function messageToEvent(message, guild) {
|
async function messageToEvent(message) {
|
||||||
const events = []
|
const events = []
|
||||||
|
|
||||||
// Text content appears first
|
// Text content appears first
|
||||||
|
@ -89,31 +87,6 @@ async function messageToEvent(message, guild) {
|
||||||
events.push(...attachmentEvents)
|
events.push(...attachmentEvents)
|
||||||
|
|
||||||
// Then stickers
|
// Then stickers
|
||||||
if (message.sticker_items) {
|
|
||||||
const stickerEvents = await Promise.all(message.sticker_items.map(async stickerItem => {
|
|
||||||
const format = file.stickerFormat.get(stickerItem.format_type)
|
|
||||||
if (format?.mime) {
|
|
||||||
let body = stickerItem.name
|
|
||||||
const sticker = guild.stickers.find(sticker => sticker.id === stickerItem.id)
|
|
||||||
if (sticker && sticker.description) body += ` - ${sticker.description}`
|
|
||||||
return {
|
|
||||||
$type: "m.sticker",
|
|
||||||
body,
|
|
||||||
info: {
|
|
||||||
mimetype: format.mime
|
|
||||||
},
|
|
||||||
url: await file.uploadDiscordFileToMxc(file.sticker(stickerItem))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
$type: "m.room.message",
|
|
||||||
msgtype: "m.text",
|
|
||||||
body: "Unsupported sticker format. Name: " + stickerItem.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
events.push(...stickerEvents)
|
|
||||||
}
|
|
||||||
|
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ const {messageToEvent} = require("./message-to-event")
|
||||||
const data = require("../../test/data")
|
const data = require("../../test/data")
|
||||||
|
|
||||||
test("message2event: stickers", async t => {
|
test("message2event: stickers", async t => {
|
||||||
const events = await messageToEvent(data.message.sticker, data.guild.general)
|
const events = await messageToEvent(data.message.sticker)
|
||||||
t.deepEqual(events, [{
|
t.deepEqual(events, [{
|
||||||
$type: "m.room.message",
|
$type: "m.room.message",
|
||||||
msgtype: "m.text",
|
msgtype: "m.text",
|
||||||
|
@ -29,6 +29,6 @@ test("message2event: stickers", async t => {
|
||||||
// thumbnail_url
|
// thumbnail_url
|
||||||
// thumbnail_info
|
// thumbnail_info
|
||||||
},
|
},
|
||||||
url: "mxc://cadence.moe/UuUaLwXhkxFRwwWCXipDlBHn"
|
url: "mxc://"
|
||||||
}])
|
}])
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const assert = require("assert").strict
|
// @ts-check
|
||||||
|
|
||||||
const {sync} = require("../passthrough")
|
const {sync} = require("../passthrough")
|
||||||
|
|
||||||
/** @type {import("./actions/send-message")}) */
|
/** @type {import("./actions/send-message")}) */
|
||||||
|
@ -14,11 +15,8 @@ module.exports = {
|
||||||
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
|
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
|
||||||
*/
|
*/
|
||||||
onMessageCreate(client, message) {
|
onMessageCreate(client, message) {
|
||||||
/** @ts-ignore @type {import("discord-api-types/v10").APIGuildChannel} */
|
|
||||||
const channel = client.channels.get(message.channel_id)
|
|
||||||
const guild = client.guilds.get(channel.guild_id)
|
|
||||||
if (message.guild_id !== "112760669178241024") return // TODO: activate on other servers (requires the space creation flow to be done first)
|
if (message.guild_id !== "112760669178241024") return // TODO: activate on other servers (requires the space creation flow to be done first)
|
||||||
sendMessage.sendMessage(message, guild)
|
sendMessage.sendMessage(message)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +24,7 @@ module.exports = {
|
||||||
* @param {import("discord-api-types/v10").GatewayMessageReactionAddDispatchData} data
|
* @param {import("discord-api-types/v10").GatewayMessageReactionAddDispatchData} data
|
||||||
*/
|
*/
|
||||||
onReactionAdd(client, data) {
|
onReactionAdd(client, data) {
|
||||||
if (data.emoji.id !== null) return // TODO: image emoji reactions
|
if (data.emoji.id !== null) return // TOOD: image emoji reactions
|
||||||
console.log(data)
|
console.log(data)
|
||||||
addReaction.addReaction(data)
|
addReaction.addReaction(data)
|
||||||
}
|
}
|
||||||
|
|
BIN
db/ooye.db
BIN
db/ooye.db
Binary file not shown.
|
@ -78,7 +78,7 @@ function getAllState(roomID) {
|
||||||
async function sendState(roomID, type, stateKey, content, mxid) {
|
async function sendState(roomID, type, stateKey, content, mxid) {
|
||||||
console.log(`[api] state: ${roomID}: ${type}/${stateKey}`)
|
console.log(`[api] state: ${roomID}: ${type}/${stateKey}`)
|
||||||
assert.ok(type)
|
assert.ok(type)
|
||||||
assert.ok(typeof stateKey === "string")
|
assert.ok(stateKey)
|
||||||
/** @type {import("../types").R.EventSent} */
|
/** @type {import("../types").R.EventSent} */
|
||||||
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/state/${type}/${stateKey}`, mxid), content)
|
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/state/${type}/${stateKey}`, mxid), content)
|
||||||
return root.event_id
|
return root.event_id
|
||||||
|
|
|
@ -83,11 +83,10 @@ function emoji(emojiID, animated) {
|
||||||
const stickerFormat = new Map([
|
const stickerFormat = new Map([
|
||||||
[1, {label: "PNG", ext: "png", mime: "image/png"}],
|
[1, {label: "PNG", ext: "png", mime: "image/png"}],
|
||||||
[2, {label: "APNG", ext: "png", mime: "image/apng"}],
|
[2, {label: "APNG", ext: "png", mime: "image/apng"}],
|
||||||
[3, {label: "LOTTIE", ext: "json", mime: null}],
|
[3, {label: "LOTTIE", ext: "json", mime: "application/json"}],
|
||||||
[4, {label: "GIF", ext: "gif", mime: "image/gif"}]
|
[4, {label: "GIF", ext: "gif", mime: "image/gif"}]
|
||||||
])
|
])
|
||||||
|
|
||||||
/** @param {{id: string, format_type: number}} sticker */
|
|
||||||
function sticker(sticker) {
|
function sticker(sticker) {
|
||||||
const format = stickerFormat.get(sticker.format_type)
|
const format = stickerFormat.get(sticker.format_type)
|
||||||
if (!format) throw new Error(`No such format ${sticker.format_type} for sticker ${JSON.stringify(sticker)}`)
|
if (!format) throw new Error(`No such format ${sticker.format_type} for sticker ${JSON.stringify(sticker)}`)
|
||||||
|
|
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -478,9 +478,9 @@
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
},
|
},
|
||||||
"node_modules/better-sqlite3": {
|
"node_modules/better-sqlite3": {
|
||||||
"version": "8.4.0",
|
"version": "8.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.3.0.tgz",
|
||||||
"integrity": "sha512-NmsNW1CQvqMszu/CFAJ3pLct6NEFlNfuGM6vw72KHkjOD1UDnL96XNN1BMQc1hiHo8vE2GbOWQYIpZ+YM5wrZw==",
|
"integrity": "sha512-JTmvBZL/JLTc+3Msbvq6gK6elbU9/wVMqiudplHrVJpr7sVMR9KJrNhZAbW+RhXKlpMcuEhYkdcHa3TXKNXQ1w==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bindings": "^1.5.0",
|
"bindings": "^1.5.0",
|
||||||
|
|
|
@ -22,8 +22,8 @@ module.exports = {
|
||||||
},
|
},
|
||||||
room: {
|
room: {
|
||||||
general: {
|
general: {
|
||||||
"m.room.name/": {name: "main"},
|
"m.room.name/": {name: "collective-unconscious"},
|
||||||
"m.room.topic/": {topic: "collective-unconscious | https://docs.google.com/document/d/blah/edit | I spread, pipe, and whip because it is my will. :headstone:\n\nChannel ID: 112760669178241024\nGuild ID: 112760669178241024"},
|
"m.room.topic/": {topic: "https://docs.google.com/document/d/blah/edit | I spread, pipe, and whip because it is my will. :headstone:"},
|
||||||
"m.room.guest_access/": {guest_access: "can_join"},
|
"m.room.guest_access/": {guest_access: "can_join"},
|
||||||
"m.room.history_visibility/": {history_visibility: "invited"},
|
"m.room.history_visibility/": {history_visibility: "invited"},
|
||||||
"m.space.parent/!jjWAGMeQdNrVZSSfvz:cadence.moe": {
|
"m.space.parent/!jjWAGMeQdNrVZSSfvz:cadence.moe": {
|
||||||
|
@ -33,7 +33,7 @@ module.exports = {
|
||||||
"m.room.join_rules/": {
|
"m.room.join_rules/": {
|
||||||
join_rule: "restricted",
|
join_rule: "restricted",
|
||||||
allow: [{
|
allow: [{
|
||||||
type: "m.room_membership",
|
type: "m.room.membership",
|
||||||
room_id: "!jjWAGMeQdNrVZSSfvz:cadence.moe"
|
room_id: "!jjWAGMeQdNrVZSSfvz:cadence.moe"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue