Merge pull request #246842 from frederictobiasc/mautrix-whatsapp-module

nixos/mautrix-whatsapp: init
This commit is contained in:
Nick Cao 2023-08-06 03:21:25 -06:00 committed by GitHub
commit 90c77d8891
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 201 additions and 0 deletions

View file

@ -18,6 +18,8 @@
- [wayfire](https://wayfire.org), A modular and extensible wayland compositor. Available as [programs.wayfire](#opt-programs.wayfire.enable).
- [mautrix-whatsapp](https://docs.mau.fi/bridges/go/whatsapp/index.html) A Matrix-WhatsApp puppeting bridge
- [GoToSocial](https://gotosocial.org/), an ActivityPub social network server, written in Golang. Available as [services.gotosocial](#opt-services.gotosocial.enable).
- [Typesense](https://github.com/typesense/typesense), a fast, typo-tolerant search engine for building delightful search experiences. Available as [services.typesense](#opt-services.typesense.enable).

View file

@ -600,6 +600,7 @@
./services/matrix/dendrite.nix
./services/matrix/mautrix-facebook.nix
./services/matrix/mautrix-telegram.nix
./services/matrix/mautrix-whatsapp.nix
./services/matrix/mjolnir.nix
./services/matrix/mx-puppet-discord.nix
./services/matrix/pantalaimon.nix

View file

@ -0,0 +1,198 @@
{
lib,
config,
pkgs,
...
}: let
cfg = config.services.mautrix-whatsapp;
dataDir = "/var/lib/mautrix-whatsapp";
registrationFile = "${dataDir}/whatsapp-registration.yaml";
settingsFile = "${dataDir}/config.json";
settingsFileUnsubstituted = settingsFormat.generate "mautrix-whatsapp-config-unsubstituted.json" cfg.settings;
settingsFormat = pkgs.formats.json {};
appservicePort = 29318;
in {
imports = [];
options.services.mautrix-whatsapp = {
enable = lib.mkEnableOption "mautrix-whatsapp, a puppeting/relaybot bridge between Matrix and WhatsApp.";
settings = lib.mkOption {
type = settingsFormat.type;
default = {
appservice = {
address = "http://localhost:${toString appservicePort}";
hostname = "[::]";
port = appservicePort;
database = {
type = "sqlite3";
uri = "${dataDir}/mautrix-whatsapp.db";
};
id = "whatsapp";
bot = {
username = "whatsappbot";
displayname = "WhatsApp Bridge Bot";
};
as_token = "";
hs_token = "";
};
bridge = {
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;
};
logging = {
min_level = "info";
writers = [
{
type = "stdout";
format = "pretty-colored";
}
{
type = "file";
format = "json";
}
];
};
};
description = lib.mdDoc ''
{file}`config.yaml` configuration as a Nix attribute set.
Configuration options should match those described in
[example-config.yaml](https://github.com/mautrix/whatsapp/blob/master/example-config.yaml).
Secret tokens should be specified using {option}`environmentFile`
instead of this world-readable attribute set.
'';
example = {
appservice = {
database = {
type = "postgres";
uri = "postgresql:///mautrix_whatsapp?host=/run/postgresql";
};
id = "whatsapp";
ephemeral_events = false;
};
bridge = {
history_sync = {
request_full_sync = true;
};
private_chat_portal_meta = true;
mute_bridging = true;
encryption = {
allow = true;
default = true;
require = true;
};
provisioning = {
shared_secret = "disable";
};
permissions = {
"example.com" = "user";
};
};
};
};
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = lib.mdDoc ''
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
`MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET`.
'';
};
serviceDependencies = lib.mkOption {
type = with lib.types; listOf str;
default = lib.optional config.services.matrix-synapse.enable "matrix-synapse.service";
defaultText = lib.literalExpression ''
optional config.services.matrix-synapse.enable "matrix-synapse.service"
'';
description = lib.mdDoc ''
List of Systemd services to require and wait for when starting the application service.
'';
};
};
config = lib.mkIf cfg.enable {
services.mautrix-whatsapp.settings = {
homeserver.domain = lib.mkDefault config.services.matrix-synapse.settings.server_name;
};
systemd.services.mautrix-whatsapp = {
description = "Mautrix-WhatsApp Service - A WhatsApp bridge for Matrix";
wantedBy = ["multi-user.target"];
wants = ["network-online.target"] ++ cfg.serviceDependencies;
after = ["network-online.target"] ++ cfg.serviceDependencies;
preStart = ''
# substitute the settings file by environment variables
# in this case read from EnvironmentFile
test -f '${settingsFile}' && rm -f '${settingsFile}'
old_umask=$(umask)
umask 0177
${pkgs.envsubst}/bin/envsubst \
-o '${settingsFile}' \
-i '${settingsFileUnsubstituted}'
umask $old_umask
# generate the appservice's registration file if absent
if [ ! -f '${registrationFile}' ]; then
${pkgs.mautrix-whatsapp}/bin/mautrix-whatsapp \
--generate-registration \
--config='${settingsFile}' \
--registration='${registrationFile}'
fi
chmod 640 ${registrationFile}
umask 0177
${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token
| .[0].appservice.hs_token = .[1].hs_token
| .[0]' '${settingsFile}' '${registrationFile}' \
> '${settingsFile}.tmp'
mv '${settingsFile}.tmp' '${settingsFile}'
umask $old_umask
'';
serviceConfig = {
DynamicUser = true;
EnvironmentFile = cfg.environmentFile;
StateDirectory = baseNameOf dataDir;
WorkingDirectory = "${dataDir}";
ExecStart = ''
${pkgs.mautrix-whatsapp}/bin/mautrix-whatsapp \
--config='${settingsFile}' \
--registration='${registrationFile}'
'';
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
Restart = "on-failure";
RestartSec = "30s";
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
SystemCallFilter = ["@system-service"];
Type = "simple";
UMask = 0027;
};
restartTriggers = [settingsFileUnsubstituted];
};
};
meta.maintainers = with lib.maintainers; [frederictobiasc];
}