{ config, secrets, ... }: let conduitCfg = config.services.matrix-conduit.settings.global; serverName = "c8h4.io"; matrixHost = "matrix.${serverName}"; webhookListener = { bindAddress = "::1"; port = 9000; resources = [ "webhooks" ]; }; in { sops.secrets = builtins.listToAttrs (map (n: { name = "matrix-hookshot/${n}"; value = { sopsFile = ../secrets/sops/matrix-hookshot.yaml; owner = config.services.matrix-hookshot.user; restartUnits = [ "matrix-hookshot.service" ]; }; }) [ "env" "passfile" ]); services.matrix-hookshot = { enable = true; environmentFile = secrets."matrix-hookshot/env".path; settings = { passFile = secrets."matrix-hookshot/passfile".path; bridge = { bindAddress = "::1"; domain = conduitCfg.server_name; url = "http://[${conduitCfg.address}]:${toString conduitCfg.port}"; }; permissions."@c8h4:${serverName}".services."*".level = "admin"; listeners = [ webhookListener ]; generic = { enabled = true; urlPrefix = "https://${matrixHost}/webhooks/"; waitForComplete = true; userIdPrefix = "_webhook_"; allowJsTransformationFunctions = true; }; }; namespaces = { users = [{ regex = "@_webhook_.*:${serverName}"; exclusive = true; }]; }; }; services.nginx.virtualHosts.${matrixHost} = let webhookUpstream = "[${webhookListener.bindAddress}]:${toString webhookListener.port}"; in { forceSSL = true; useACMEHost = serverName; kTLS = true; locations."~ ^/webhooks/(.*)" = { proxyPass = "http://${webhookUpstream}/webhook/$1"; proxyWebsockets = true; extraConfig = '' proxy_set_header Host $host; proxy_hide_header X-Powered-By; ''; }; }; }