glue
This commit is contained in:
parent
6e55e6d1b3
commit
3578ca28b5
5 changed files with 94 additions and 28 deletions
|
@ -1,6 +1,7 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const assert = require("assert").strict
|
const assert = require("assert").strict
|
||||||
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {discord, db} = passthrough
|
const {discord, db} = passthrough
|
||||||
|
|
||||||
|
@ -46,5 +47,17 @@ async function withWebhook(channelID, callback) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} channelID
|
||||||
|
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]}[]} data
|
||||||
|
*/
|
||||||
|
async function sendMessageWithWebhook(channelID, data) {
|
||||||
|
const result = await withWebhook(channelID, async webhook => {
|
||||||
|
return discord.snow.webhook.executeWebhook(webhook.id, webhook.token, data, {wait: true, disableEveryone: true})
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.ensureWebhook = ensureWebhook
|
module.exports.ensureWebhook = ensureWebhook
|
||||||
module.exports.withWebhook = withWebhook
|
module.exports.withWebhook = withWebhook
|
||||||
|
module.exports.sendMessageWithWebhook = sendMessageWithWebhook
|
43
m2d/actions/send-event.js
Normal file
43
m2d/actions/send-event.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const assert = require("assert").strict
|
||||||
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
|
const passthrough = require("../../passthrough")
|
||||||
|
const {sync, discord, db} = passthrough
|
||||||
|
|
||||||
|
/** @type {import("./channel-webhook")} */
|
||||||
|
const channelWebhook = sync.require("./channel-webhook")
|
||||||
|
/** @type {import("../converters/event-to-message")} */
|
||||||
|
const eventToMessage = sync.require("../converters/event-to-message")
|
||||||
|
|
||||||
|
/** @param {import("../../types").Event.Outer<any>} event */
|
||||||
|
async function sendEvent(event) {
|
||||||
|
// TODO: matrix equivalents...
|
||||||
|
const roomID = await createRoom.ensureRoom(message.channel_id)
|
||||||
|
// TODO: no need to sync the member to the other side... right?
|
||||||
|
let senderMxid = null
|
||||||
|
if (!message.webhook_id) {
|
||||||
|
assert(message.member)
|
||||||
|
senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
|
||||||
|
await registerUser.syncUser(message.author, message.member, message.guild_id, roomID)
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = eventToMessage.eventToMessage(event)
|
||||||
|
assert(Array.isArray(messages))
|
||||||
|
|
||||||
|
/** @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)
|
||||||
|
// TODO: are you sure about that? many to many? and we don't need to store which side it originated from?
|
||||||
|
db.prepare("INSERT INTO event_message (event_id, message_id, part) VALUES (?, ?, ?)").run(event.event_id, messageResponse.id, eventPart)
|
||||||
|
|
||||||
|
eventPart = 1 // TODO: use more intelligent algorithm to determine whether primary or supporting
|
||||||
|
messageResponses.push(messageResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
return messageResponses
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.sendEvent = sendEvent
|
|
@ -1,23 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
const assert = require("assert").strict
|
|
||||||
const DiscordTypes = require("discord-api-types/v10")
|
|
||||||
const passthrough = require("../../passthrough")
|
|
||||||
const {sync, discord, db} = passthrough
|
|
||||||
|
|
||||||
/** @type {import("./register-webhook")} */
|
|
||||||
const registerWebhook = sync.require("./register-webhook")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} channelID
|
|
||||||
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]}[]} data
|
|
||||||
*/
|
|
||||||
// param {DiscordTypes.RESTPostAPIWebhookWithTokenQuery & {wait: true, disableEveryone?: boolean}} options
|
|
||||||
async function sendMessage(channelID, data) {
|
|
||||||
const result = await registerWebhook.withWebhook(channelID, async webhook => {
|
|
||||||
return discord.snow.webhook.executeWebhook(webhook.id, webhook.token, data, {wait: true, disableEveryone: true})
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.sendMessage = sendMessage
|
|
|
@ -1,12 +1,37 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grab Matrix events we care about, check them, and bridge them.
|
||||||
|
*/
|
||||||
|
|
||||||
const assert = require("assert").strict
|
const assert = require("assert").strict
|
||||||
const {sync, as} = require("../passthrough")
|
const {sync, as} = require("../passthrough")
|
||||||
|
const reg = require("../matrix/read-registration")
|
||||||
|
/** @type {import("./actions/send-event")} */
|
||||||
|
const sendEvent = sync.require("./actions/send-event")
|
||||||
|
|
||||||
// Grab Matrix events we care about for the bridge, check them, and pass them on
|
const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
|
||||||
|
/**
|
||||||
|
* Determine whether an event is the bridged representation of a discord message.
|
||||||
|
* Such messages shouldn't be bridged again.
|
||||||
|
* @param {import("../types").Event.Outer<any>} event
|
||||||
|
*/
|
||||||
|
function eventOriginatedFromDiscord(event) {
|
||||||
|
if (
|
||||||
|
// If it's from a user in the bridge's namespace...
|
||||||
|
userRegex.some(x => event.sender.match(x))
|
||||||
|
// ...not counting the appservice's own user...
|
||||||
|
&& !event.sender.startsWith(`@${reg.sender_localpart}:`)
|
||||||
|
) {
|
||||||
|
// ...then it originated from discord
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
sync.addTemporaryListener(as, "type:m.room.message", event => {
|
sync.addTemporaryListener(as, "type:m.room.message", event => {
|
||||||
console.log(event)
|
console.log(event)
|
||||||
// TODO: filter out events that were bridged discord messages (i.e. sent by OOYE)
|
if (eventOriginatedFromDiscord(event)) return
|
||||||
// TODO: call sendMessage
|
const messageResponses = sendEvent.sendEvent(event)
|
||||||
})
|
})
|
||||||
|
|
12
types.d.ts
vendored
12
types.d.ts
vendored
|
@ -5,6 +5,16 @@ export type AppServiceRegistrationConfig = {
|
||||||
url: string
|
url: string
|
||||||
sender_localpart: string
|
sender_localpart: string
|
||||||
namespace_prefix: string
|
namespace_prefix: string
|
||||||
|
namespaces: {
|
||||||
|
users: {
|
||||||
|
exclusive: boolean
|
||||||
|
regex: string
|
||||||
|
}[]
|
||||||
|
aliases: {
|
||||||
|
exclusive: boolean
|
||||||
|
regex: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
protocols: [string]
|
protocols: [string]
|
||||||
rate_limited: boolean
|
rate_limited: boolean
|
||||||
}
|
}
|
||||||
|
@ -23,8 +33,6 @@ namespace Event {
|
||||||
origin_server_ts: number
|
origin_server_ts: number
|
||||||
unsigned: any
|
unsigned: any
|
||||||
event_id: string
|
event_id: string
|
||||||
user_id: string
|
|
||||||
age: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BaseStateEvent = {
|
export type BaseStateEvent = {
|
||||||
|
|
Loading…
Reference in a new issue