import { MatrixClient, SimpleFsStorageProvider, AutojoinUpgradedRoomsMixin, RichRepliesPreprocessor, } from "matrix-bot-sdk"; import axios from "axios"; import config from "./config.json" assert {type: "json"}; const homeserverUrl = config.homeserver; const token = config.token; const prefix = config.prefix; const commandsRaw = config.commands; const rooms = config.rooms; const doorbellWebhook = config.doorbellWebhook; function configNotFound(name) { throw new Error(`ERROR: Config option "${name}" not found`); } if (!homeserverUrl) configNotFound("homeserver"); if (!token) configNotFound("token"); if (!prefix) configNotFound("prefix"); if (!commandsRaw) configNotFound("commands"); if (!rooms) configNotFound("rooms"); if (!doorbellWebhook) configNotFound("doorbellWebhook"); const commands = commandsRaw.map(cmd => cmd.toLowerCase()); // We'll want to make sure the bot doesn't have to do an initial sync every // time it restarts, so we need to prepare a storage provider. Here we use // a simple JSON database. const storage = new SimpleFsStorageProvider("bot-storage.json"); // Now we can create the client and set it up to automatically join rooms. const client = await new MatrixClient(homeserverUrl, token, storage); AutojoinUpgradedRoomsMixin.setupOnClient(client); client.addPreprocessor(new RichRepliesPreprocessor(false)); // We also want to make sure we can receive events - this is where we will // handle our command. client.on("room.message", handleCommand); client.on("room.invite", (roomId) => { if (rooms.includes(roomId)) { return client.joinRoom(roomId); } }); // Now that the client is all set up and the event handler is registered, start the // client up. This will start it syncing. client.start().then(() => console.log("Client started!")); function noDingDong(client, roomId, event, error) { console.log("No ding dong :("); console.log(error); client.replyNotice(roomId, event, "Couldn't dingdong the doorbell :("); } // This is our event handler for dealing with commands. async function handleCommand(roomId, event) { // Don't handle events that don't have contents (they were probably redacted) if (!event["content"]) return; // Don't handle non-text events if (event["content"]["msgtype"] !== "m.text") return; // We never send `m.text` messages so this isn't required, however this is // how you would filter out events sent by the bot itself. if (event["sender"] === await client.getUserId()) return; // Make sure that the event looks like a command we're expecting // If not in any authorized rooms, ignore if (!rooms.includes(roomId)) return; // Check that the message starts with the prefix, and get the prefix-less message const rawText = event["content"]["body"]; if (!rawText || !rawText.startsWith(prefix)) return; const text = rawText.substring(prefix.length); if (commands.some(cmd => text.toLowerCase().startsWith(cmd))) { fetch(doorbellWebhook, { method: 'POST' }).then(response => { if (response.ok) { console.log("DING DONG!"); client.replyNotice(roomId, event, "Doorbell dingdonged!"); } else { noDingDong(client, roomId, event, response); } }).catch(err => noDingDong(client, roomId, event, err)); } var tags = []; var re = /`([a-z1-9:. æøå]*)`/g; do { var m = re.exec(text); if (m) { tags.push(m[1]); } } while (m); if (tags == false) return; var encoded_tags = encodeURI(JSON.stringify(tags)); var file_ids = (await axios.get(hydrusURI + "/get_files/search_files?system_inbox=true&tags=" + encoded_tags, {headers: {'Hydrus-Client-API-Access-Key': hydrusToken}})).data.file_ids; if (file_ids == false) return; console.log(file_ids); var random_id = [file_ids[Math.floor(Math.random() * file_ids.length)]]; var encoded_id = encodeURI(JSON.stringify(random_id)); var metadata = (await axios.get(hydrusURI + "/get_files/file_metadata?&file_ids=" + encoded_id, {headers: {'Hydrus-Client-API-Access-Key': hydrusToken}})).data.metadata[0]; console.log(metadata); var hash = metadata.hash; var width = metadata.width; var height = metadata.height; var mime = metadata.mime; var ext = metadata.ext; var size = metadata.size; var mxc = "mxc://" + fake_hs + "/" + prefix + hash; var event = { "body": hash + ext, "info": { "h": height, "w": width, "mimetype": mime, "size": size, }, "msgtype": "m.image", "url": mxc }; client.sendMessage(roomId, event); }