sending events in matrix
This commit is contained in:
parent
6990957c9e
commit
8a0c2b5663
13 changed files with 2764 additions and 10 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,4 +1,3 @@
|
||||||
/node_modules
|
node_modules
|
||||||
package-lock.json
|
config.js
|
||||||
|
registration.yaml
|
||||||
/config.js
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const reg = require("../../matrix/read-registration.js")
|
||||||
|
const fetch = require("node-fetch")
|
||||||
|
|
||||||
|
fetch("https://matrix.cadence.moe/_matrix/client/v3/createRoom?user_id=@_ooye_example:cadence.moe", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
invite: ["@cadence:cadence.moe"],
|
||||||
|
is_direct: false,
|
||||||
|
name: "New Bot User Room",
|
||||||
|
preset: "trusted_private_chat"
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${reg.as_token}`
|
||||||
|
}
|
||||||
|
}).then(res => res.text()).then(text => {
|
||||||
|
// {"room_id":"!aAVaqeAKwChjWbsywj:cadence.moe"}
|
||||||
|
console.log(text)
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
20
d2m/actions/register-user.js
Normal file
20
d2m/actions/register-user.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const reg = require("../../matrix/read-registration.js")
|
||||||
|
const fetch = require("node-fetch")
|
||||||
|
|
||||||
|
fetch("https://matrix.cadence.moe/_matrix/client/v3/register", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: "m.login.application_service",
|
||||||
|
username: "_ooye_example"
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${reg.as_token}`
|
||||||
|
}
|
||||||
|
}).then(res => res.text()).then(text => {
|
||||||
|
// {"user_id":"@_ooye_example:cadence.moe","home_server":"cadence.moe","access_token":"XXX","device_id":"XXX"}
|
||||||
|
console.log(text)
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
27
d2m/actions/send-message.js
Normal file
27
d2m/actions/send-message.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const reg = require("../../matrix/read-registration.js")
|
||||||
|
const makeTxnId = require("../../matrix/txnid.js")
|
||||||
|
const fetch = require("node-fetch")
|
||||||
|
const messageToEvent = require("../converters/message-to-event.js")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
|
||||||
|
*/
|
||||||
|
function sendMessage(message) {
|
||||||
|
const event = messageToEvent(message)
|
||||||
|
fetch(`https://matrix.cadence.moe/_matrix/client/v3/rooms/!VwVlIAjOjejUpDhlbA:cadence.moe/send/m.room.message/${makeTxnId()}?user_id=@_ooye_example:cadence.moe`, {
|
||||||
|
method: "PUT",
|
||||||
|
body: JSON.stringify(event),
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${reg.as_token}`
|
||||||
|
}
|
||||||
|
}).then(res => res.text()).then(text => {
|
||||||
|
// {"event_id":"$4Zxs0fMmYlbo-sTlMmSEvwIs9b4hcg6yORzK0Ems84Q"}
|
||||||
|
console.log(text)
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = sendMessage
|
|
@ -6,21 +6,21 @@ const markdown = require("discord-markdown")
|
||||||
* @param {import("discord-api-types/v10").APIMessage} message
|
* @param {import("discord-api-types/v10").APIMessage} message
|
||||||
* @returns {import("../../types").M_Room_Message_content}
|
* @returns {import("../../types").M_Room_Message_content}
|
||||||
*/
|
*/
|
||||||
module.exports = function(message) {
|
module.exports = function messageToEvent(message) {
|
||||||
const body = message.content
|
const body = message.content
|
||||||
const html = markdown.toHTML(body, {
|
const html = markdown.toHTML(body, {
|
||||||
discordCallback: {
|
/* discordCallback: {
|
||||||
user: Function,
|
user: Function,
|
||||||
channel: Function,
|
channel: Function,
|
||||||
role: Function,
|
role: Function,
|
||||||
everyone: Function,
|
everyone: Function,
|
||||||
here: Function
|
here: Function
|
||||||
}
|
} */
|
||||||
}, null, null)
|
}, null, null)
|
||||||
return {
|
return {
|
||||||
msgtype: "m.text",
|
msgtype: "m.text",
|
||||||
body: body,
|
body: body,
|
||||||
format: "m.custom.html",
|
format: "org.matrix.custom.html",
|
||||||
formatted_body: html
|
formatted_body: html
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
|
// Discord library internals type beat
|
||||||
|
|
||||||
const passthrough = require("../passthrough")
|
const passthrough = require("../passthrough")
|
||||||
const { sync } = passthrough
|
const { sync } = passthrough
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
|
// Grab Discord events we care about for the bridge, check them, and pass them on
|
||||||
|
|
||||||
|
const sendMessage = require("./actions/send-message")
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
/**
|
||||||
* @param {import("./discord-client")} client
|
* @param {import("./discord-client")} client
|
||||||
|
@ -9,7 +13,7 @@ module.exports = {
|
||||||
console.log(message)
|
console.log(message)
|
||||||
console.log(message.guild_id)
|
console.log(message.guild_id)
|
||||||
console.log(message.member)
|
console.log(message.member)
|
||||||
return {}
|
sendMessage(message)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
4
matrix/read-registration.js
Normal file
4
matrix/read-registration.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
const fs = require("fs")
|
||||||
|
const yaml = require("js-yaml")
|
||||||
|
|
||||||
|
module.exports = yaml.load(fs.readFileSync("registration.yaml", "utf8"))
|
7
matrix/txnid.js
Normal file
7
matrix/txnid.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
let now = Date.now()
|
||||||
|
|
||||||
|
module.exports = function makeTxnId() {
|
||||||
|
return now++
|
||||||
|
}
|
31
notes.md
31
notes.md
|
@ -5,7 +5,7 @@ Remember that a discord message may be transformed to multiple matrix messages.
|
||||||
A database will be used to store the discord id to matrix event id mapping. Table columns:
|
A database will be used to store the discord id to matrix event id mapping. Table columns:
|
||||||
- discord id
|
- discord id
|
||||||
- matrix id
|
- matrix id
|
||||||
- the "type" of the matrix id, used to update things properly next time. for example, whether it is the message text or an attachment
|
- the "type" of the matrix id, used to update things properly next time. for example, whether it is the message text or an attachment. alternatively, whether it is a primary or supporting event for the discord message, primary being message content and supporting being embeds or attachments or etc.
|
||||||
|
|
||||||
There needs to be a way to easily manually trigger something later. For example, it should be easy to manually retry sending a message, or check all members for changes, etc.
|
There needs to be a way to easily manually trigger something later. For example, it should be easy to manually retry sending a message, or check all members for changes, etc.
|
||||||
|
|
||||||
|
@ -22,6 +22,35 @@ There needs to be a way to easily manually trigger something later. For example,
|
||||||
5. Send attachments.
|
5. Send attachments.
|
||||||
6. Store in database.
|
6. Store in database.
|
||||||
|
|
||||||
|
## Discord's permissions in spaces
|
||||||
|
|
||||||
|
### The space itself
|
||||||
|
|
||||||
|
Discord guilds are invite only, so the corresponding **space** should initially be set to:
|
||||||
|
|
||||||
|
- Find & join access: Invite only
|
||||||
|
- Preview space: Yes
|
||||||
|
|
||||||
|
Public channels in that server should then use the following settings, so that they can be opened by anyone who was successfully invited to the space:
|
||||||
|
|
||||||
|
- Find & join access: Space members (so users must have been invited to the space already, even if they find out the room ID to join)
|
||||||
|
- Who can read history: Anyone (so that people can see messages during the preview before joining)
|
||||||
|
|
||||||
|
### Private channels
|
||||||
|
|
||||||
|
Discord **channels** that disallow view permission to @everyone should instead have the following **room** settings in Matrix:
|
||||||
|
|
||||||
|
- Find & join access: Private (so space members cannot join without an additional invitation)
|
||||||
|
- Who can read history: Anyone (XXX: is this safe??? is this a fishbowl situation? https://github.com/matrix-org/synapse/issues/9202)
|
||||||
|
|
||||||
|
### Discord experience
|
||||||
|
|
||||||
|
To add an initial Matrix user to the **space**, a Discord member would use /invite @cadence:cadence.moe in any channel. If this member has create invite permissions, then the bridge bot should send a Matrix invite to the **space** for @cadence:cadence.moe.
|
||||||
|
|
||||||
|
Not yet sure how access to private **channels** would be granted to individual Matrix users. Maybe somebody with Manage Server can use another invite command?
|
||||||
|
|
||||||
|
# d2m events
|
||||||
|
|
||||||
## Message sent
|
## Message sent
|
||||||
|
|
||||||
1. Transform content.
|
1. Transform content.
|
||||||
|
|
2616
package-lock.json
generated
Normal file
2616
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -19,8 +19,10 @@
|
||||||
"cloudstorm": "^0.7.0",
|
"cloudstorm": "^0.7.0",
|
||||||
"discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#24508e701e91d5a00fa5e773ced874d9ee8c889b",
|
"discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#24508e701e91d5a00fa5e773ced874d9ee8c889b",
|
||||||
"heatsync": "^2.4.0",
|
"heatsync": "^2.4.0",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
"matrix-appservice": "^2.0.0",
|
"matrix-appservice": "^2.0.0",
|
||||||
"matrix-js-sdk": "^24.1.0",
|
"matrix-js-sdk": "^24.1.0",
|
||||||
|
"node-fetch": "^2.6.7",
|
||||||
"snowtransfer": "^0.7.0",
|
"snowtransfer": "^0.7.0",
|
||||||
"supertape": "^8.3.0"
|
"supertape": "^8.3.0"
|
||||||
},
|
},
|
||||||
|
|
22
scripts/register.js
Normal file
22
scripts/register.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const { AppServiceRegistration } = require("matrix-appservice");
|
||||||
|
|
||||||
|
let id = AppServiceRegistration.generateToken()
|
||||||
|
try {
|
||||||
|
const reg = require("../matrix/read-registration")
|
||||||
|
if (reg.id) id = reg.id
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// creating registration files
|
||||||
|
const newReg = new AppServiceRegistration(null);
|
||||||
|
newReg.setAppServiceUrl("http://localhost:6693");
|
||||||
|
newReg.setId(id);
|
||||||
|
newReg.setHomeserverToken(AppServiceRegistration.generateToken());
|
||||||
|
newReg.setAppServiceToken(AppServiceRegistration.generateToken());
|
||||||
|
newReg.setSenderLocalpart("_ooye_bot");
|
||||||
|
newReg.addRegexPattern("users", "@_ooye_.*", true);
|
||||||
|
newReg.addRegexPattern("aliases", "#_ooye_.*", true);
|
||||||
|
newReg.setProtocols(["discord"]); // For 3PID lookups
|
||||||
|
newReg.setRateLimited(false);
|
||||||
|
newReg.outputAsYaml("registration.yaml");
|
Loading…
Reference in a new issue