mirror of
https://github.com/kmein/niveum
synced 2026-03-16 10:11:08 +01:00
format
This commit is contained in:
@@ -84,7 +84,11 @@ in
|
||||
Type = "simple";
|
||||
ExecStart = ''
|
||||
${lib.getExe cfg.package} \
|
||||
${lib.optionalString (cfg.contactInstructions != null) ("--contact " + lib.escapeShellArg cfg.contactInstructions)} \
|
||||
${
|
||||
lib.optionalString (cfg.contactInstructions != null) (
|
||||
"--contact " + lib.escapeShellArg cfg.contactInstructions
|
||||
)
|
||||
} \
|
||||
--host ${cfg.host} \
|
||||
--index ${pkgs.writeText "index.html" cfg.homePageTemplate} \
|
||||
--listen ${cfg.listenAddress} \
|
||||
|
||||
@@ -4,18 +4,20 @@
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.moodle-dl;
|
||||
json = pkgs.formats.json {};
|
||||
json = pkgs.formats.json { };
|
||||
moodle-dl-json = json.generate "moodle-dl.json" cfg.settings;
|
||||
stateDirectoryDefault = "/var/lib/moodle-dl";
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.moodle-dl = {
|
||||
enable = mkEnableOption "moodle-dl, a Moodle downloader";
|
||||
|
||||
settings = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = json.type;
|
||||
description = ''
|
||||
Configuration for moodle-dl. For a full example, see
|
||||
@@ -69,11 +71,11 @@ in {
|
||||
group = "moodle-dl";
|
||||
};
|
||||
|
||||
users.groups.moodle-dl = {};
|
||||
users.groups.moodle-dl = { };
|
||||
|
||||
systemd.services.moodle-dl = {
|
||||
description = "A Moodle downloader that downloads course content";
|
||||
wants = ["network-online.target"];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = mkMerge [
|
||||
{
|
||||
Type = "oneshot";
|
||||
@@ -83,11 +85,11 @@ in {
|
||||
ExecStart = "${cfg.package}/bin/moodle-dl ${lib.optionalString cfg.notifyOnly "--without-downloading-files"}";
|
||||
ExecStartPre = pkgs.writers.writeDash "moodle-dl-config" "${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${toString moodle-dl-json} ${toString cfg.tokensFile} > ${cfg.directory}/config.json";
|
||||
}
|
||||
(mkIf (cfg.directory == stateDirectoryDefault) {StateDirectory = "moodle-dl";})
|
||||
(mkIf (cfg.directory == stateDirectoryDefault) { StateDirectory = "moodle-dl"; })
|
||||
];
|
||||
inherit (cfg) startAt;
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [maintainers.kmein];
|
||||
meta.maintainers = [ maintainers.kmein ];
|
||||
}
|
||||
|
||||
@@ -3,65 +3,69 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
options.services.panoptikon = {
|
||||
enable = lib.mkEnableOption "Generic command output / website watcher";
|
||||
watchers = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule (watcher: {
|
||||
options = {
|
||||
script = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
A script whose stdout is to be watched.
|
||||
'';
|
||||
example = ''
|
||||
pkgs.writers.writeDash "github-meta" '''
|
||||
''${pkgs.curl}/bin/curl -sSL https://api.github.com/meta | ''${pkgs.jq}/bin/jq
|
||||
'''
|
||||
'';
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (watcher: {
|
||||
options = {
|
||||
script = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
A script whose stdout is to be watched.
|
||||
'';
|
||||
example = ''
|
||||
pkgs.writers.writeDash "github-meta" '''
|
||||
''${pkgs.curl}/bin/curl -sSL https://api.github.com/meta | ''${pkgs.jq}/bin/jq
|
||||
'''
|
||||
'';
|
||||
};
|
||||
frequency = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
How often to run the script. See systemd.time(7) for more information about the format.
|
||||
'';
|
||||
example = "*:0/3";
|
||||
default = "daily";
|
||||
};
|
||||
loadCredential = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
This can be used to pass secrets to the systemd service without adding them to the nix store.
|
||||
'';
|
||||
default = [ ];
|
||||
};
|
||||
reporters = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
description = ''
|
||||
A list of scripts that take the diff (if any) via stdin and report it (e.g. to IRC, Telegram or Prometheus). The name of the watcher will be in the $PANOPTIKON_WATCHER environment variable.
|
||||
'';
|
||||
example = ''
|
||||
[
|
||||
(pkgs.writers.writeDash "telegram-reporter" '''
|
||||
''${pkgs.curl}/bin/curl -X POST https://api.telegram.org/bot''${TOKEN}/sendMessage \
|
||||
-d chat_id=123456 \
|
||||
-d text="$(cat)"
|
||||
''')
|
||||
(pkgs.writers.writeDash "notify" '''
|
||||
''${pkgs.libnotify}/bin/notify-send "$PANOPTIKON_WATCHER has changed."
|
||||
''')
|
||||
]
|
||||
'';
|
||||
};
|
||||
};
|
||||
frequency = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
How often to run the script. See systemd.time(7) for more information about the format.
|
||||
'';
|
||||
example = "*:0/3";
|
||||
default = "daily";
|
||||
};
|
||||
loadCredential = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
This can be used to pass secrets to the systemd service without adding them to the nix store.
|
||||
'';
|
||||
default = [];
|
||||
};
|
||||
reporters = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
description = ''
|
||||
A list of scripts that take the diff (if any) via stdin and report it (e.g. to IRC, Telegram or Prometheus). The name of the watcher will be in the $PANOPTIKON_WATCHER environment variable.
|
||||
'';
|
||||
example = ''
|
||||
[
|
||||
(pkgs.writers.writeDash "telegram-reporter" '''
|
||||
''${pkgs.curl}/bin/curl -X POST https://api.telegram.org/bot''${TOKEN}/sendMessage \
|
||||
-d chat_id=123456 \
|
||||
-d text="$(cat)"
|
||||
''')
|
||||
(pkgs.writers.writeDash "notify" '''
|
||||
''${pkgs.libnotify}/bin/notify-send "$PANOPTIKON_WATCHER has changed."
|
||||
''')
|
||||
]
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = {};
|
||||
}));
|
||||
config = { };
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.services.panoptikon;
|
||||
in
|
||||
config =
|
||||
let
|
||||
cfg = config.services.panoptikon;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
users.extraUsers.panoptikon = {
|
||||
isSystemUser = true;
|
||||
@@ -70,45 +74,50 @@
|
||||
group = "panoptikon";
|
||||
};
|
||||
|
||||
users.extraGroups.panoptikon = {};
|
||||
users.extraGroups.panoptikon = { };
|
||||
|
||||
systemd.timers = lib.attrsets.mapAttrs' (watcherName: _:
|
||||
systemd.timers = lib.attrsets.mapAttrs' (
|
||||
watcherName: _:
|
||||
lib.nameValuePair "panoptikon-${watcherName}" {
|
||||
timerConfig.RandomizedDelaySec = toString (60 * 60);
|
||||
})
|
||||
cfg.watchers;
|
||||
}
|
||||
) cfg.watchers;
|
||||
|
||||
systemd.services =
|
||||
lib.attrsets.mapAttrs' (watcherName: watcherOptions:
|
||||
lib.nameValuePair "panoptikon-${watcherName}" {
|
||||
enable = true;
|
||||
startAt = watcherOptions.frequency;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "panoptikon";
|
||||
Group = "panoptikon";
|
||||
WorkingDirectory = "/var/lib/panoptikon";
|
||||
RestartSec = toString (60 * 60);
|
||||
Restart = "on-failure";
|
||||
LoadCredential = watcherOptions.loadCredential;
|
||||
};
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = "300";
|
||||
StartLimitBurst = "5";
|
||||
};
|
||||
environment.PANOPTIKON_WATCHER = watcherName;
|
||||
wants = ["network-online.target"];
|
||||
script = ''
|
||||
set -fux
|
||||
${watcherOptions.script} > ${lib.escapeShellArg watcherName}
|
||||
diff_output=$(${pkgs.diffutils}/bin/diff --new-file ${lib.escapeShellArg (watcherName + ".old")} ${lib.escapeShellArg watcherName} || :)
|
||||
if [ -n "$diff_output" ]
|
||||
then
|
||||
${lib.strings.concatMapStringsSep "\n" (reporter: ''echo "$diff_output" | ${reporter} || :'') watcherOptions.reporters}
|
||||
fi
|
||||
mv ${lib.escapeShellArg watcherName} ${lib.escapeShellArg (watcherName + ".old")}
|
||||
'';
|
||||
})
|
||||
cfg.watchers;
|
||||
systemd.services = lib.attrsets.mapAttrs' (
|
||||
watcherName: watcherOptions:
|
||||
lib.nameValuePair "panoptikon-${watcherName}" {
|
||||
enable = true;
|
||||
startAt = watcherOptions.frequency;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "panoptikon";
|
||||
Group = "panoptikon";
|
||||
WorkingDirectory = "/var/lib/panoptikon";
|
||||
RestartSec = toString (60 * 60);
|
||||
Restart = "on-failure";
|
||||
LoadCredential = watcherOptions.loadCredential;
|
||||
};
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = "300";
|
||||
StartLimitBurst = "5";
|
||||
};
|
||||
environment.PANOPTIKON_WATCHER = watcherName;
|
||||
wants = [ "network-online.target" ];
|
||||
script = ''
|
||||
set -fux
|
||||
${watcherOptions.script} > ${lib.escapeShellArg watcherName}
|
||||
diff_output=$(${pkgs.diffutils}/bin/diff --new-file ${
|
||||
lib.escapeShellArg (watcherName + ".old")
|
||||
} ${lib.escapeShellArg watcherName} || :)
|
||||
if [ -n "$diff_output" ]
|
||||
then
|
||||
${lib.strings.concatMapStringsSep "\n" (
|
||||
reporter: ''echo "$diff_output" | ${reporter} || :''
|
||||
) watcherOptions.reporters}
|
||||
fi
|
||||
mv ${lib.escapeShellArg watcherName} ${lib.escapeShellArg (watcherName + ".old")}
|
||||
'';
|
||||
}
|
||||
) cfg.watchers;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
cfg = config.niveum.passport;
|
||||
sortOn = a: lib.sort (as1: as2: lib.lessThan (lib.getAttr a as1) (lib.getAttr a as2));
|
||||
css = ''
|
||||
@@ -52,20 +53,22 @@
|
||||
}
|
||||
'';
|
||||
in
|
||||
with lib; {
|
||||
options.niveum.passport = {
|
||||
enable = mkEnableOption "server passport";
|
||||
with lib;
|
||||
{
|
||||
options.niveum.passport = {
|
||||
enable = mkEnableOption "server passport";
|
||||
|
||||
introductionHTML = mkOption {type = types.str;};
|
||||
introductionHTML = mkOption { type = types.str; };
|
||||
|
||||
virtualHost = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
virtualHost = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
services = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
services = mkOption {
|
||||
type = types.listOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
title = mkOption {type = types.str;};
|
||||
title = mkOption { type = types.str; };
|
||||
link = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
@@ -75,61 +78,62 @@ in
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [];
|
||||
}
|
||||
);
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx.enable = true;
|
||||
|
||||
services.nginx.virtualHosts."${cfg.virtualHost}".locations."/passport".extraConfig = ''
|
||||
default_type "text/html";
|
||||
root ${
|
||||
pkgs.linkFarm "www" [
|
||||
{
|
||||
name = "passport/index.html";
|
||||
path = pkgs.writeText "index.html" ''
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>${config.networking.hostName} passport</title>
|
||||
<style>${css}</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<section id="server">
|
||||
<h1>${config.networking.hostName}</h1>
|
||||
${cfg.introductionHTML}
|
||||
</section>
|
||||
|
||||
<section id="services">
|
||||
<h2>Services</h2>
|
||||
<dl>
|
||||
${lib.strings.concatMapStringsSep "\n" (service: ''
|
||||
<dt>
|
||||
${lib.optionalString (service.link != null) "<a href=\"${service.link}\">"}
|
||||
${service.title}
|
||||
${lib.optionalString (service.link != null) "</a>"}
|
||||
</dt>
|
||||
<dd>
|
||||
${service.description}
|
||||
</dd>
|
||||
'') (sortOn "title" cfg.services)}
|
||||
</dl>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<tt>${config.networking.hostName}</tt> is part of the <i><a href="https://github.com/kmein/niveum/tree/master/systems/${config.networking.hostName}">niveum</a></i> network.
|
||||
</footer>
|
||||
</body>
|
||||
'';
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx.enable = true;
|
||||
|
||||
services.nginx.virtualHosts."${cfg.virtualHost}".locations."/passport".extraConfig = ''
|
||||
default_type "text/html";
|
||||
root ${
|
||||
pkgs.linkFarm "www" [
|
||||
{
|
||||
name = "passport/index.html";
|
||||
path = pkgs.writeText "index.html" ''
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>${config.networking.hostName} passport</title>
|
||||
<style>${css}</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<section id="server">
|
||||
<h1>${config.networking.hostName}</h1>
|
||||
${cfg.introductionHTML}
|
||||
</section>
|
||||
|
||||
<section id="services">
|
||||
<h2>Services</h2>
|
||||
<dl>
|
||||
${lib.strings.concatMapStringsSep "\n" (service: ''
|
||||
<dt>
|
||||
${lib.optionalString (service.link != null) "<a href=\"${service.link}\">"}
|
||||
${service.title}
|
||||
${lib.optionalString (service.link != null) "</a>"}
|
||||
</dt>
|
||||
<dd>
|
||||
${service.description}
|
||||
</dd>
|
||||
'') (sortOn "title" cfg.services)}
|
||||
</dl>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<tt>${config.networking.hostName}</tt> is part of the <i><a href="https://github.com/kmein/niveum/tree/master/systems/${config.networking.hostName}">niveum</a></i> network.
|
||||
</footer>
|
||||
</body>
|
||||
'';
|
||||
}
|
||||
]
|
||||
};
|
||||
index index.html;
|
||||
'';
|
||||
};
|
||||
}
|
||||
index index.html;
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.power-action;
|
||||
|
||||
out = {
|
||||
@@ -27,7 +28,8 @@ with lib; let
|
||||
default = "*:0/1";
|
||||
};
|
||||
plans = mkOption {
|
||||
type = with types;
|
||||
type =
|
||||
with types;
|
||||
attrsOf (submodule {
|
||||
options = {
|
||||
charging = mkOption {
|
||||
@@ -71,14 +73,18 @@ with lib; let
|
||||
state="$(${state})"
|
||||
${concatStringsSep "\n" (mapAttrsToList writeRule cfg.plans)}
|
||||
'';
|
||||
charging_check = plan:
|
||||
if (plan.charging == null)
|
||||
then ""
|
||||
else if plan.charging
|
||||
then ''&& [ "$state" = "true" ]''
|
||||
else ''&& ! [ "$state" = "true" ]'';
|
||||
charging_check =
|
||||
plan:
|
||||
if (plan.charging == null) then
|
||||
""
|
||||
else if plan.charging then
|
||||
''&& [ "$state" = "true" ]''
|
||||
else
|
||||
''&& ! [ "$state" = "true" ]'';
|
||||
|
||||
writeRule = _: plan: "if [ $power -ge ${toString plan.lowerLimit} ] && [ $power -le ${toString plan.upperLimit} ] ${charging_check plan}; then ${plan.action}; fi";
|
||||
writeRule =
|
||||
_: plan:
|
||||
"if [ $power -ge ${toString plan.lowerLimit} ] && [ $power -le ${toString plan.upperLimit} ] ${charging_check plan}; then ${plan.action}; fi";
|
||||
|
||||
powerlvl = pkgs.writers.writeDash "powerlvl" ''
|
||||
cat /sys/class/power_supply/${cfg.battery}/capacity
|
||||
@@ -91,4 +97,4 @@ with lib; let
|
||||
fi
|
||||
'';
|
||||
in
|
||||
out
|
||||
out
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
with lib;
|
||||
let
|
||||
netname = "retiolum";
|
||||
cfg = config.networking.retiolum;
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
networking.retiolum.ipv4 = mkOption {
|
||||
type = types.str;
|
||||
@@ -33,10 +35,9 @@ in {
|
||||
config = {
|
||||
services.tinc.networks.${netname} = {
|
||||
name = cfg.nodename;
|
||||
hosts =
|
||||
builtins.mapAttrs
|
||||
(name: _: builtins.readFile "${<retiolum/hosts>}/${name}")
|
||||
(builtins.readDir <retiolum/hosts>);
|
||||
hosts = builtins.mapAttrs (name: _: builtins.readFile "${<retiolum/hosts>}/${name}") (
|
||||
builtins.readDir <retiolum/hosts>
|
||||
);
|
||||
rsaPrivateKeyFile = toString <system-secrets/retiolum.key>;
|
||||
ed25519PrivateKeyFile = toString <system-secrets/retiolum.ed25519>;
|
||||
extraConfig = ''
|
||||
@@ -47,11 +48,11 @@ in {
|
||||
|
||||
networking.extraHosts = builtins.readFile (toString <retiolum/etc.hosts>);
|
||||
|
||||
environment.systemPackages = [config.services.tinc.networks.${netname}.package];
|
||||
environment.systemPackages = [ config.services.tinc.networks.${netname}.package ];
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [655];
|
||||
allowedUDPPorts = [655];
|
||||
allowedTCPPorts = [ 655 ];
|
||||
allowedUDPPorts = [ 655 ];
|
||||
};
|
||||
#services.netdata.portcheck.checks.tinc.port = 655;
|
||||
|
||||
|
||||
@@ -4,32 +4,35 @@
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; {
|
||||
with lib;
|
||||
{
|
||||
options.niveum = {
|
||||
wirelessInterface = mkOption {type = types.str;};
|
||||
wirelessInterface = mkOption { type = types.str; };
|
||||
|
||||
batteryName = mkOption {type = types.str;};
|
||||
batteryName = mkOption { type = types.str; };
|
||||
|
||||
promptColours = let
|
||||
colours16 = types.enum [
|
||||
"black"
|
||||
"red"
|
||||
"green"
|
||||
"yellow"
|
||||
"blue"
|
||||
"magenta"
|
||||
"cyan"
|
||||
"white"
|
||||
];
|
||||
in {
|
||||
success = mkOption {
|
||||
type = colours16;
|
||||
default = "green";
|
||||
promptColours =
|
||||
let
|
||||
colours16 = types.enum [
|
||||
"black"
|
||||
"red"
|
||||
"green"
|
||||
"yellow"
|
||||
"blue"
|
||||
"magenta"
|
||||
"cyan"
|
||||
"white"
|
||||
];
|
||||
in
|
||||
{
|
||||
success = mkOption {
|
||||
type = colours16;
|
||||
default = "green";
|
||||
};
|
||||
failure = mkOption {
|
||||
type = colours16;
|
||||
default = "red";
|
||||
};
|
||||
};
|
||||
failure = mkOption {
|
||||
type = colours16;
|
||||
default = "red";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,24 +4,29 @@
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
with lib;
|
||||
let
|
||||
cfg = config.niveum.bots;
|
||||
|
||||
botService = name: bot:
|
||||
botService =
|
||||
name: bot:
|
||||
nameValuePair "bot-${name}" {
|
||||
enable = bot.enable;
|
||||
startAt = bot.time;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
LoadCredential = lib.optionals (bot.telegram.enable) [
|
||||
"telegram-token:${bot.telegram.tokenFile}"
|
||||
] ++ lib.optionals (bot.mastodon.enable) [
|
||||
"mastodon-token:${bot.mastodon.tokenFile}"
|
||||
] ++ lib.optionals (bot.matrix.enable) [
|
||||
"matrix-token:${bot.matrix.tokenFile}"
|
||||
];
|
||||
LoadCredential =
|
||||
lib.optionals (bot.telegram.enable) [
|
||||
"telegram-token:${bot.telegram.tokenFile}"
|
||||
]
|
||||
++ lib.optionals (bot.mastodon.enable) [
|
||||
"mastodon-token:${bot.mastodon.tokenFile}"
|
||||
]
|
||||
++ lib.optionals (bot.matrix.enable) [
|
||||
"matrix-token:${bot.matrix.tokenFile}"
|
||||
];
|
||||
};
|
||||
wants = ["network-online.target"];
|
||||
wants = [ "network-online.target" ];
|
||||
script = ''
|
||||
QUOTE=$(${bot.command})
|
||||
if [ -n "$QUOTE" ]; then
|
||||
@@ -30,12 +35,14 @@ with lib; let
|
||||
${lib.optionalString (bot.matrix.enable) ''
|
||||
export MATRIX_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/matrix-token")"
|
||||
export JSON_PAYLOAD=$(${pkgs.jq}/bin/jq -n --arg msgtype "m.text" --arg body "$QUOTE" '{msgtype: $msgtype, body: $body}')
|
||||
${strings.concatStringsSep "\n" (map (chatId: ''
|
||||
${pkgs.curl}/bin/curl -X POST "https://${bot.matrix.homeserver}/_matrix/client/r0/rooms/${chatId}/send/m.room.message" \
|
||||
-d "$JSON_PAYLOAD" \
|
||||
-H "Authorization: Bearer $MATRIX_TOKEN" \
|
||||
-H "Content-Type: application/json"
|
||||
'') bot.matrix.chatIds)}
|
||||
${strings.concatStringsSep "\n" (
|
||||
map (chatId: ''
|
||||
${pkgs.curl}/bin/curl -X POST "https://${bot.matrix.homeserver}/_matrix/client/r0/rooms/${chatId}/send/m.room.message" \
|
||||
-d "$JSON_PAYLOAD" \
|
||||
-H "Authorization: Bearer $MATRIX_TOKEN" \
|
||||
-H "Content-Type: application/json"
|
||||
'') bot.matrix.chatIds
|
||||
)}
|
||||
''}
|
||||
|
||||
${lib.optionalString (bot.mastodon.enable) ''
|
||||
@@ -49,78 +56,90 @@ with lib; let
|
||||
|
||||
${lib.optionalString (bot.telegram.enable) ''
|
||||
export TELEGRAM_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/telegram-token")"
|
||||
${strings.concatStringsSep "\n" (map (chatId: ''
|
||||
${pkgs.curl}/bin/curl -X POST "https://api.telegram.org/bot''${TELEGRAM_TOKEN}/sendMessage" \
|
||||
-d chat_id="${chatId}" \
|
||||
-d text="$QUOTE" ${
|
||||
lib.strings.optionalString (bot.telegram.parseMode != null)
|
||||
"-d parse_mode=${bot.telegram.parseMode}"
|
||||
} | ${pkgs.jq}/bin/jq -e .ok
|
||||
'')
|
||||
bot.telegram.chatIds)}
|
||||
${strings.concatStringsSep "\n" (
|
||||
map (chatId: ''
|
||||
${pkgs.curl}/bin/curl -X POST "https://api.telegram.org/bot''${TELEGRAM_TOKEN}/sendMessage" \
|
||||
-d chat_id="${chatId}" \
|
||||
-d text="$QUOTE" ${
|
||||
lib.strings.optionalString (
|
||||
bot.telegram.parseMode != null
|
||||
) "-d parse_mode=${bot.telegram.parseMode}"
|
||||
} | ${pkgs.jq}/bin/jq -e .ok
|
||||
'') bot.telegram.chatIds
|
||||
)}
|
||||
''}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.niveum.bots = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Mastodon and Telegram bot";
|
||||
time = mkOption {type = types.str;};
|
||||
command = mkOption {type = types.str;};
|
||||
matrix = mkOption {
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Posting to Matrix";
|
||||
tokenFile = mkOption {type = types.path;};
|
||||
homeserver = mkOption {
|
||||
type = types.str;
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Mastodon and Telegram bot";
|
||||
time = mkOption { type = types.str; };
|
||||
command = mkOption { type = types.str; };
|
||||
matrix = mkOption {
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Posting to Matrix";
|
||||
tokenFile = mkOption { type = types.path; };
|
||||
homeserver = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
chatIds = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
chatIds = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
mastodon = mkOption {
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Posting to Mastodon";
|
||||
language = mkOption {
|
||||
type = types.str;
|
||||
default = "en";
|
||||
};
|
||||
tokenFile = mkOption { type = types.path; };
|
||||
homeserver = mkOption {
|
||||
type = types.str;
|
||||
default = "social.krebsco.de";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
telegram = mkOption {
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Posting to Telegram";
|
||||
tokenFile = mkOption { type = types.path; };
|
||||
chatIds = mkOption {
|
||||
type = types.listOf (types.strMatching "-?[0-9]+|@[A-Za-z0-9]+");
|
||||
};
|
||||
parseMode = mkOption {
|
||||
type = types.nullOr (
|
||||
types.enum [
|
||||
"HTML"
|
||||
"Markdown"
|
||||
]
|
||||
);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
mastodon = mkOption {
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Posting to Mastodon";
|
||||
language = mkOption {
|
||||
type = types.str;
|
||||
default = "en";
|
||||
};
|
||||
tokenFile = mkOption {type = types.path;};
|
||||
homeserver = mkOption {
|
||||
type = types.str;
|
||||
default = "social.krebsco.de";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
telegram = mkOption {
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Posting to Telegram";
|
||||
tokenFile = mkOption {type = types.path;};
|
||||
chatIds = mkOption {
|
||||
type = types.listOf (types.strMatching "-?[0-9]+|@[A-Za-z0-9]+");
|
||||
};
|
||||
parseMode = mkOption {
|
||||
type = types.nullOr (types.enum ["HTML" "Markdown"]);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
default = {};
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
};
|
||||
|
||||
config = {systemd.services = attrsets.mapAttrs' botService cfg;};
|
||||
config = {
|
||||
systemd.services = attrsets.mapAttrs' botService cfg;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user