Compare commits
1 Commits
main
...
improved-b
Author | SHA1 | Date |
---|---|---|
Henrik Kjernmoen Gran | b0ac3ea19c |
|
@ -2,7 +2,7 @@
|
|||
<p>Doorbell bot for matrix</p>
|
||||
<p>The bot will only respond & join in authorized rooms (add authorized room IDs in `config.json` => `rooms`).
|
||||
NOTE: The bot needs to have the room authorized before being invited. If the bot is invited, then has the room authorized in the config, it <b>will not</b> join!</p>
|
||||
<p>The commands to trigger the doorbell is: "doorbell", "open", "ring", "knock", "ding", "dong" & "dingdong"</p>
|
||||
<p>The commands to trigger the doorbell are defined in the config file</p>
|
||||
|
||||
# How to run:
|
||||
## Step 1: Getting an access token
|
||||
|
@ -20,6 +20,7 @@ NOTE: The bot needs to have the room authorized before being invited. If the bot
|
|||
- Fill in: `homeserver` (`config.json`) (This should already be filled if step `1.1` was done)
|
||||
- Fill in: `token` (`config.json`) (This is the token you got in step `1.2`)
|
||||
- Fill in: `prefix` (`config.json`)
|
||||
- Fill in: `commands` (`config.json`) (Commands are case insensitive, and should not include the prefix)
|
||||
- Fill in: `rooms` (`config.json`)
|
||||
- Fill in: `doorbellWebhook` (`config.json`)
|
||||
### Step 2.2: Actually running the bot
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"homeserver": "HOME_SERVER",
|
||||
"token": "ACCESS_TOKEN",
|
||||
"prefix": "BOT_PREFIX",
|
||||
"commands": ["COMMAND1", "COMMAND2"],
|
||||
"rooms": ["AUTHORIZED_ROOM_ID", "ANOTHER_AUTHORIZED_ID"],
|
||||
"doorbellWebhook": "https://GOOGLE.ASSISTANT.WEBHOOK.URL/"
|
||||
}
|
18
flake.nix
18
flake.nix
|
@ -23,23 +23,19 @@
|
|||
src = lib.fileset.toSource {
|
||||
root = ./.;
|
||||
fileset = lib.fileset.difference ./. (lib.fileset.unions [
|
||||
./module.nix
|
||||
./flake.lock
|
||||
./flake.nix
|
||||
./flake.lock
|
||||
]);
|
||||
};
|
||||
npmDepsHash = "sha256-518ln/eAlgnKcubOTquBP8gj9Q/lT5bhpJGWOeuUKmY=";
|
||||
npmDepsHash = "sha256-UNc902yMkoWfpun1RrLYlEtOXcFd7uxlwKFWoM0/nTE=";
|
||||
|
||||
postInstall = ''
|
||||
ln -vs /run/secrets/pvv-doorbell-config.json $out/lib/node_modules/$pname/config.json
|
||||
'';
|
||||
dontNpmBuild = true;
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
overlays = forAllSystems (system: {
|
||||
default = prevPackages: finalPackages: {
|
||||
pvv-doorbell-bot = self.packages.${system}.default;
|
||||
};
|
||||
});
|
||||
|
||||
nixosModules.default = import ./module.nix;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
24
index.mjs
24
index.mjs
|
@ -7,13 +7,12 @@ import {
|
|||
|
||||
import axios from "axios";
|
||||
|
||||
import { env } from 'node:process';
|
||||
|
||||
const config = await import (env.DOORBELL_CONFIG_FILE || "./config.json"); // assert {type: "json"};
|
||||
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;
|
||||
|
||||
|
@ -24,9 +23,12 @@ function configNotFound(name) {
|
|||
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.
|
||||
|
@ -50,6 +52,12 @@ client.on("room.invite", (roomId) => {
|
|||
// 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)
|
||||
|
@ -71,16 +79,16 @@ async function handleCommand(roomId, event) {
|
|||
if (!rawText || !rawText.startsWith(prefix)) return;
|
||||
const text = rawText.substring(prefix.length);
|
||||
|
||||
if (["doorbell", "open", "ring", "knock", "ding", "dong", "dingdong"].includes(text)) {
|
||||
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 {
|
||||
console.log("No ding dong :(");
|
||||
console.log(response);
|
||||
noDingDong(client, roomId, event, response);
|
||||
}
|
||||
});
|
||||
}).catch(err => noDingDong(client, roomId, event, err));
|
||||
}
|
||||
|
||||
var tags = [];
|
||||
|
@ -132,4 +140,4 @@ async function handleCommand(roomId, event) {
|
|||
};
|
||||
|
||||
client.sendMessage(roomId, event);
|
||||
}
|
||||
}
|
61
module.nix
61
module.nix
|
@ -1,61 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.pvv-doorbell-bot;
|
||||
inherit (lib) mkDefault mkEnableOption mkPackageOption mkIf mkOption types mdDoc;
|
||||
in
|
||||
{
|
||||
options.services.pvv-doorbell-bot = {
|
||||
enable = mkEnableOption (lib.mdDoc "Enable the doorbell service that alerts on matrix/discord pings");
|
||||
|
||||
package = mkPackageOption pkgs "pvv-doorbell-bot" { };
|
||||
nodePackage = mkPackageOption pkgs "nodejs_20" { };
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "pvv-doorbell-bot";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "pvv-doorbell-bot";
|
||||
};
|
||||
|
||||
settings = {
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
description = mdDoc "Path to secret config.json file that sets the options defined in `config.json.template`";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users = mkIf (cfg.user == "pvv-doorbell-bot") {
|
||||
pvv-doorbell-bot = {
|
||||
description = "PVV Doorbell Matrix Bot User";
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.group == "pvv-doorbell-bot") {
|
||||
pvv-doorbell-bot = { };
|
||||
};
|
||||
|
||||
systemd.services."pvv-doorbell-bot" = {
|
||||
serviceConfig = let
|
||||
appDir = "${cfg.package}/lib/node_modules/doorbell-matrix-bot";
|
||||
in {
|
||||
ExecStart = "${lib.getExe cfg.nodePackage} ${appDir}/index.mjs";
|
||||
WorkingDirectory = appDir;
|
||||
RuntimeDirectory = "pvv-doorbell-bot";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
};
|
||||
|
||||
environment = {
|
||||
DOORBELL_CONFIG_FILE = cfg.settings.configFile;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,6 @@
|
|||
"author": "henrkgr",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.7.4",
|
||||
"matrix-bot-sdk": "^0.7.1"
|
||||
"axios": "^1.7.4"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue