forked from cadence/out-of-your-element
		
	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
 | 
			
		||||
package-lock.json
 | 
			
		||||
 | 
			
		||||
/config.js
 | 
			
		||||
node_modules
 | 
			
		||||
config.js
 | 
			
		||||
registration.yaml
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 * @returns {import("../../types").M_Room_Message_content}
 | 
			
		||||
 */
 | 
			
		||||
module.exports = function(message) {
 | 
			
		||||
module.exports = function messageToEvent(message) {
 | 
			
		||||
	const body = message.content
 | 
			
		||||
	const html = markdown.toHTML(body, {
 | 
			
		||||
		discordCallback: {
 | 
			
		||||
		/* discordCallback: {
 | 
			
		||||
			user: Function,
 | 
			
		||||
			channel: Function,
 | 
			
		||||
			role: Function,
 | 
			
		||||
			everyone: Function,
 | 
			
		||||
			here: Function
 | 
			
		||||
		}
 | 
			
		||||
		} */
 | 
			
		||||
	}, null, null)
 | 
			
		||||
	return {
 | 
			
		||||
		msgtype: "m.text",
 | 
			
		||||
		body: body,
 | 
			
		||||
		format: "m.custom.html",
 | 
			
		||||
		format: "org.matrix.custom.html",
 | 
			
		||||
		formatted_body: html
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
// @ts-check
 | 
			
		||||
 | 
			
		||||
// Discord library internals type beat
 | 
			
		||||
 | 
			
		||||
const passthrough = require("../passthrough")
 | 
			
		||||
const { sync } = passthrough
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,9 @@
 | 
			
		|||
// @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 = {
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param {import("./discord-client")} client
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +13,7 @@ module.exports = {
 | 
			
		|||
		console.log(message)
 | 
			
		||||
		console.log(message.guild_id)
 | 
			
		||||
		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:
 | 
			
		||||
- discord 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.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,35 @@ There needs to be a way to easily manually trigger something later. For example,
 | 
			
		|||
5. Send attachments.
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
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",
 | 
			
		||||
    "discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#24508e701e91d5a00fa5e773ced874d9ee8c889b",
 | 
			
		||||
    "heatsync": "^2.4.0",
 | 
			
		||||
    "js-yaml": "^4.1.0",
 | 
			
		||||
    "matrix-appservice": "^2.0.0",
 | 
			
		||||
    "matrix-js-sdk": "^24.1.0",
 | 
			
		||||
    "node-fetch": "^2.6.7",
 | 
			
		||||
    "snowtransfer": "^0.7.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…
	
	Add table
		Add a link
		
	
		Reference in a new issue