{ config, pkgs, lib, ... }: with lib; let cfg = config.services.mautrix-slack; dataDir = "/var/lib/mautrix-slack"; registrationFile = "${dataDir}/slack-registration.yaml"; settingsFormat = pkgs.formats.json { }; settingsFile = settingsFormat.generate "mautrix-slack-config.json" cfg.settings; in { options = { services.mautrix-slack = { enable = mkEnableOption (lib.mdDoc "Mautrix-Slack, a Matrix-Slack hybrid puppeting/relaybot bridge"); package = mkOption { type = types.package; default = pkgs.callPackage ./pkgs/mautrix-slack.nix { }; defaultText = "pkgs.mautrix-slack"; example = "pkgs.mautrix-slack.override { … = …; }"; description = lib.mdDoc '' Package of the application to run, exposed for overriding purposes. ''; }; settings = mkOption rec { apply = recursiveUpdate default; type = settingsFormat.type; default = { homeserver = { software = "standard"; }; appservice = rec { address = "http://${hostname}:${toString port}"; hostname = "localhost"; port = 29319; database = { type = "postgres"; uri = "postgres:///mautrix-slack?host=/run/postgresql&sslmode=disable"; }; id = "slack"; bot = { username = "slackbot"; }; # backfill = { # enable = false; # conversations_count = 200; # unread_hours_threshold = 720; # immediate_messages = 10; # incremental = { # messages_per_batch = 100; # post_batch_delay = 20; # max_messages = { # channel = -1; # group_dm = -1; # dm = -1; # }; # }; # }; # encryption = { # allow = false; # default = false; # appservice = false; # require = false; # allow_key_sharing = false; # verification_levels = { # receive = "unverified"; # send = "unverified"; # share = "cross-signed-tofu"; # }; # rotation = { # enable_custom = false; # milliseconds = 604800000; # messages = 100; # }; # }; # provisioning = { # prefix = "/_matrix/provision"; # shared_secret = "generate"; # }; }; logging = { directory = "/var/log/mautrix"; file_name_format = "slack-{{.Date}}-{{.Index}}.log"; file_date_format = "2006-01-02"; file_mode = 384; timestamp_format = "Jan _2, 2006 15:04:05"; print_level = "debug"; print_json = false; file_json = false; }; }; }; environmentFile = mkOption { type = types.nullOr types.path; default = null; description = lib.mdDoc '' File containing environment variables to be passed to the mautrix-slack service. Any config variable can be overridden by setting `MAUTRIX_SLACK_SOME_KEY` to override the `some.key` variable. ''; }; configurePostgresql = mkOption { type = types.bool; default = true; description = lib.mdDoc '' Enable PostgreSQL and create a user and database for mautrix-slack. The default `settings` reference this database, if you disable this option you must provide a database URL. ''; }; }; }; config = mkIf cfg.enable { users.groups.mautrix-slack = { }; users.users.mautrix-slack = { group = "mautrix-slack"; isSystemUser = true; }; services.postgresql = mkIf cfg.configurePostgresql { enable = true; ensureDatabases = [ "mautrix-slack" ]; ensureUsers = [{ name = "mautrix-slack"; # ensurePermissions = { # "DATABASE \"mautrix-slack\"" = "ALL PRIVILEGES"; # }; }]; }; systemd.services.mautrix-slack = rec { wantedBy = [ "multi-user.target" ]; wants = [ "network-online.target" ] ++ optional config.services.matrix-synapse.enable "matrix-synapse.service" ++ optional cfg.configurePostgresql "postgresql.service"; after = wants; preStart = '' # generate the appservice's registration file if absent if [ ! -f '${registrationFile}' ]; then ${cfg.package}/bin/mautrix-slack -g -c ${settingsFile} \ -r ${registrationFile} fi ''; serviceConfig = { Type = "simple"; Restart = "always"; User = "mautrix-slack"; NoNewPrivileges = true; MemoryDenyWriteExecute = true; PrivateDevices = true; PrivateTmp = true; ProtectHome = true; ProtectSystem = "strict"; ProtectControlGroups = true; RestrictSUIDSGID = true; RestrictRealtime = true; LockPersonality = true; ProtectKernelLogs = true; ProtectKernelTunables = true; ProtectHostname = true; ProtectKernelModules = true; PrivateUsers = true; ProtectClock = true; SystemCallArchitectures = "native"; SystemCallErrorNumber = "EPERM"; SystemCallFilter = "@system-service"; StateDirectory = baseNameOf dataDir; LogsDirectory = "mautrix"; LogsDirectoryMode = "0750"; EnvironmentFile = cfg.environmentFile; ExecStart = '' ${cfg.package}/bin/mautrix-slack --no-update --config=${settingsFile} --registration=${registrationFile} ''; }; }; }; }