137 lines
4.1 KiB
Nix
137 lines
4.1 KiB
Nix
{ config, pkgs, lib, musiclink, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.services.musiclink;
|
|
musiclinkPkg = musiclink; # musiclink input passed via specialArgs is the package set? No, usually it's the flake itself if not mapped.
|
|
# But in flake.nix we did: musiclink = inputs.musiclink.packages.x86_64-linux.default;
|
|
# So `musiclink` here is the package.
|
|
|
|
in {
|
|
options.services.musiclink = {
|
|
enable = mkEnableOption "MusicLink bot with Matterbridge";
|
|
|
|
package = mkOption {
|
|
type = types.package;
|
|
default = musiclink;
|
|
description = "The MusicLink bot package";
|
|
};
|
|
|
|
matterbridge = {
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = "Enable bundled Matterbridge instance";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = types.port;
|
|
default = 4242;
|
|
description = "Matterbridge API port";
|
|
};
|
|
|
|
slackChannel = mkOption {
|
|
type = types.str;
|
|
default = "music";
|
|
description = "Slack channel to bridge";
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
# -------------------------------------------------------------------------
|
|
# Matterbridge Service
|
|
# -------------------------------------------------------------------------
|
|
systemd.services.musiclink-matterbridge = mkIf cfg.matterbridge.enable {
|
|
description = "Matterbridge for MusicLink";
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
DynamicUser = true;
|
|
StateDirectory = "musiclink-matterbridge";
|
|
WorkingDirectory = "/var/lib/musiclink-matterbridge";
|
|
|
|
# Secrets
|
|
LoadCredential = [
|
|
"slack-bot-token:/run/secrets/slack-bot-token"
|
|
"slack-app-token:/run/secrets/slack-app-token"
|
|
];
|
|
|
|
ExecStartPre = pkgs.writeShellScript "generate-matterbridge-config" ''
|
|
set -euo pipefail
|
|
|
|
SLACK_TOKEN=$(cat $CREDENTIALS_DIRECTORY/slack-bot-token)
|
|
SLACK_APP_TOKEN=$(cat $CREDENTIALS_DIRECTORY/slack-app-token)
|
|
|
|
cat > /var/lib/musiclink-matterbridge/matterbridge.toml <<EOF
|
|
[api.local]
|
|
BindAddress="127.0.0.1:${toString cfg.matterbridge.port}"
|
|
Token="musiclink-internal-token"
|
|
|
|
[[slack]]
|
|
[slack.my-slack]
|
|
Token="$SLACK_TOKEN"
|
|
AppToken="$SLACK_APP_TOKEN"
|
|
# Socket Mode is cleaner (no public ingress needed)
|
|
# If using Socket Mode, we usually need app-level token.
|
|
# Matterbridge supports it? It seems to use standard Slack API.
|
|
# Let's assume standard RTM or Events API if not specified.
|
|
# Wait, for standard Slack bot we need 'Token'. 'AppToken' is for Socket Mode.
|
|
|
|
[[gateway]]
|
|
name = "musiclink-gateway"
|
|
enable = true
|
|
|
|
[[gateway.inout]]
|
|
account = "api.local"
|
|
|
|
[[gateway.inout]]
|
|
account = "slack.my-slack"
|
|
channel = "${cfg.matterbridge.slackChannel}"
|
|
EOF
|
|
'';
|
|
|
|
ExecStart = "${pkgs.matterbridge}/bin/matterbridge -conf /var/lib/musiclink-matterbridge/matterbridge.toml";
|
|
|
|
Restart = "always";
|
|
RestartSec = "10s";
|
|
};
|
|
};
|
|
|
|
# -------------------------------------------------------------------------
|
|
# MusicLink Bot Service
|
|
# -------------------------------------------------------------------------
|
|
systemd.services.musiclink = {
|
|
description = "MusicLink Bot";
|
|
after = [ "musiclink-matterbridge.service" ];
|
|
wants = [ "musiclink-matterbridge.service" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
DynamicUser = true;
|
|
StateDirectory = "musiclink";
|
|
WorkingDirectory = "/var/lib/musiclink";
|
|
|
|
ExecStartPre = pkgs.writeShellScript "generate-musiclink-config" ''
|
|
cat > /var/lib/musiclink/config.toml <<EOF
|
|
[matterbridge]
|
|
url = "http://127.0.0.1:${toString cfg.matterbridge.port}/api/websocket"
|
|
token = "musiclink-internal-token"
|
|
gateway = "musiclink-gateway"
|
|
username = "MusicLink"
|
|
EOF
|
|
'';
|
|
|
|
ExecStart = "${cfg.package}/bin/musiclink";
|
|
|
|
Restart = "always";
|
|
RestartSec = "10s";
|
|
};
|
|
};
|
|
};
|
|
}
|