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 id = "facebook";
33 address = "http://${hostname}:${toString port}";
34 hostname = "localhost";
35 port = 29319;
36
37 database = "postgresql://";
38
39 bot_username = "facebookbot";
40 };
41
42 metrics.enabled = false;
43 manhole.enabled = false;
44
45 bridge = {
46 encryption = {
47 allow = true;
48 default = true;
49
50 verification_levels = {
51 receive = "cross-signed-tofu";
52 send = "cross-signed-tofu";
53 share = "cross-signed-tofu";
54 };
55 };
56 username_template = "facebook_{userid}";
57 };
58
59 logging = {
60 version = 1;
61 formatters.journal_fmt.format = "%(name)s: %(message)s";
62 handlers.journal = {
63 class = "systemd.journal.JournalHandler";
64 formatter = "journal_fmt";
65 SYSLOG_IDENTIFIER = "mautrix-facebook";
66 };
67 root = {
68 level = "INFO";
69 handlers = ["journal"];
70 };
71 };
72 };
73 example = literalExpression ''
74 {
75 homeserver = {
76 address = "http://localhost:8008";
77 domain = "mydomain.example";
78 };
79
80 bridge.permissions = {
81 "@admin:mydomain.example" = "admin";
82 "mydomain.example" = "user";
83 };
84 }
85 '';
86 description = lib.mdDoc ''
87 {file}`config.yaml` configuration as a Nix attribute set.
88 Configuration options should match those described in
89 [example-config.yaml](https://github.com/mautrix/facebook/blob/master/mautrix_facebook/example-config.yaml).
90
91 Secret tokens should be specified using {option}`environmentFile`
92 instead of this world-readable attribute set.
93 '';
94 };
95
96 environmentFile = mkOption {
97 type = types.nullOr types.path;
98 default = null;
99 description = lib.mdDoc ''
100 File containing environment variables to be passed to the mautrix-facebook service.
101
102 Any config variable can be overridden by setting `MAUTRIX_FACEBOOK_SOME_KEY` to override the `some.key` variable.
103 '';
104 };
105
106 configurePostgresql = mkOption {
107 type = types.bool;
108 default = true;
109 description = lib.mdDoc ''
110 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.
111 '';
112 };
113
114 registrationData = mkOption {
115 type = types.attrs;
116 default = {};
117 description = lib.mdDoc ''
118 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.
119
120 Currently `as_token` and `hs_token` need to be added as they are not known to this module.
121 '';
122 };
123 };
124 };
125
126 config = mkIf cfg.enable {
127 users.groups.mautrix-facebook = {};
128
129 users.users.mautrix-facebook = {
130 group = "mautrix-facebook";
131 isSystemUser = true;
132 };
133
134 services.postgresql = mkIf cfg.configurePostgresql {
135 ensureDatabases = ["mautrix-facebook"];
136 ensureUsers = [{
137 name = "mautrix-facebook";
138 ensureDBOwnership = true;
139 }];
140 };
141
142 systemd.services.mautrix-facebook = rec {
143 wantedBy = [ "multi-user.target" ];
144 wants = [
145 "network-online.target"
146 ] ++ optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
147 ++ optional cfg.configurePostgresql "postgresql.service";
148 after = wants;
149
150 serviceConfig = {
151 Type = "simple";
152 Restart = "always";
153
154 User = "mautrix-facebook";
155
156 ProtectSystem = "strict";
157 ProtectHome = true;
158 ProtectKernelTunables = true;
159 ProtectKernelModules = true;
160 ProtectControlGroups = true;
161 PrivateTmp = true;
162
163 EnvironmentFile = cfg.environmentFile;
164
165 ExecStart = ''
166 ${pkgs.mautrix-facebook}/bin/mautrix-facebook --config=${settingsFile}
167 '';
168 };
169 };
170
171 services.mautrix-facebook = {
172 registrationData = {
173 id = cfg.settings.appservice.id;
174
175 namespaces = {
176 users = [
177 {
178 exclusive = true;
179 regex = escapeRegex "@${cfg.settings.appservice.bot_username}:${cfg.settings.homeserver.domain}";
180 }
181 {
182 exclusive = true;
183 regex = "@${puppetRegex}:${escapeRegex cfg.settings.homeserver.domain}";
184 }
185 ];
186 aliases = [];
187 };
188
189 url = cfg.settings.appservice.address;
190 sender_localpart = "mautrix-facebook-sender";
191
192 rate_limited = false;
193 "de.sorunome.msc2409.push_ephemeral" = true;
194 push_ephemeral = true;
195 };
196 };
197 };
198
199 meta.maintainers = with maintainers; [ kevincox ];
200}