changing spaces to tabs

This commit is contained in:
Cadence Ember 2023-08-21 21:04:41 +12:00
parent c22f434c1f
commit c8021cadec
9 changed files with 154 additions and 120 deletions

View File

@ -1,2 +1,5 @@
{
"editor.insertSpaces": false,
"editor.detectIndentation": false,
"editor.tabSize": 3
}

View File

@ -15,20 +15,20 @@ const createRoom = sync.require("../actions/create-room")
* @param {import("discord-api-types/v10").GatewayMessageReactionAddDispatchData} data
*/
async function addReaction(data) {
const user = data.member?.user
assert.ok(user && user.username)
const parentID = db.prepare("SELECT event_id FROM event_message WHERE message_id = ? AND part = 0").pluck().get(data.message_id) // 0 = primary
if (!parentID) return // Nothing can be done if the parent message was never bridged.
assert.equal(typeof parentID, "string")
const user = data.member?.user
assert.ok(user && user.username)
const parentID = db.prepare("SELECT event_id FROM event_message WHERE message_id = ? AND part = 0").pluck().get(data.message_id) // 0 = primary
if (!parentID) return // Nothing can be done if the parent message was never bridged.
assert.equal(typeof parentID, "string")
const roomID = await createRoom.ensureRoom(data.channel_id)
const senderMxid = await registerUser.ensureSimJoined(user, roomID)
const eventID = await api.sendEvent(roomID, "m.reaction", {
"m.relates_to": {
rel_type: "m.annotation",
event_id: parentID,
key: data.emoji.name
}
}, senderMxid)
"m.relates_to": {
rel_type: "m.annotation",
event_id: parentID,
key: data.emoji.name
}
}, senderMxid)
return eventID
}

View File

@ -52,10 +52,10 @@ async function withWebhook(channelID, callback) {
* @param {string} [threadID]
*/
async function sendMessageWithWebhook(channelID, data, threadID) {
const result = await withWebhook(channelID, async webhook => {
return discord.snow.webhook.executeWebhook(webhook.id, webhook.token, data, {wait: true, thread_id: threadID, disableEveryone: true})
})
return result
const result = await withWebhook(channelID, async webhook => {
return discord.snow.webhook.executeWebhook(webhook.id, webhook.token, data, {wait: true, thread_id: threadID, disableEveryone: true})
})
return result
}
module.exports.ensureWebhook = ensureWebhook

View File

@ -12,7 +12,7 @@ const eventToMessage = sync.require("../converters/event-to-message")
/** @param {import("../../types").Event.Outer<any>} 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
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 threadID = undefined
@ -21,16 +21,16 @@ async function sendEvent(event) {
channelID = row.thread_parent // it's the thread's parent... get with the times...
}
// 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 messages = eventToMessage.eventToMessage(event)
assert(Array.isArray(messages)) // sanity
assert(Array.isArray(messages)) // sanity
/** @type {DiscordTypes.APIMessage[]} */
/** @type {DiscordTypes.APIMessage[]} */
const messageResponses = []
let eventPart = 0 // 0 is primary, 1 is supporting
for (const message of messages) {
const messageResponse = await channelWebhook.sendMessageWithWebhook(channelID, message, threadID)
const messageResponse = await channelWebhook.sendMessageWithWebhook(channelID, message, threadID)
db.prepare("INSERT INTO event_message (event_id, event_type, event_subtype, message_id, channel_id, part, source) VALUES (?, ?, ?, ?, ?, ?, 0)").run(event.event_id, event.type, event.content.msgtype || null, messageResponse.id, channelID, eventPart) // source 0 = matrix
eventPart = 1 // TODO: use more intelligent algorithm to determine whether primary or supporting?

View File

@ -19,15 +19,15 @@ const makeTxnId = sync.require("./txnid")
* @returns {string} the new endpoint
*/
function path(p, mxid, otherParams = {}) {
if (!mxid) return p
const u = new URL(p, "http://localhost")
u.searchParams.set("user_id", mxid)
for (const entry of Object.entries(otherParams)) {
if (entry[1] != undefined) {
u.searchParams.set(entry[0], entry[1])
}
}
return u.pathname + "?" + u.searchParams.toString()
if (!mxid) return p
const u = new URL(p, "http://localhost")
u.searchParams.set("user_id", mxid)
for (const entry of Object.entries(otherParams)) {
if (entry[1] != undefined) {
u.searchParams.set(entry[0], entry[1])
}
}
return u.pathname + "?" + u.searchParams.toString()
}
/**
@ -35,40 +35,40 @@ function path(p, mxid, otherParams = {}) {
* @returns {Promise<Ty.R.Registered>}
*/
function register(username) {
console.log(`[api] register: ${username}`)
return mreq.mreq("POST", "/client/v3/register", {
type: "m.login.application_service",
username
})
console.log(`[api] register: ${username}`)
return mreq.mreq("POST", "/client/v3/register", {
type: "m.login.application_service",
username
})
}
/**
* @returns {Promise<string>} room ID
*/
async function createRoom(content) {
console.log(`[api] create room:`, content)
/** @type {Ty.R.RoomCreated} */
const root = await mreq.mreq("POST", "/client/v3/createRoom", content)
return root.room_id
console.log(`[api] create room:`, content)
/** @type {Ty.R.RoomCreated} */
const root = await mreq.mreq("POST", "/client/v3/createRoom", content)
return root.room_id
}
/**
* @returns {Promise<string>} room ID
*/
async function joinRoom(roomIDOrAlias, mxid) {
/** @type {Ty.R.RoomJoined} */
const root = await mreq.mreq("POST", path(`/client/v3/join/${roomIDOrAlias}`, mxid))
return root.room_id
/** @type {Ty.R.RoomJoined} */
const root = await mreq.mreq("POST", path(`/client/v3/join/${roomIDOrAlias}`, mxid))
return root.room_id
}
async function inviteToRoom(roomID, mxidToInvite, mxid) {
await mreq.mreq("POST", path(`/client/v3/rooms/${roomID}/invite`, mxid), {
user_id: mxidToInvite
})
await mreq.mreq("POST", path(`/client/v3/rooms/${roomID}/invite`, mxid), {
user_id: mxidToInvite
})
}
async function leaveRoom(roomID, mxid) {
await mreq.mreq("POST", path(`/client/v3/rooms/${roomID}/leave`, mxid), {})
await mreq.mreq("POST", path(`/client/v3/rooms/${roomID}/leave`, mxid), {})
}
/**
@ -77,9 +77,9 @@ async function leaveRoom(roomID, mxid) {
* @template T
*/
async function getEvent(roomID, eventID) {
/** @type {Ty.Event.Outer<T>} */
const root = await mreq.mreq("GET", `/client/v3/rooms/${roomID}/event/${eventID}`)
return root
/** @type {Ty.Event.Outer<T>} */
const root = await mreq.mreq("GET", `/client/v3/rooms/${roomID}/event/${eventID}`)
return root
}
/**
@ -87,7 +87,17 @@ async function getEvent(roomID, eventID) {
* @returns {Promise<Ty.Event.BaseStateEvent[]>}
*/
function getAllState(roomID) {
return mreq.mreq("GET", `/client/v3/rooms/${roomID}/state`)
return mreq.mreq("GET", `/client/v3/rooms/${roomID}/state`)
}
/**
* @param {string} roomID
* @param {string} type
* @param {string} key
* @returns the *content* of the state event
*/
function getStateEvent(roomID, type, key) {
return mreq.mreq("GET", `/client/v3/rooms/${roomID}/state/${type}/${key}`)
}
/**
@ -96,7 +106,7 @@ function getAllState(roomID) {
* @returns {Promise<{joined: {[mxid: string]: Ty.R.RoomMember}}>}
*/
function getJoinedMembers(roomID) {
return mreq.mreq("GET", `/client/v3/rooms/${roomID}/joined_members`)
return mreq.mreq("GET", `/client/v3/rooms/${roomID}/joined_members`)
}
/**
@ -107,12 +117,12 @@ function getJoinedMembers(roomID) {
* @returns {Promise<string>} event ID
*/
async function sendState(roomID, type, stateKey, content, mxid) {
console.log(`[api] state: ${roomID}: ${type}/${stateKey}`)
assert.ok(type)
assert.ok(typeof stateKey === "string")
/** @type {Ty.R.EventSent} */
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/state/${type}/${stateKey}`, mxid), content)
return root.event_id
console.log(`[api] state: ${roomID}: ${type}/${stateKey}`)
assert.ok(type)
assert.ok(typeof stateKey === "string")
/** @type {Ty.R.EventSent} */
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/state/${type}/${stateKey}`, mxid), content)
return root.event_id
}
/**
@ -123,31 +133,51 @@ async function sendState(roomID, type, stateKey, content, mxid) {
* @param {number} [timestamp] timestamp of the newly created event, in unix milliseconds
*/
async function sendEvent(roomID, type, content, mxid, timestamp) {
console.log(`[api] event ${type} to ${roomID} as ${mxid || "default sim"}`)
/** @type {Ty.R.EventSent} */
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/send/${type}/${makeTxnId.makeTxnId()}`, mxid, {ts: timestamp}), content)
return root.event_id
console.log(`[api] event ${type} to ${roomID} as ${mxid || "default sim"}`)
/** @type {Ty.R.EventSent} */
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/send/${type}/${makeTxnId.makeTxnId()}`, mxid, {ts: timestamp}), content)
return root.event_id
}
/**
* @returns {Promise<string>} room ID
*/
async function redactEvent(roomID, eventID, mxid) {
/** @type {Ty.R.EventRedacted} */
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/redact/${eventID}/${makeTxnId.makeTxnId()}`, mxid), {})
return root.event_id
/** @type {Ty.R.EventRedacted} */
const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/redact/${eventID}/${makeTxnId.makeTxnId()}`, mxid), {})
return root.event_id
}
async function profileSetDisplayname(mxid, displayname) {
await mreq.mreq("PUT", path(`/client/v3/profile/${mxid}/displayname`, mxid), {
displayname
})
await mreq.mreq("PUT", path(`/client/v3/profile/${mxid}/displayname`, mxid), {
displayname
})
}
async function profileSetAvatarUrl(mxid, avatar_url) {
await mreq.mreq("PUT", path(`/client/v3/profile/${mxid}/avatar_url`, mxid), {
avatar_url
})
await mreq.mreq("PUT", path(`/client/v3/profile/${mxid}/avatar_url`, mxid), {
avatar_url
})
}
/**
* Set a user's power level within a room.
* @param {string} roomID
* @param {string} mxid
* @param {number} power
*/
async function setUserPower(roomID, mxid, power) {
// Yes it's this hard https://github.com/matrix-org/matrix-appservice-bridge/blob/2334b0bae28a285a767fe7244dad59f5a5963037/src/components/intent.ts#L352
const powerLevels = await getStateEvent(roomID, "m.room.power_levels", "")
const users = powerLevels.users || {}
if (power != null) {
users[mxid] = power
} else {
delete users[mxid]
}
powerLevels.users = users
await sendState(roomID, "m.room.power_levels", "", powerLevels)
return powerLevels
}
module.exports.path = path
@ -164,3 +194,4 @@ module.exports.sendEvent = sendEvent
module.exports.redactEvent = redactEvent
module.exports.profileSetDisplayname = profileSetDisplayname
module.exports.profileSetAvatarUrl = profileSetAvatarUrl
module.exports.setUserPower = setUserPower

View File

@ -2,22 +2,22 @@ const {kstateToState, stateToKState, diffKState, kstateStripConditionals} = requ
const {test} = require("supertape")
test("kstate strip: strips false conditions", t => {
t.deepEqual(kstateStripConditionals({
a: {$if: false, value: 2},
b: {value: 4}
}), {
b: {value: 4}
})
t.deepEqual(kstateStripConditionals({
a: {$if: false, value: 2},
b: {value: 4}
}), {
b: {value: 4}
})
})
test("kstate strip: keeps true conditions while removing $if", t => {
t.deepEqual(kstateStripConditionals({
a: {$if: true, value: 2},
b: {value: 4}
}), {
a: {value: 2},
b: {value: 4}
})
t.deepEqual(kstateStripConditionals({
a: {$if: true, value: 2},
b: {value: 4}
}), {
a: {value: 2},
b: {value: 4}
})
})
test("kstate2state: general", t => {

View File

@ -2,9 +2,9 @@ const {test} = require("supertape")
const reg = require("./read-registration")
test("reg: has necessary parameters", t => {
const propertiesToCheck = ["sender_localpart", "id", "as_token", "ooye"]
t.deepEqual(
propertiesToCheck.filter(p => p in reg),
propertiesToCheck
)
const propertiesToCheck = ["sender_localpart", "id", "as_token", "ooye"]
t.deepEqual(
propertiesToCheck.filter(p => p in reg),
propertiesToCheck
)
})

View File

@ -18,10 +18,10 @@ passthrough.discord = discord
;(async () => {
await discord.cloud.connect()
console.log("Discord gateway started")
console.log("Discord gateway started")
const f = event => onPacket(discord, event, () => discord.cloud.off("event", f))
discord.cloud.on("event", f)
const f = event => onPacket(discord, event, () => discord.cloud.off("event", f))
discord.cloud.on("event", f)
})()
const expectedGuilds = new Set()
@ -30,29 +30,29 @@ const prepared = db.prepare("UPDATE channel_room SET name = ? WHERE channel_id =
/** @param {DiscordClient} discord */
function onPacket(discord, event, unsubscribe) {
if (event.t === "READY") {
for (const obj of event.d.guilds) {
expectedGuilds.add(obj.id)
}
if (event.t === "READY") {
for (const obj of event.d.guilds) {
expectedGuilds.add(obj.id)
}
} else if (event.t === "GUILD_CREATE") {
expectedGuilds.delete(event.d.id)
} else if (event.t === "GUILD_CREATE") {
expectedGuilds.delete(event.d.id)
// Store the channel.
for (const channel of event.d.channels || []) {
prepared.run(channel.name, channel.id)
}
// Store the channel.
for (const channel of event.d.channels || []) {
prepared.run(channel.name, channel.id)
}
// Checked them all?
if (expectedGuilds.size === 0) {
discord.cloud.disconnect()
unsubscribe()
// Checked them all?
if (expectedGuilds.size === 0) {
discord.cloud.disconnect()
unsubscribe()
// I don't know why node keeps running.
setTimeout(() => {
console.log("Stopping now.")
process.exit()
}, 1500).unref()
}
}
// I don't know why node keeps running.
setTimeout(() => {
console.log("Stopping now.")
process.exit()
}, 1500).unref()
}
}
}

View File

@ -18,13 +18,13 @@ const rows = db.prepare("SELECT event_id, room_id, event_type FROM event_message
const preparedUpdate = db.prepare("UPDATE event_message SET event_type = ?, event_subtype = ? WHERE event_id = ?")
;(async () => {
for (const row of rows) {
if (row.event_type == null) {
const event = await api.getEvent(row.room_id, row.event_id)
const type = event.type
const subtype = event.content.msgtype || null
preparedUpdate.run(type, subtype, row.event_id)
console.log(`Updated ${row.event_id} -> ${type} + ${subtype}`)
}
}
for (const row of rows) {
if (row.event_type == null) {
const event = await api.getEvent(row.room_id, row.event_id)
const type = event.type
const subtype = event.content.msgtype || null
preparedUpdate.run(type, subtype, row.event_id)
console.log(`Updated ${row.event_id} -> ${type} + ${subtype}`)
}
}
})()