1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 cfg = config.services.matrix-hookshot;
9 settingsFormat = pkgs.formats.yaml { };
10 configFile = settingsFormat.generate "matrix-hookshot-config.yml" cfg.settings;
11in
12{
13 options = {
14 services.matrix-hookshot = {
15 enable = lib.mkEnableOption "matrix-hookshot, a bridge between Matrix and project management services";
16
17 package = lib.mkPackageOption pkgs "matrix-hookshot" { };
18
19 registrationFile = lib.mkOption {
20 type = lib.types.path;
21 description = ''
22 Appservice registration file.
23 As it contains secret tokens, you may not want to add this to the publicly readable Nix store.
24 '';
25 example = lib.literalExpression ''
26 pkgs.writeText "matrix-hookshot-registration" \'\'
27 id: matrix-hookshot
28 as_token: aaaaaaaaaa
29 hs_token: aaaaaaaaaa
30 namespaces:
31 rooms: []
32 users:
33 - regex: "@_webhooks_.*:foobar"
34 exclusive: true
35
36 sender_localpart: hookshot
37 url: "http://localhost:9993"
38 rate_limited: false
39 \'\'
40 '';
41 };
42
43 settings = lib.mkOption {
44 description = ''
45 {file}`config.yml` configuration as a Nix attribute set.
46
47 For details please see the [documentation](https://matrix-org.github.io/matrix-hookshot/latest/setup/sample-configuration.html).
48 '';
49 example = {
50 bridge = {
51 domain = "example.com";
52 url = "http://localhost:8008";
53 mediaUrl = "https://example.com";
54 port = 9993;
55 bindAddress = "127.0.0.1";
56 };
57 listeners = [
58 {
59 port = 9000;
60 bindAddress = "0.0.0.0";
61 resources = [ "webhooks" ];
62 }
63 {
64 port = 9001;
65 bindAddress = "localhost";
66 resources = [
67 "metrics"
68 "provisioning"
69 ];
70 }
71 ];
72 };
73 default = { };
74 type = lib.types.submodule {
75 freeformType = settingsFormat.type;
76 options = {
77 passFile = lib.mkOption {
78 type = lib.types.path;
79 default = "/var/lib/matrix-hookshot/passkey.pem";
80 description = ''
81 A passkey used to encrypt tokens stored inside the bridge.
82 File will be generated if not found.
83 '';
84 };
85 };
86 };
87 };
88
89 serviceDependencies = lib.mkOption {
90 type = with lib.types; listOf str;
91 default = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
92 defaultText = lib.literalExpression ''
93 lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
94 '';
95 description = ''
96 List of Systemd services to require and wait for when starting the application service,
97 such as the Matrix homeserver if it's running on the same host.
98 '';
99 };
100 };
101 };
102
103 config = lib.mkIf cfg.enable {
104 systemd.services.matrix-hookshot = {
105 description = "a bridge between Matrix and multiple project management services";
106
107 wantedBy = [ "multi-user.target" ];
108 wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
109 after = [ "network-online.target" ] ++ cfg.serviceDependencies;
110
111 preStart = ''
112 if [ ! -f '${cfg.settings.passFile}' ]; then
113 mkdir -p $(dirname '${cfg.settings.passFile}')
114 ${pkgs.openssl}/bin/openssl genpkey -out '${cfg.settings.passFile}' -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:4096
115 fi
116 '';
117
118 serviceConfig = {
119 Type = "simple";
120 Restart = "always";
121 ExecStart = "${cfg.package}/bin/matrix-hookshot ${configFile} ${cfg.registrationFile}";
122 };
123 };
124 };
125
126 meta.maintainers = with lib.maintainers; [ flandweber ];
127}