nixos/mautrix-whatsapp: adapt to new config file format

This commit is contained in:
Kabbone 2025-06-28 10:40:53 +02:00 committed by Sandro Jäckel
parent 6e5554c44c
commit 65a1a7985a
No known key found for this signature in database
GPG Key ID: 3AF5A43A3EECC2E5

View File

@ -8,34 +8,55 @@ let
cfg = config.services.mautrix-whatsapp; cfg = config.services.mautrix-whatsapp;
dataDir = "/var/lib/mautrix-whatsapp"; dataDir = "/var/lib/mautrix-whatsapp";
registrationFile = "${dataDir}/whatsapp-registration.yaml"; registrationFile = "${dataDir}/whatsapp-registration.yaml";
settingsFile = "${dataDir}/config.json"; settingsFile = "${dataDir}/config.yaml";
settingsFileUnsubstituted = settingsFormat.generate "mautrix-whatsapp-config-unsubstituted.json" cfg.settings; settingsFileUnsubstituted = settingsFormat.generate "mautrix-whatsapp-config-unsubstituted.json" cfg.settings;
settingsFormat = pkgs.formats.json { }; settingsFormat = pkgs.formats.json { };
appservicePort = 29318; appservicePort = 29318;
# to be used with a list of lib.mkIf values
optOneOf = lib.lists.findFirst (value: value.condition) (lib.mkIf false null);
mkDefaults = lib.mapAttrsRecursive (n: v: lib.mkDefault v); mkDefaults = lib.mapAttrsRecursive (n: v: lib.mkDefault v);
defaultConfig = { defaultConfig = {
network = {
displayname_template = "{{or .BusinessName .PushName .Phone}} (WA)";
identity_change_notices = true;
history_sync = {
request_full_sync = true;
};
};
bridge = {
command_prefix = "!wa";
relay.enabled = true;
permissions."*" = "relay";
};
database = {
type = "sqlite3-fk-wal";
uri = "file:${dataDir}/mautrix-whatsapp.db?_txlock=immediate";
};
homeserver.address = "http://localhost:8448"; homeserver.address = "http://localhost:8448";
appservice = { appservice = {
hostname = "[::]"; hostname = "[::]";
port = appservicePort; port = appservicePort;
database.type = "sqlite3";
database.uri = "${dataDir}/mautrix-whatsapp.db";
id = "whatsapp"; id = "whatsapp";
bot.username = "whatsappbot"; bot = {
bot.displayname = "WhatsApp Bridge Bot"; username = "whatsappbot";
displayname = "WhatsApp Bridge Bot";
};
as_token = ""; as_token = "";
hs_token = ""; hs_token = "";
};
bridge = {
username_template = "whatsapp_{{.}}"; username_template = "whatsapp_{{.}}";
displayname_template = "{{if .BusinessName}}{{.BusinessName}}{{else if .PushName}}{{.PushName}}{{else}}{{.JID}}{{end}} (WA)";
double_puppet_server_map = { };
login_shared_secret_map = { };
command_prefix = "!wa";
permissions."*" = "relay";
relay.enabled = true;
}; };
double_puppet = {
servers = { };
secrets = { };
};
# By default, the following keys/secrets are set to `generate`. This would break when the service
# is restarted, since the previously generated configuration will be overwritten everytime.
# If encryption is enabled, it's recommended to set those keys via `environmentFile`.
encryption.pickle_key = "";
provisioning.shared_secret = "";
public_media.signing_key = "";
direct_media.server_key = "";
logging = { logging = {
min_level = "info"; min_level = "info";
writers = lib.singleton { writers = lib.singleton {
@ -49,65 +70,78 @@ let
in in
{ {
options.services.mautrix-whatsapp = { options.services.mautrix-whatsapp = {
enable = lib.mkEnableOption "mautrix-whatsapp, a puppeting/relaybot bridge between Matrix and WhatsApp"; enable = lib.mkEnableOption "mautrix-whatsapp, a Matrix-WhatsApp puppeting bridge";
package = lib.mkPackageOption pkgs "mautrix-whatsapp" { }; package = lib.mkPackageOption pkgs "mautrix-whatsapp" { };
settings = lib.mkOption { settings = lib.mkOption {
apply = lib.recursiveUpdate defaultConfig;
type = settingsFormat.type; type = settingsFormat.type;
default = defaultConfig; default = defaultConfig;
description = '' description = ''
{file}`config.yaml` configuration as a Nix attribute set. {file}`config.yaml` configuration as a Nix attribute set.
Configuration options should match those described in Configuration options should match those described in the example configuration.
[example-config.yaml](https://github.com/mautrix/whatsapp/blob/master/example-config.yaml). Get an example configuration by executing `mautrix-whatsapp -c example.yaml --generate-example-config`
Secret tokens should be specified using {option}`environmentFile` Secret tokens should be specified using {option}`environmentFile`
instead of this world-readable attribute set. instead of this world-readable attribute set.
''; '';
example = { example = {
appservice = {
database = {
type = "postgres";
uri = "postgresql:///mautrix_whatsapp?host=/run/postgresql";
};
id = "whatsapp";
ephemeral_events = false;
};
bridge = { bridge = {
history_sync = {
request_full_sync = true;
};
private_chat_portal_meta = true; private_chat_portal_meta = true;
mute_bridging = true; mute_only_on_create = false;
encryption = {
allow = true;
default = true;
require = true;
};
provisioning = {
shared_secret = "disable";
};
permissions = { permissions = {
"example.com" = "user"; "example.com" = "user";
}; };
}; };
database = {
type = "postgres";
uri = "postgresql:///mautrix_whatsapp?host=/run/postgresql";
};
homeserver = {
address = "http://[::1]:8008";
domain = "my-domain.tld";
};
appservice = {
id = "whatsapp";
ephemeral_events = false;
};
matrix.message_status_events = true;
provisioning = {
shared_secret = "disable";
};
backfill.enabled = true;
encryption = {
allow = true;
default = true;
require = true;
pickle_key = "$ENCRYPTION_PICKLE_KEY";
};
}; };
}; };
environmentFile = lib.mkOption { environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path; type = lib.types.nullOr lib.types.path;
default = null; default = null;
description = '' description = ''
File containing environment variables to be passed to the mautrix-whatsapp service, File containing environment variables to be passed to the mautrix-whatsapp service.
in which secret tokens can be specified securely by optionally defining a value for If an environment variable `MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET` is set,
`MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET`. then its value will be used in the configuration file for the option
`double_puppet.secrets` without leaking it to the store, using the configured
`homeserver.domain` as key.
''; '';
}; };
serviceDependencies = lib.mkOption { serviceDependencies = lib.mkOption {
type = with lib.types; listOf str; type = with lib.types; listOf str;
default = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit; default =
defaultText = lib.literalExpression "lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnits"; lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
++ lib.optional config.services.matrix-conduit.enable "conduit.service";
defaultText = lib.literalExpression ''
optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
++ optional config.services.matrix-conduit.enable "conduit.service"
'';
description = '' description = ''
List of Systemd services to require and wait for when starting the application service. List of systemd units to require and wait for when starting the application service.
''; '';
}; };
@ -140,20 +174,28 @@ in
serviceConfig.SupplementaryGroups = [ "mautrix-whatsapp" ]; serviceConfig.SupplementaryGroups = [ "mautrix-whatsapp" ];
}; };
services.mautrix-whatsapp.settings = lib.mkMerge ( # Note: this is defined here to avoid the docs depending on `config`
map mkDefaults [ services.mautrix-whatsapp.settings.homeserver = optOneOf (
defaultConfig with config.services;
# Note: this is defined here to avoid the docs depending on `config` [
{ homeserver.domain = config.services.matrix-synapse.settings.server_name; } (lib.mkIf matrix-synapse.enable (mkDefaults {
domain = matrix-synapse.settings.server_name;
}))
(lib.mkIf matrix-conduit.enable (mkDefaults {
domain = matrix-conduit.settings.global.server_name;
address = "http://localhost:${toString matrix-conduit.settings.global.port}";
}))
] ]
); );
systemd.services.mautrix-whatsapp = { systemd.services.mautrix-whatsapp = {
description = "Mautrix-WhatsApp Service - A WhatsApp bridge for Matrix"; description = "Mautrix-WhatsApp, a Matrix-WhatsApp puppeting bridge";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ] ++ cfg.serviceDependencies; wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
after = [ "network-online.target" ] ++ cfg.serviceDependencies; after = [ "network-online.target" ] ++ cfg.serviceDependencies;
# ffmpeg is required for conversion of voice messages
path = [ pkgs.ffmpeg-headless ];
preStart = '' preStart = ''
# substitute the settings file by environment variables # substitute the settings file by environment variables
@ -183,7 +225,7 @@ in
${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token ${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token
| .[0].appservice.hs_token = .[1].hs_token | .[0].appservice.hs_token = .[1].hs_token
| .[0] | .[0]
| if env.MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET then .bridge.login_shared_secret_map.[.homeserver.domain] = env.MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET else . end' \ | if env.MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET then .double_puppet.secrets.[.homeserver.domain] = env.MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET else . end' \
'${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp' '${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp'
mv '${settingsFile}.tmp' '${settingsFile}' mv '${settingsFile}.tmp' '${settingsFile}'
umask $old_umask umask $old_umask
@ -201,7 +243,6 @@ in
--registration='${registrationFile}' --registration='${registrationFile}'
''; '';
LockPersonality = true; LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true; NoNewPrivileges = true;
PrivateDevices = true; PrivateDevices = true;
PrivateTmp = true; PrivateTmp = true;
@ -227,5 +268,12 @@ in
restartTriggers = [ settingsFileUnsubstituted ]; restartTriggers = [ settingsFileUnsubstituted ];
}; };
}; };
meta.maintainers = with lib.maintainers; [ frederictobiasc ]; meta = {
buildDocsInSandbox = false;
doc = ./mautrix-whatsapp.md;
maintainers = with lib.maintainers; [
pentane
frederictobiasc
];
};
} }