base16-schemes: unstable-2024-06-21 -> unstable-2024-11-12
[NixPkgs.git] / nixos / modules / services / matrix / mautrix-telegram.nix
blob16a4046e1d3ae2259b6e7654686c9a2c8818a5c0
1 { config, pkgs, lib, ... }:
2 let
3   dataDir = "/var/lib/mautrix-telegram";
4   registrationFile = "${dataDir}/telegram-registration.yaml";
5   cfg = config.services.mautrix-telegram;
6   settingsFormat = pkgs.formats.json {};
7   settingsFile =
8     settingsFormat.generate "mautrix-telegram-config.json" cfg.settings;
10 in {
11   options = {
12     services.mautrix-telegram = {
13       enable = lib.mkEnableOption "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge";
15       settings = lib.mkOption rec {
16         apply = lib.recursiveUpdate default;
17         inherit (settingsFormat) type;
18         default = {
19           homeserver = {
20             software = "standard";
21           };
23           appservice = rec {
24             database = "sqlite:///${dataDir}/mautrix-telegram.db";
25             database_opts = {};
26             hostname = "0.0.0.0";
27             port = 8080;
28             address = "http://localhost:${toString port}";
29           };
31           bridge = {
32             permissions."*" = "relaybot";
33             relaybot.whitelist = [ ];
34             double_puppet_server_map = {};
35             login_shared_secret_map = {};
36           };
38           logging = {
39             version = 1;
41             formatters.precise.format = "[%(levelname)s@%(name)s] %(message)s";
43             handlers.console = {
44               class = "logging.StreamHandler";
45               formatter = "precise";
46             };
48             loggers = {
49               mau.level = "INFO";
50               telethon.level = "INFO";
52               # prevent tokens from leaking in the logs:
53               # https://github.com/tulir/mautrix-telegram/issues/351
54               aiohttp.level = "WARNING";
55             };
57             # log to console/systemd instead of file
58             root = {
59               level = "INFO";
60               handlers = [ "console" ];
61             };
62           };
63         };
64         example = lib.literalExpression ''
65           {
66             homeserver = {
67               address = "http://localhost:8008";
68               domain = "public-domain.tld";
69             };
71             appservice.public = {
72               prefix = "/public";
73               external = "https://public-appservice-address/public";
74             };
76             bridge.permissions = {
77               "example.com" = "full";
78               "@admin:example.com" = "admin";
79             };
80             telegram = {
81               connection.use_ipv6 = true;
82             };
83           }
84         '';
85         description = ''
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/telegram/blob/master/mautrix_telegram/example-config.yaml).
90           Secret tokens should be specified using {option}`environmentFile`
91           instead of this world-readable attribute set.
92         '';
93       };
95       environmentFile = lib.mkOption {
96         type = lib.types.nullOr lib.types.path;
97         default = null;
98         description = ''
99           File containing environment variables to be passed to the mautrix-telegram service,
100           in which secret tokens can be specified securely by defining values for e.g.
101           `MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN`,
102           `MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN`,
103           `MAUTRIX_TELEGRAM_TELEGRAM_API_ID`,
104           `MAUTRIX_TELEGRAM_TELEGRAM_API_HASH` and optionally
105           `MAUTRIX_TELEGRAM_TELEGRAM_BOT_TOKEN`.
107           These environment variables can also be used to set other options by
108           replacing hierarchy levels by `.`, converting the name to uppercase
109           and prepending `MAUTRIX_TELEGRAM_`.
110           For example, the first value above maps to
111           {option}`settings.appservice.as_token`.
113           The environment variable values can be prefixed with `json::` to have
114           them be parsed as JSON. For example, `login_shared_secret_map` can be
115           set as follows:
116           `MAUTRIX_TELEGRAM_BRIDGE_LOGIN_SHARED_SECRET_MAP=json::{"example.com":"secret"}`.
117         '';
118       };
120       serviceDependencies = lib.mkOption {
121         type = with lib.types; listOf str;
122         default = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
123         defaultText = lib.literalExpression ''
124           lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
125         '';
126         description = ''
127           List of Systemd services to require and wait for when starting the application service.
128         '';
129       };
130     };
131   };
133   config = lib.mkIf cfg.enable {
134     systemd.services.mautrix-telegram = {
135       description = "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge.";
137       wantedBy = [ "multi-user.target" ];
138       wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
139       after = [ "network-online.target" ] ++ cfg.serviceDependencies;
140       path = [ pkgs.lottieconverter pkgs.ffmpeg-full ];
142       # mautrix-telegram tries to generate a dotfile in the home directory of
143       # the running user if using a postgresql database:
144       #
145       #  File "python3.10/site-packages/asyncpg/connect_utils.py", line 257, in _dot_postgre>
146       #    return (pathlib.Path.home() / '.postgresql' / filename).resolve()
147       #  File "python3.10/pathlib.py", line 1000, in home
148       #    return cls("~").expanduser()
149       #  File "python3.10/pathlib.py", line 1440, in expanduser
150       #    raise RuntimeError("Could not determine home directory.")
151       # RuntimeError: Could not determine home directory.
152       environment.HOME = dataDir;
154       preStart = ''
155         # generate the appservice's registration file if absent
156         if [ ! -f '${registrationFile}' ]; then
157           ${pkgs.mautrix-telegram}/bin/mautrix-telegram \
158             --generate-registration \
159             --config='${settingsFile}' \
160             --registration='${registrationFile}'
161         fi
162       '' + lib.optionalString (pkgs.mautrix-telegram ? alembic) ''
163         # run automatic database init and migration scripts
164         ${pkgs.mautrix-telegram.alembic}/bin/alembic -x config='${settingsFile}' upgrade head
165       '';
167       serviceConfig = {
168         Type = "simple";
169         Restart = "always";
171         ProtectSystem = "strict";
172         ProtectHome = true;
173         ProtectKernelTunables = true;
174         ProtectKernelModules = true;
175         ProtectControlGroups = true;
177         DynamicUser = true;
178         PrivateTmp = true;
179         WorkingDirectory = pkgs.mautrix-telegram; # necessary for the database migration scripts to be found
180         StateDirectory = baseNameOf dataDir;
181         UMask = "0027";
182         EnvironmentFile = cfg.environmentFile;
184         ExecStart = ''
185           ${pkgs.mautrix-telegram}/bin/mautrix-telegram \
186             --config='${settingsFile}'
187         '';
188       };
189     };
190   };
192   meta.maintainers = with lib.maintainers; [ pacien vskilet ];