1 { config, pkgs, lib, ... }:
3 dataDir = "/var/lib/mautrix-telegram";
4 registrationFile = "${dataDir}/telegram-registration.yaml";
5 cfg = config.services.mautrix-telegram;
6 settingsFormat = pkgs.formats.json {};
8 settingsFormat.generate "mautrix-telegram-config.json" cfg.settings;
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;
20 software = "standard";
24 database = "sqlite:///${dataDir}/mautrix-telegram.db";
28 address = "http://localhost:${toString port}";
32 permissions."*" = "relaybot";
33 relaybot.whitelist = [ ];
34 double_puppet_server_map = {};
35 login_shared_secret_map = {};
41 formatters.precise.format = "[%(levelname)s@%(name)s] %(message)s";
44 class = "logging.StreamHandler";
45 formatter = "precise";
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";
57 # log to console/systemd instead of file
60 handlers = [ "console" ];
64 example = lib.literalExpression ''
67 address = "http://localhost:8008";
68 domain = "public-domain.tld";
73 external = "https://public-appservice-address/public";
76 bridge.permissions = {
77 "example.com" = "full";
78 "@admin:example.com" = "admin";
81 connection.use_ipv6 = true;
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.
95 environmentFile = lib.mkOption {
96 type = lib.types.nullOr lib.types.path;
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
116 `MAUTRIX_TELEGRAM_BRIDGE_LOGIN_SHARED_SECRET_MAP=json::{"example.com":"secret"}`.
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
127 List of Systemd services to require and wait for when starting the application service.
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:
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;
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}'
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
171 ProtectSystem = "strict";
173 ProtectKernelTunables = true;
174 ProtectKernelModules = true;
175 ProtectControlGroups = true;
179 WorkingDirectory = pkgs.mautrix-telegram; # necessary for the database migration scripts to be found
180 StateDirectory = baseNameOf dataDir;
182 EnvironmentFile = cfg.environmentFile;
185 ${pkgs.mautrix-telegram}/bin/mautrix-telegram \
186 --config='${settingsFile}'
192 meta.maintainers = with lib.maintainers; [ pacien vskilet ];