diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index a5485f5a304..e8c4a4c14cf 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -464,6 +464,7 @@
./services/misc/mathics.nix
./services/misc/matrix-appservice-discord.nix
./services/misc/matrix-synapse.nix
+ ./services/misc/mautrix-telegram.nix
./services/misc/mbpfan.nix
./services/misc/mediatomb.nix
./services/misc/mesos-master.nix
diff --git a/nixos/modules/services/misc/mautrix-telegram.nix b/nixos/modules/services/misc/mautrix-telegram.nix
new file mode 100644
index 00000000000..78a42fbb574
--- /dev/null
+++ b/nixos/modules/services/misc/mautrix-telegram.nix
@@ -0,0 +1,163 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ dataDir = "/var/lib/mautrix-telegram";
+ registrationFile = "${dataDir}/telegram-registration.yaml";
+ cfg = config.services.mautrix-telegram;
+ # TODO: switch to configGen.json once RFC42 is implemented
+ settingsFile = pkgs.writeText "mautrix-telegram-settings.json" (builtins.toJSON cfg.settings);
+
+in {
+ options = {
+ services.mautrix-telegram = {
+ enable = mkEnableOption "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge";
+
+ settings = mkOption rec {
+ # TODO: switch to types.config.json as prescribed by RFC42 once it's implemented
+ type = types.attrs;
+ apply = recursiveUpdate default;
+ default = {
+ appservice = rec {
+ database = "sqlite:///${dataDir}/mautrix-telegram.db";
+ hostname = "0.0.0.0";
+ port = 8080;
+ address = "http://localhost:${toString port}";
+ };
+
+ bridge = {
+ permissions."*" = "relaybot";
+ relaybot.whitelist = [ ];
+ };
+
+ logging = {
+ version = 1;
+
+ formatters.precise.format = "[%(levelname)s@%(name)s] %(message)s";
+
+ handlers.console = {
+ class = "logging.StreamHandler";
+ formatter = "precise";
+ };
+
+ loggers = {
+ mau.level = "INFO";
+ telethon.level = "INFO";
+
+ # prevent tokens from leaking in the logs:
+ # https://github.com/tulir/mautrix-telegram/issues/351
+ aiohttp.level = "WARNING";
+ };
+
+ # log to console/systemd instead of file
+ root = {
+ level = "INFO";
+ handlers = [ "console" ];
+ };
+ };
+ };
+ example = literalExample ''
+ {
+ homeserver = {
+ address = "http://localhost:8008";
+ domain = "public-domain.tld";
+ };
+
+ appservice.public = {
+ prefix = "/public";
+ external = "https://public-appservice-address/public";
+ };
+
+ bridge.permissions = {
+ "example.com" = "full";
+ "@admin:example.com" = "admin";
+ };
+ }
+ '';
+ description = ''
+ config.yaml configuration as a Nix attribute set.
+ Configuration options should match those described in
+
+ example-config.yaml.
+
+
+
+ Secret tokens should be specified using
+ instead of this world-readable attribute set.
+ '';
+ };
+
+ environmentFile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ File containing environment variables to be passed to the mautrix-telegram service,
+ in which secret tokens can be specified securely by defining values for
+ MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN,
+ MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN,
+ MAUTRIX_TELEGRAM_TELEGRAM_API_ID,
+ MAUTRIX_TELEGRAM_TELEGRAM_API_HASH and optionally
+ MAUTRIX_TELEGRAM_TELEGRAM_BOT_TOKEN.
+ '';
+ };
+
+ serviceDependencies = mkOption {
+ type = with types; listOf str;
+ default = optional config.services.matrix-synapse.enable "matrix-synapse.service";
+ description = ''
+ List of Systemd services to require and wait for when starting the application service.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.mautrix-telegram = {
+ description = "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge.";
+
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
+ after = [ "network-online.target" ] ++ cfg.serviceDependencies;
+
+ preStart = ''
+ # generate the appservice's registration file if absent
+ if [ ! -f '${registrationFile}' ]; then
+ ${pkgs.mautrix-telegram}/bin/mautrix-telegram \
+ --generate-registration \
+ --base-config='${pkgs.mautrix-telegram}/example-config.yaml' \
+ --config='${settingsFile}' \
+ --registration='${registrationFile}'
+ fi
+
+ # run automatic database init and migration scripts
+ ${pkgs.mautrix-telegram.alembic}/bin/alembic -x config='${settingsFile}' upgrade head
+ '';
+
+ serviceConfig = {
+ Type = "simple";
+ Restart = "always";
+
+ ProtectSystem = "strict";
+ ProtectHome = true;
+ ProtectKernelTunables = true;
+ ProtectKernelModules = true;
+ ProtectControlGroups = true;
+
+ DynamicUser = true;
+ PrivateTmp = true;
+ WorkingDirectory = pkgs.mautrix-telegram; # necessary for the database migration scripts to be found
+ StateDirectory = baseNameOf dataDir;
+ UMask = 0027;
+ EnvironmentFile = cfg.environmentFile;
+
+ ExecStart = ''
+ ${pkgs.mautrix-telegram}/bin/mautrix-telegram \
+ --config='${settingsFile}'
+ '';
+ };
+ };
+ };
+
+ meta.maintainers = with maintainers; [ pacien vskilet ];
+}