{ config, lib, pkgs, ... }: let cfg = config.services.matrix-ops-bot; defaultMatrixOpsBotPackage = if builtins.hasAttr "matrix-ops-bot" pkgs then pkgs."matrix-ops-bot" else null; in { options.services.matrix-ops-bot = { enable = lib.mkEnableOption "matrix-ops-bot webhook daemon"; package = lib.mkOption { type = lib.types.nullOr lib.types.package; default = defaultMatrixOpsBotPackage; description = "Package that provides matrix-ops-bot."; }; stateDirectory = lib.mkOption { type = lib.types.str; default = "matrix-ops-bot"; description = "StateDirectory name for persistent service state under /var/lib."; }; configFile = lib.mkOption { type = lib.types.str; default = "/etc/matrix-ops-bot/config.json"; description = "Source file loaded into systemd credentials as config.json."; }; envFile = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Optional source env file loaded into systemd credentials as bot.env."; }; templateRoot = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Template root directory passed via OPS_BOT_TEMPLATE_ROOT."; }; listenAddress = lib.mkOption { type = lib.types.str; default = "127.0.0.1"; description = "Listen address passed via BOT_LISTEN_HOST."; }; port = lib.mkOption { type = lib.types.port; default = 1111; description = "Listen port passed via BOT_LISTEN_PORT."; }; extraEnvironment = lib.mkOption { type = lib.types.attrsOf lib.types.str; default = { }; description = "Additional environment variables for the service."; }; }; config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.package != null; message = '' services.matrix-ops-bot.package is not set and pkgs.matrix-ops-bot was not found. Configure package explicitly. ''; } ]; systemd.services.matrix-ops-bot = { description = "Matrix Ops Bot webhook daemon"; wantedBy = [ "multi-user.target" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; environment = { BOT_CONFIG_FILE = "%d/config.json"; BOT_LISTEN_HOST = cfg.listenAddress; BOT_LISTEN_PORT = toString cfg.port; OPS_BOT_TEMPLATE_ROOT = if cfg.templateRoot != null then cfg.templateRoot else "${cfg.package}/share/matrix-ops-bot/templates"; } // lib.optionalAttrs (cfg.envFile != null) { BOT_ENV_FILE = "%d/bot.env"; } // cfg.extraEnvironment; serviceConfig = { Type = "simple"; ExecStart = "${cfg.package}/bin/matrix-ops-bot"; DynamicUser = true; StateDirectory = cfg.stateDirectory; WorkingDirectory = "/var/lib/${cfg.stateDirectory}"; LoadCredential = [ "config.json:${cfg.configFile}" ] ++ lib.optionals (cfg.envFile != null) [ "bot.env:${cfg.envFile}" ]; Restart = "on-failure"; RestartSec = "5s"; NoNewPrivileges = true; PrivateTmp = true; ProtectSystem = "strict"; ProtectHome = true; }; }; }; }