Files
matrix/discord-bridge/install.sh
T
Lotus CIandClaude Opus 5.5 3e6f210f46
Lint / Shell (shellcheck) (push) Successful in 12s
Lint / JS (eslint) (push) Successful in 11s
Lint / No secrets in webhook configs (push) Successful in 7s
Lint / Landing page is rendered (matrix (push) Successful in 8s
Lint / Python (ruff) (push) Successful in 12s
Lint / Python deps (pip-audit) (push) Failing after 1m1s
Lint / Secret scan (gitleaks) (push) Successful in 8s
Lint / Shell (shellcheck) (pull_request) Successful in 15s
Lint / JS (eslint) (pull_request) Successful in 14s
Lint / No secrets in webhook configs (pull_request) Successful in 6s
Lint / Landing page is rendered (matrix (pull_request) Successful in 5s
Lint / Python (ruff) (pull_request) Successful in 7s
Lint / Secret scan (gitleaks) (pull_request) Successful in 9s
Lint / Python deps (pip-audit) (pull_request) Failing after 1m54s
Add mautrix-discord bridge config and installer
Bot-login Discord bridge on LXC 151: config template (DB password is
filled in on the server), systemd unit, and a one-time install script
run from the Proxmox node that sets up the PostgreSQL role/database,
installs the checksum-verified v0.7.7 binary, generates the appservice
registration, adds it to Synapse and restarts Synapse once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-28 21:08:45 -04:00

104 lines
4.4 KiB
Bash
Executable File

#!/bin/bash
# One-time install of the mautrix-discord bridge.
# Run on the Proxmox node that hosts LXC 109 (PostgreSQL) and LXC 151 (Synapse):
# pct exec 151 -- cat /opt/matrix-config/discord-bridge/install.sh | bash
# Needs this repo's main branch already pulled to /opt/matrix-config on LXC 151
# (the auto-deploy does that). Restarts Synapse once (~30-60s of downtime).
# Safe to re-run: existing database, user, config and registration are kept.
set -euo pipefail
VERSION="v0.7.7"
SHA256="1f3b6953b4eae00d141ce706f6e97c1b5d0e50268a447bc605df2fa4f44c5d9d"
PG_CT=109
SYNAPSE_CT=151
SYNAPSE_IP="10.10.10.29"
# Only used if the database role does not exist yet; never printed.
DB_PASSWORD="$(openssl rand -hex 24 </dev/null)"
echo "== [1/3] PostgreSQL (LXC $PG_CT): role, database, pg_hba =="
pct exec "$PG_CT" -- bash -s "$DB_PASSWORD" "$SYNAPSE_IP" <<'PG'
set -euo pipefail
PW="$1"; SRC="$2"
HBA=/etc/postgresql/17/main/pg_hba.conf
if su postgres -c "psql -Atc \"select 1 from pg_roles where rolname='mautrix_discord'\"" | grep -q 1; then
echo "role mautrix_discord exists, keeping it"
echo "EXISTS" > /root/.mautrix-discord-role-existed
else
su postgres -c "psql -v ON_ERROR_STOP=1 -q" <<SQL
CREATE ROLE mautrix_discord LOGIN PASSWORD '$PW';
SQL
rm -f /root/.mautrix-discord-role-existed
fi
if ! su postgres -c "psql -Atc \"select 1 from pg_database where datname='mautrix_discord'\"" | grep -q 1; then
su postgres -c "psql -v ON_ERROR_STOP=1 -q -c \"CREATE DATABASE mautrix_discord OWNER mautrix_discord ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0\""
fi
if ! grep -q '^host *mautrix_discord ' "$HBA"; then
cp "$HBA" "$HBA.bak-$(date +%Y%m%d%H%M%S)-discord"
sed -i "/^host *synapse *synapse_user/a host mautrix_discord mautrix_discord $SRC/32 scram-sha-256" "$HBA"
fi
su postgres -c "psql -Atqc 'select pg_reload_conf()'" >/dev/null
echo "ok"
PG
ROLE_EXISTED=$(pct exec "$PG_CT" -- sh -c 'test -f /root/.mautrix-discord-role-existed && echo yes || echo no' </dev/null)
echo "== [2/3] Bridge (LXC $SYNAPSE_CT): binary, config, registration, service =="
pct exec "$SYNAPSE_CT" -- bash -s "$DB_PASSWORD" "$ROLE_EXISTED" "$VERSION" "$SHA256" <<'BR'
set -euo pipefail
PW="$1"; ROLE_EXISTED="$2"; VERSION="$3"; SHA256="$4"
DIR=/opt/mautrix-discord
SRC=/opt/matrix-config
id mautrix-discord >/dev/null 2>&1 || useradd --system --home "$DIR" --shell /usr/sbin/nologin mautrix-discord
mkdir -p "$DIR" /var/log/mautrix-discord
curl -fsSL -o "$DIR/mautrix-discord.new" "https://github.com/mautrix/discord/releases/download/$VERSION/mautrix-discord-amd64"
echo "$SHA256 $DIR/mautrix-discord.new" | sha256sum -c -
chmod 755 "$DIR/mautrix-discord.new"
mv "$DIR/mautrix-discord.new" "$DIR/mautrix-discord"
if [ ! -f "$DIR/config.yaml" ]; then
if [ "$ROLE_EXISTED" = yes ]; then
echo "ERROR: DB role already existed but there is no config; set the password in $DIR/config.yaml by hand" >&2
exit 1
fi
sed "s/DB_PASSWORD/$PW/" "$SRC/discord-bridge/config.yaml" > "$DIR/config.yaml"
fi
if [ ! -f "$DIR/registration.yaml" ]; then
(cd "$DIR" && ./mautrix-discord -g -c config.yaml -r registration.yaml)
fi
chown -R mautrix-discord:mautrix-discord "$DIR" /var/log/mautrix-discord
chmod 600 "$DIR/config.yaml"
install -m 640 -o root -g matrix-synapse "$DIR/registration.yaml" /etc/matrix-synapse/discord-registration.yaml
install -m 644 "$SRC/systemd/mautrix-discord.service" /etc/systemd/system/mautrix-discord.service
systemctl daemon-reload
HS=/etc/matrix-synapse/homeserver.yaml
if ! grep -q discord-registration.yaml "$HS"; then
cp "$HS" "$HS.bak-$(date +%Y%m%d%H%M%S)-discord"
sed -i '/^ - \/etc\/matrix-synapse\/hookshot-registration.yaml/a \ - /etc/matrix-synapse/discord-registration.yaml' "$HS"
fi
grep -A3 '^app_service_config_files' "$HS"
echo "ok"
BR
echo "== [3/3] Restart Synapse, start bridge =="
pct exec "$SYNAPSE_CT" -- bash -s <<'RS'
set -euo pipefail
systemctl restart matrix-synapse
for i in $(seq 1 60); do
curl -fsS -o /dev/null http://127.0.0.1:8008/health && break
sleep 2
done
curl -fsS http://127.0.0.1:8008/health && echo " (synapse healthy)"
systemctl enable --now mautrix-discord
sleep 5
systemctl --no-pager --lines=15 status mautrix-discord
RS
pct exec "$PG_CT" -- rm -f /root/.mautrix-discord-role-existed </dev/null
echo
echo "Done. In Lotus Chat, start a DM with @discordbot:matrix.lotusguild.org and send:"
echo " login-token bot <your new bot token>"