1{ config, pkgs, lib, ... }:
2
3with lib;
4
5let
6 cfg = config.services.mautrix-facebook;
7 settingsFormat = pkgs.formats.json {};
8 settingsFile = settingsFormat.generate "mautrix-facebook-config.json" cfg.settings;
9
10 puppetRegex = concatStringsSep
11 ".*"
12 (map
13 escapeRegex
14 (splitString
15 "{userid}"
16 cfg.settings.bridge.username_template));
17in {
18 options = {
19 services.mautrix-facebook = {
20 enable = mkEnableOption (lib.mdDoc "Mautrix-Facebook, a Matrix-Facebook hybrid puppeting/relaybot bridge");
21
22 settings = mkOption rec {
23 apply = recursiveUpdate default;
24 type = settingsFormat.type;
25 default = {
26 homeserver = {
27 address = "http://localhost:8008";
28 software = "standard";
29 };
30
31 appservice = rec {
32 address = "http://${hostname}:${toString port}";
33 hostname = "localhost";
34 port = 29319;
35
36 database = "postgresql://";
37
38 bot_username = "facebookbot";
39 };
40
41 metrics.enabled = false;
42 manhole.enabled = false;
43
44 bridge = {
45 encryption = {
46 allow = true;
47 default = true;
48
49 verification_levels = {
50 receive = "cross-signed-tofu";
51 send = "cross-signed-tofu";
52 share = "cross-signed-tofu";
53 };
54 };
55 username_template = "facebook_{userid}";
56 };
57
58 logging = {
59 version = 1;
60 formatters.journal_fmt.format = "%(name)s: %(message)s";
61 handlers.journal = {
62 class = "systemd.journal.JournalHandler";
63 formatter = "journal_fmt";
64 SYSLOG_IDENTIFIER = "mautrix-facebook";
65 };
66 root = {
67 level = "INFO";
68 handlers = ["journal"];
69 };
70 };
71 };
72 example = literalExpression ''
73 {
74 homeserver = {
75 address = "http://localhost:8008";
76 domain = "mydomain.example";
77 };
78
79 bridge.permissions = {
80 "@admin:mydomain.example" = "admin";
81 "mydomain.example" = "user";
82 };
83 }
84 '';
85 description = lib.mdDoc ''
86 {file}`config.yaml` configuration as a Nix attribute set.
87 Configuration options should match those described in
88 [example-config.yaml](https://github.com/mautrix/facebook/blob/master/mautrix_facebook/example-config.yaml).
89
90 Secret tokens should be specified using {option}`environmentFile`
91 instead of this world-readable attribute set.
92 '';
93 };
94
95 environmentFile = mkOption {
96 type = types.nullOr types.path;
97 default = null;
98 description = lib.mdDoc ''
99 File containing environment variables to be passed to the mautrix-facebook service.
100
101 Any config variable can be overridden by setting `MAUTRIX_FACEBOOK_SOME_KEY` to override the `some.key` variable.
102 '';
103 };
104
105 configurePostgresql = mkOption {
106 type = types.bool;
107 default = true;
108 description = lib.mdDoc ''
109 Enable PostgreSQL and create a user and database for mautrix-facebook. The default `settings` reference this database, if you disable this option you must provide a database URL.
110 '';
111 };
112
113 registrationData = mkOption {
114 type = types.attrs;
115 default = {};
116 description = lib.mdDoc ''
117 Output data for appservice registration. Simply make any desired changes and serialize to JSON. Note that this data contains secrets so think twice before putting it into the nix store.
118
119 Currently `as_token` and `hs_token` need to be added as they are not known to this module.
120 '';
121 };
122 };
123 };
124
125 config = mkIf cfg.enable {
126 users.groups.mautrix-facebook = {};
127
128 users.users.mautrix-facebook = {
129 group = "mautrix-facebook";
130 isSystemUser = true;
131 };
132
133 services.postgresql = mkIf cfg.configurePostgresql {
134 ensureDatabases = ["mautrix-facebook"];
135 ensureUsers = [{
136 name = "mautrix-facebook";
137 ensurePermissions = {
138 "DATABASE \"mautrix-facebook\"" = "ALL PRIVILEGES";
139 };
140 }];
141 };
142
143 systemd.services.mautrix-facebook = rec {
144 wantedBy = [ "multi-user.target" ];
145 wants = [
146 "network-online.target"
147 ] ++ optional config.services.matrix-synapse.enable "matrix-synapse.service"
148 ++ optional cfg.configurePostgresql "postgresql.service";
149 after = wants;
150
151 serviceConfig = {
152 Type = "simple";
153 Restart = "always";
154
155 User = "mautrix-facebook";
156
157 ProtectSystem = "strict";
158 ProtectHome = true;
159 ProtectKernelTunables = true;
160 ProtectKernelModules = true;
161 ProtectControlGroups = true;
162 PrivateTmp = true;
163
164 EnvironmentFile = cfg.environmentFile;
165
166 ExecStart = ''
167 ${pkgs.mautrix-facebook}/bin/mautrix-facebook --config=${settingsFile}
168 '';
169 };
170 };
171
172 services.mautrix-facebook = {
173 registrationData = {
174 id = "mautrix-facebook";
175
176 namespaces = {
177 users = [
178 {
179 exclusive = true;
180 regex = escapeRegex "@${cfg.settings.appservice.bot_username}:${cfg.settings.homeserver.domain}";
181 }
182 {
183 exclusive = true;
184 regex = "@${puppetRegex}:${escapeRegex cfg.settings.homeserver.domain}";
185 }
186 ];
187 aliases = [];
188 };
189
190 url = cfg.settings.appservice.address;
191 sender_localpart = "mautrix-facebook-sender";
192
193 rate_limited = false;
194 "de.sorunome.msc2409.push_ephemeral" = true;
195 push_ephemeral = true;
196 };
197 };
198 };
199
200 meta.maintainers = with maintainers; [ kevincox ];
201}