chipmunkbot3/plugins/matrix.js
2024-08-03 21:20:09 -04:00

109 lines
3.2 KiB
JavaScript

const matrix = require('matrix-js-sdk')
const CommandSource = require('../util/command/command_source')
const htmlStringify = require('../util/chat/stringify/html')
function inject (bot, options) {
if (!options.matrix?.enabled) return
bot.matrix = {
client: options.matrix.client ?? matrix.createClient(options.matrix),
roomId: options.matrix.roomId,
commandPrefix: options.matrix.commandPrefix,
inviteUrl: String(options.matrix.inviteUrl)
}
const startTime = Date.now()
bot.on('chat_html', (html, message) => {
if (!bot.chat.shouldLog(message)) return
sendMessage(html)
})
const matrixPrefix = {
text: 'ChipmunkBot Matrix',
hoverEvent: {
action: 'show_text',
contents: 'Click to copy the invite link for the Matrix space to your clipboard!'
},
clickEvent: {
action: 'copy_to_clipboard', // * Minecraft, and Java's URI class in general, seem to hate `#`, so open_url does not work.
value: bot.matrix.inviteUrl
}
}
bot.matrix.client.on('Room.timeline', (event, room, toStartOfTimeline) => {
if (event.getRoomId() !== bot.matrix.roomId || event.getType() !== 'm.room.message' || event.getTs() < startTime || event.sender.userId === bot.matrix.client.getUserId() || !bot.loggedIn) return
const content = event.getContent()
const permissionLevel = event.sender.powerLevelNorm
let message = content.body
const senderText = {
text: String(event.sender.rawDisplayName || event.sender.name || event.sender.userId),
hoverEvent: {
action: 'show_text',
contents: [String(event.sender.userId), '\nPermission Level: ', String(permissionLevel), '\n\nClick to copy the User ID']
},
clickEvent: {
action: 'copy_to_clipboard',
value: String(event.sender.userId)
}
}
if (content.url) {
message = {
text: '[Attachment]',
...bot.styles.primary,
clickEvent: {
action: 'open_url',
value: bot.matrix.client.mxcUrlToHttp(content.url)
}
}
} else if (message.startsWith(bot.matrix.commandPrefix)) {
const source = new CommandSource({ bot, permissionLevel, sendFeedback, displayName: senderText })
bot.commands.execute(message.substring(bot.matrix.commandPrefix.length), source)
return
}
bot.fancyMsg(matrixPrefix, senderText, message)
})
let dequeuingMessages = false
let queue = []
async function sendMessage (html) {
queue.push(html)
if (dequeuingMessages) return
dequeuingMessages = true
while (queue.length !== 0) {
const html = queue.join('<br>')
queue = []
await _sendMessage(html)
}
dequeuingMessages = false
}
async function _sendMessage (html) {
const content = {
msgtype: 'm.text',
format: 'org.matrix.custom.html',
body: html,
formatted_body: html,
'm.mentions': {}
}
try {
await bot.matrix.client.sendEvent(bot.matrix.roomId, 'm.room.message', content, '')
} catch (error) {
console.error('Unable to send Matrix message:', error)
}
}
function sendFeedback (text, sendFeedback) {
const html = htmlStringify(text, { lang: bot.registry.language })
sendMessage(html)
}
}
module.exports = inject