initial with Discord
This commit is contained in:
commit
acfeab68e6
7 changed files with 142 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/node_modules
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
/config.js
|
3
config.example.js
Normal file
3
config.example.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
discordToken: "yes"
|
||||||
|
}
|
39
index.js
Normal file
39
index.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
const repl = require("repl")
|
||||||
|
const util = require("util")
|
||||||
|
|
||||||
|
const DiscordClient = require("./modules/DiscordClient")
|
||||||
|
|
||||||
|
const config = require("./config")
|
||||||
|
|
||||||
|
const discord = new DiscordClient(config.discordToken)
|
||||||
|
|
||||||
|
discord.cloud.connect().then(() => console.log("Discord gateway started"))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {import("vm").Context} _context
|
||||||
|
* @param {string} _filename
|
||||||
|
* @param {(err: Error | null, result: unknown) => unknown} callback
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function customEval(input, _context, _filename, callback) {
|
||||||
|
let depth = 0
|
||||||
|
if (input === "exit\n") return process.exit()
|
||||||
|
if (input.startsWith(":")) {
|
||||||
|
const depthOverwrite = input.split(" ")[0]
|
||||||
|
depth = +depthOverwrite.slice(1)
|
||||||
|
input = input.slice(depthOverwrite.length + 1)
|
||||||
|
}
|
||||||
|
/** @type {unknown} */
|
||||||
|
let result
|
||||||
|
try {
|
||||||
|
result = await eval(input)
|
||||||
|
const output = util.inspect(result, false, depth, true)
|
||||||
|
return callback(null, output)
|
||||||
|
} catch (e) {
|
||||||
|
return callback(e, undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cli = repl.start({ prompt: "", eval: customEval, writer: s => s })
|
||||||
|
cli.once("exit", process.exit)
|
63
modules/DiscordClient.js
Normal file
63
modules/DiscordClient.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
const { SnowTransfer } = require("snowtransfer")
|
||||||
|
const { Client: CloudStorm } = require("cloudstorm")
|
||||||
|
|
||||||
|
let wasReadyBefore = false
|
||||||
|
|
||||||
|
class DiscordClient {
|
||||||
|
/**
|
||||||
|
* @param {string} discordToken
|
||||||
|
*/
|
||||||
|
constructor(discordToken) {
|
||||||
|
this.discordToken = discordToken
|
||||||
|
this.snow = new SnowTransfer(discordToken)
|
||||||
|
this.cloud = new CloudStorm(discordToken, {
|
||||||
|
shards: "auto",
|
||||||
|
reconnect: true,
|
||||||
|
snowtransferInstance: this.snow,
|
||||||
|
intents: [
|
||||||
|
"DIRECT_MESSAGES", "DIRECT_MESSAGE_REACTIONS", "DIRECT_MESSAGE_TYPING",
|
||||||
|
"GUILDS", "GUILD_EMOJIS_AND_STICKERS", "GUILD_MESSAGES", "GUILD_MESSAGE_REACTIONS", "GUILD_MESSAGE_TYPING", "GUILD_WEBHOOKS",
|
||||||
|
"MESSAGE_CONTENT"
|
||||||
|
],
|
||||||
|
ws: {
|
||||||
|
compress: false,
|
||||||
|
encoding: "json"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/** @type {import("discord-typings").User | null} */
|
||||||
|
this.user = null
|
||||||
|
/** @type {import("discord-typings").Application | null} */
|
||||||
|
this.application = null
|
||||||
|
/** @type {Map<string, import("discord-typings").Channel>} */
|
||||||
|
this.channels = new Map()
|
||||||
|
this.cloud.on("event", this.onPacket.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("cloudstorm").IGatewayMessage} message
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
onPacket(message) {
|
||||||
|
if (message.t === "READY") {
|
||||||
|
if (wasReadyBefore) return
|
||||||
|
/** @type {import("discord-typings").ReadyPayload} */
|
||||||
|
const typed = message.d
|
||||||
|
this.user = typed.user
|
||||||
|
this.application = typed.application
|
||||||
|
console.log(`Discord logged in as ${this.user.username}#${this.user.discriminator} (${this.user.id})`)
|
||||||
|
} else if (message.t === "GUILD_CREATE") {
|
||||||
|
/** @type {import("discord-typings").Guild} */
|
||||||
|
const typed = message.d
|
||||||
|
for (const channel of typed.channels || []) {
|
||||||
|
this.channels.set(channel.id, channel)
|
||||||
|
}
|
||||||
|
} else if (message.t === "CHANNEL_CREATE" || message.t === "CHANNEL_DELETE") {
|
||||||
|
/** @type {import("discord-typings").Channel} */
|
||||||
|
const typed = message.d
|
||||||
|
if (message.t === "CHANNEL_CREATE") this.channels.set(typed.id, typed)
|
||||||
|
else this.channels.delete(typed.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DiscordClient
|
11
modules/DiscordEvents.js
Normal file
11
modules/DiscordEvents.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Process Discord messages and convert to a message Matrix can understand
|
||||||
|
*
|
||||||
|
* @param {import("discord-typings").Message} message
|
||||||
|
* @returns {import("../types").MatrixMessage}
|
||||||
|
*/
|
||||||
|
onMessageCreate: message => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
21
package.json
Normal file
21
package.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "out-of-your-element",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A bridge between Matrix and Discord",
|
||||||
|
"main": "index.js",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@ssh.gitdab.com:cadence/out-of-your-element.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"matrix",
|
||||||
|
"discord",
|
||||||
|
"bridge"
|
||||||
|
],
|
||||||
|
"author": "Cadence, PapiOphidian",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cloudstorm": "^0.6.1",
|
||||||
|
"snowtransfer": "^0.6.1"
|
||||||
|
}
|
||||||
|
}
|
1
types.d.ts
vendored
Normal file
1
types.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export type MatrixMessage = {}
|
Loading…
Reference in a new issue