Rocket.Chat
Siehe auch
- Ansible-Rolle Rocket.Chat:
Rocket.Chat ist eine Workstream Collaboration Platform (WSC) und damit eine freie Alternative zu Slack und MS Teams. Es basiert auf Node.js. Da Node.js „single threaded“ ist, kann Rocket.Chat nicht von mehreren CPU-Cores profitieren. Bei vielen Concurrent Users kann Rocket.Chat daher träger reagieren, ein Core wird dann zu 100% durch Node.js ausgelastet. In dem Fall lässt sich Rocket.Chat in mehreren Instanzen betreiben.
Rocket.Chat legt die Inhalte (Chat-Nachrichten, Raum-Konfigurationen etc.) in einer MongoDB ab.
Wichtig seit v6.0:
Die Rocket.Chat Community Edition ist für den Einstieg gedacht, aber NICHT für den produktiven Einsatz in grossen Unternehmen.
Version 6.0 bringt deshalb Änderungen im Registrierungsprozess, um die Registrierungsrate zu erhöhen.
Nicht registrierte Workspaces haben keinen Zugang zu Push-Benachrichtigungen, Gateway-Diensten oder dem Marketplace.
Was bringt die Enterprise-Variante?
Infrastructure: High Scalability
Administration: Feature wie LDAP/Active Directory, > 10K Push Notifications, Federation
Security: Secured Push Notifications, Message Audit Panel, Data Loss Prevention
Support: Support from Rocket.Chat
Advanced Team Collaboration: Engagement Dashboard (Data-driven decisions), Read Receipt
Advanced Omnichannel Customer Engagement: On-Hold Queues, Queue Waiting Time, Concurrent Chat Limit, Canned Responses, Advanced Queue Monitoring
- Links
Homepage: https://rocket.chat
Doku: https://docs.rocket.chat
Download Stable Version: https://download.rocket.chat/stable
Download Latest Version: https://releases.rocket.chat/latest/download
Source Code: https://github.com/RocketChat/Rocket.Chat
Konzepte
- Channel („#“):
Channels sind Chaträume. Meist werden Channels themenbezogen organisiert.
Channels („Rooms“) können Threads, Discussions und Benutzer (Members) enthalten.
Ein Channel kann nur einem Team zugeordnet werden.
Wird ein Channel-Member entfernt, bleiben seine Nachrichten erhalten.
- Team
Ein Team ist im Grunde eine Sammlung von Channels, die jeweils einem bestimmten Zweck, Kunden oder Projekt dienen. Ein Team enthält ausgewählte Mitglieder einer Organisation und eine Reihe von Channels, die auf die Rollen dieser Mitglieder zugeschnitten sind. Der Hauptvorteil liegt in der Automatisierung der Zugriffsrechte: Wenn ein neues Mitglied dem Team beitritt, erhält es sofort Zugang zu allen zugehörigen Channels, sofern im Team der Haken „Auto-join“ beim jeweiligen Channel in der Channel-Liste aktiviert ist. Dadurch müssen Mitglieder nicht mehr manuell zu jedem Kanal hinzugefügt werden, was die Effizienz steigert und den Verwaltungsaufwand reduziert.
Teams können Channels, Threads, Discussions und Team Members beinhalten. In Teams kann auch gechattet werden.
Ein Team kann nur Benutzer, aber keine anderen Teams als Members beinhalten. Interessanterweise kann der zentrale Admin-Account keinem Team als Member zugeordnet werden. Wird ein Benutzer einem Team hinzugefügt, sieht er nur das Team, falls die angehängten Channels keinen Auto-join haben. Wird ein Team-Member entfernt, wird gefragt, aus welchen Channels der Benutzer, in denen er Mitglied ist, ebenfalls entfernt werden soll. Seine Nachrichten im Team bleiben erhalten.
Wird ein Channel erstellt, erbt dieser die Team-Members ohne aktiviertes Auto-join nicht - egal ob der Channel zuerst erstellt und später hinzugefügt wird, oder direkt im Team. Wurden Team-Members per Auto-join hinzugefügt, und der Auto-join später deaktiviert, bleiben die Benutzer dem Channel zugeordnet.
- Diskussionen
Diskussionen ermöglichen es, grössere Themen innerhalb eines Teams oder Channels zu diskutieren (sie müssen also zu einem übergeordneten Team oder Channel gehören).
Wird eine neue Discussion erstellt, wird nach dem „Parent Channel or Group“ (gemeint ist Team) gefragt. Discussions können nur mit Admin_Rechten erstellt werden. Wird die Discussion in einem Channel mit Auto-join erstellt und ohne Member-Angabe, erhalten Team Member den Hinweis, dass es eine neue Diskussion gibt. Sie können dann per Klick auf „Join“ selbst entscheiden, ob sie an der Diskussion teilehmen möchten.
Wird ein Discussion-Member entfernt, bleiben seine Nachrichten erhalten.
- Benutzer
Neu angelegte Benutzer sehen (auch über die Suche) nur die Teams, Channels, Diskussionen und andere Benutzer, über die sie zugeteilt wurden.
Benutzer dürfen nur „Direct Messages“ erstellen.
Werden Benutzer per
@
in Teams, Channels oder Discussions erwähnt (= „mention“), zu denen sie nicht gehören, erhalten sie die Nachricht nicht.Wird ein Benutzer in Rocket.Chat gelöscht, werden alle Nachrichten des Benutzers aus allen Objekten entfernt. Daher sollten Benutzer deaktiviert statt gelöscht werden, wenn man auf eine konsistente Chat-History Wert legt. Wird ein Benutzer deaktiviert, wird er sofort ausgeloggt.
- Beispiel
Man hat ein technisches Team und unter diesem Team einen Channel mit dem Namen „Website-Entwicklung“ erstellt. Die Gespräche über jede Funktion der Website können in Diskussionen untergebracht werden.
Update
Ein Update/Upgrade entspricht dem Vorgehen der Neuinstallation:
Shutdown Rocket.Chat
Goto the installation folder: cd /opt/
Remove or move the Rocket.Chat folder.
Follow the installation section
Rocket.Chat konfigurieren
Was ist nach einer Erst-Installation einzurichten?
Auf dem Reverse Proxy: vHost erstellen
Avatar für den Rocket-Administrator und „rocket.cat“ setzen
Standard-Sprache deutsch/englisch setzen, je nach Zielgruppe
Auf Wunsch die User-Registrierung abschalten: Administration > Accounts > Registration > „Registration Form: Disabled“ und „Registration Form Secret URL“
Mail-Einstellungen vornehmen: Administration > Email > SMTP (meist an localhost, 25)
Auf Wunsch PIWIK/Matomo integrieren
Benutzer anlegen oder LDAP integrieren. Wichtig: Benutzer auf „Verified“ setzen, damit sie im Falle einer Abwesenheit Notifications per E-Mail erhalten.
Die ersten Räume einrichten, Benutzer zuteilen
Betrieb hinter Reverse Proxy
SELinux - nach einer Standard-Installation wird sich der Apache Reverse Proxy nicht auf Port 3000 verbinden können:
type=AVC msg=audit(1508497633.925:12355): avc: denied { name_connect } for pid=31373 comm="httpd" dest=3000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:ntop_port_t:s0 tclass=tcp_socket
Deshalb:
setsebool -P httpd_can_network_connect on
Beispiel für einen Apache vHost, der als Reverse Proxy agiert:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName chat.example.com
ProxyRequests Off
ProxyVia Off
<Location />
Require all granted
</Location>
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://10.80.32.19:3000/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://10.80.32.19:3000/$1 [P,L]
ProxyPassReverse / http://10.80.32.19:3000/
<Proxy *>
Require all granted
</Proxy>
SSLEngine on
SSLOptions +StrictRequire
SSLCertificateFile /etc/letsencrypt/live/chat.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/chat.example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/chat.example.com/chain.pem
</VirtualHost>
</IfModule>
Siehe auch https://docs.rocket.chat/installation/manual-installation/configuring-ssl-reverse-proxy
Backup und Restore
Backup:
/opt
sichernMongo-Dump sichern
Daten-Export
Channels (Rooms) und Groups lassen sich mit https://github.com/frdmn/rocketchat-export-channel-messages als CSV oder JSON exportieren, sofern der Benutzer, den man dafür verwendet, die Zugriffsrechte auf die Ressourcen hat. Der Raum-Name muss bekannt sein, also vorher mit dem API-Call channel.listAll
etc. arbeiten.
Posten von Messages per Skript
Dafür gibt es zwei Möglichkeiten:
Man postet unter einem bestimmten Benutzer und legt in der Weboberfläche im Profil unter „My Account > Personal Access Tokens“ ein Token an. Das erhaltene Token und die User ID verwendet man dann beispielsweise mit
curl
:curl --header 'X-Auth-Token: YOUR-ACCESS-TOKEN' \ --header 'X-User-Id: YOUR-USER-ID' \ --header 'Content-type: application/json' \ --data '{ "channel": "CHANNEL-NAME", "text": "Test message" }' \ https://chat.example.com/api/v1/chat.postMessage
Man arbeitet mit Webhooks (bevorzugt). Solch einen Hook erstellt man unter „Administration > Integrations > New Integration“, zum Beispiel für einen Raum oder einen Benutzer. Auf der Admin-Page ist dann auch alles beschrieben, man weiter vorgehen muss. Nicht vergessen, den Absender der Nachricht zum Channel hinzuzufügen, z.B. den Benutzer „rocket.cat“:
curl --request POST \ --header 'Content-Type: application/json' \ --data '{ "channel": "CHANNEL-NAME", "text": "Test message" }' \ https://chat.example.com/hooks/T6yRim2606JJjfNSRKLqya0815a9QygBvsepZ9wQT
Push-Nachrichten
Oft gefragt: Muss ich meine Instanz bei Rocket.Chat registrieren? Wird eine Push-Nachricht nicht von meinem Server direkt verschickt?
Die Push-Notifcations können nicht direkt vom eigenen Rocket.Chat-Server versendet werden: die App-Stores von Google und Apple verlangen, dass in der kompilierten Mobile App fix hinterlegt ist, von welchem Server Push-Notifications stammen. Das Gateway ist also nicht frei konfigurierbar.
Um trotzdem Push-Notifications zu ermöglichen, hostet Rocket.Chat ein Push-Gateway, welches in den Apps hinterlegt ist. Der eigene Rocket.Chat-Server sendet seine Notifications an das Push-Gateway von Rocket.Chat, welches diese dann an das mobile Endgerät weiterleitet. Stand 2020-11 sind kostenlos maximal 10’000 Push-Nachrichten pro Monat pro möglich. Wer mehr benötigt, löst ein Abo, oder man erhält bei Erreichen des Kontingents bis zum Monatsende keine Notifications mehr. Eine Registrierung ist inzwischen damit Pflicht. Siehe auch https://forums.rocket.chat/t/enforcing-registration-requirement-to-utilize-push-gateway/7545
Das offizielle Push-Gateway ist über https://gateway.rocket.chat auf Port 443 erreichbar. Das Senden einer Push-Nachricht vom Rocket.Chat-Server aus ist so auch über einen Outbound-Proxy-Server möglich.
Alternativ kann man ein eigenes Push-Gateway betreiben - allerdings muss man dann die Mobile Apps selbst kompilieren und in den App-Stores anbieten. Ein eigenes Push-Gateway empfehlen wir daher nicht. Siehe auch https://github.com/RocketChat/Rocket.Chat/issues/8692 und https://forums.rocket.chat/t/your-own-push-notifications-not-using-the-default-gateway/7063/2.
Wer Angst hat, dass die Push-Nachrichten sensitive Daten enthalten, die die Rocket.Chat-Entwickler mitlesen können, sendet seine Notifications einfach ohne Inhalt: „Administration > Settings > Push > Privacy > Show Message in Notification: off“.
API
Die Administration klappt auch per API. Das API findet sich dokumentiert auf https://github.com/RocketChat/developer-docs/tree/master/reference/api/rest-api und im Source Code unter packages/rocketchat-api/server/v1
.
Welche API-Methoden sind verfügbar (die Doku hinkt für gewöhnlich hinterher)?
git clone https://github.com/RocketChat/Rocket.Chat
grep -ir 'API\.v1\.addRoute' Rocket.Chat
Am Anfang steht der Login. Man erhält einen „authToken“ und eine „userId“, die für alle nachfolgenden Requests benötigt werden.
RC_URL=chat.linuxfabrik.io
RC_USERNAME=linus
RC_PASSWORD=linuxfabrik
AUTH_RESPONSE=$(curl \
--silent \
--data "user=$RC_USERNAME&password=$RC_PASSWORD" \
https://$RC_URL/api/v1/login)
AUTH_TOKEN=$(echo $AUTH_RESPONSE | jq -r '.data.authToken')
USER_ID=$(echo $AUTH_RESPONSE | jq -r '.data.userId')
Info über Rocket.Chat auslesen - geht ohne Login (und es kommt HTML zurück):
curl https://$RC_URL/api/v1/info
Alle Einstellungen holen:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
https://$RC_URL/api/v1/settings
Tipp
Probleme mit dem API?
Das API mag keine Single-Quotes innerhalb des
--data
JSON-Dictionary.Eventuell hilft ein Blick in
/var/log/messages
.
Benutzern in einem Raum eine Nachricht senden (hier per Webhook):
curl \
--header "Content-Type: application/json" \
--data '{ "text": ":hammer_pick: Was habt ihr für heute geplant? :hammer_pick:" }'
https://$RC_URL/hooks/89b730ea-5dad-4f15-84cb-9999119cba91
Infos über einen Benutzer auslesen:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
https://$RC_URL/api/v1/users.info?username=myuser
Tipp
Der count
-Parameter unterstützt maximal 250 Datensätze. Der offset
beginnt bei 0.
Benutzer von 250 bis 500 auflisten und mit Hilfe von jq als csv exportieren:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
https://$RC_URL/api/v1/users.list?count=250\&offset=250 | jq -r '.users[] | [.username, .lastLogin] | @csv' > login.csv
Benutzer von 250 bis 500 daruf prüfen, ob sie online sind (filtern mittels jq):
curl \
--silent \
--head \
--header "X-User-Id: $USER_ID \
https://$RC_URL/api/v1/users.list?count=250\&offset=250 | jq -r '.users[] | select(.status == "online") | .username'
Benutzer von 250 bis 500 auflisten, die eine nicht-verifizierte E-Mail-Adresse haben (filtern mittels jq):
curl \
--silent \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
https://$RC_URL/api/v1/users.list?count=250\&offset=250 | jq -r '.users[] | select(.emails[0].verified == false) | .username'
Einen Benutzer deaktivieren (die hier beispielhaft angegebene User-UUID vorher per /api/v1/users.list
ermitteln):
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
--data '{ "userId": "0d68d4ce-2b4e-4e3b-ba89-bfa68517668f", "activeStatus": false }' \
https://$RC_URL/api/v1/users.setActiveStatus
Alle User der Gruppe „$role“ deaktivieren, welche in den letzten 365 Tagen inaktiv waren:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
--data "{ \"daysIdle\": 365, \"role\": \"$role\" }" \
https://$RC_URL/api/v1/users.deactivateIdle
Alle Channels auflisten (Rooms):
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
https://$RC_URL/api/v1/channels.list
Infos über einen Channel auslesen:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
https://$RC_URL/api/v1/channels.info?roomName=myroom
Notification-Einstellungen für alle Channels anpassen:
for room_id in $(curl --header "X-User-Id: $USER_ID" --header "X-Auth-Token: $AUTH_TOKEN" --header "Content-type: application/json" https://$RC_URL/api/v1/rooms.get | jq '.update[] | select(.t == "p")._id'); do
curl \
--header "X-User-Id: $USER_ID" \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "Content-type: application/json" \
--data-raw "{ \
\"roomId\": $room_id, \
\"notifications\": {
\"disableNotifications\": \"0\", \
\"muteGroupMentions\": \"0\", \
\"hideUnreadStatus\": \"0\", \
\"hideMentionStatus\": \"0\", \
\"desktopNotifications\": \"default\", \
\"audioNotificationValue\": \"default\", \
\"mobilePushNotifications\": \"default\", \
\"emailNotifications\": \"default\" \
} \
}" \
https://$RC_URL/api/v1/rooms.saveNotification
done
User als Owner für alle Gruppen setzen:
new_owner_user_id=...
for room_id in $(curl --header "X-User-Id: $USER_ID" --header "X-Auth-Token: $AUTH_TOKEN" --header "Content-type: application/json" https://$RC_URL/api/v1/groups.listAll\?count\=100 | jq '.groups[] | select(.t == "p")._id'); do
echo "Room ID: $room_id"
curl \
--header "X-User-Id: $USER_ID" \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "Content-type: application/json" \
--data "{ \"roomId\": $room_id, \"userId\": \"$new_owner_user_id\" }" \
https://$RC_URL/api/v1/groups.addOwner
done
Liste aller Gruppen mit einem bestimmten Teilnehmer:
search_user=linus
for room_name in $(curl --header "X-User-Id: $USER_ID" --header "X-Auth-Token: $AUTH_TOKEN" --header "Content-type: application/json" https://$RC_URL/api/v1/groups.listAll\?count\=100 | jq '.groups[] | select(.t == "p").name' --raw-output); do
if curl \
--header "X-User-Id: $USER_ID" \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "Content-type: application/json" \
"https://$RC_URL/api/v1/groups.members?roomName=$room_name" --silent | grep "$search_user" > /dev/null; then
echo "User is in: $room_name"
fi
done
Channel löschen:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
--data '{ "roomName": "myroom" }' \
https://$RC_URL/api/v1/channels.delete
Alle Private Groups auflisten:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
https://$RC_URL/api/v1/groups.listAll
Private Group löschen - das geht nur, wenn der API-User auch Admin-Mitglied der Private Group ist:
curl \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
--data '{ "roomName": "myroom" }' \
https://$RC_URL/api/v1/groups.delete
Einen Member aus einem Channel entfernen:
curl \
--request DELETE \
--header "X-Auth-Token: $AUTH_TOKEN" \
--header "X-User-Id: $USER_ID" \
--header "Content-type: application/json" \
--data '{ "roomName": "myroom", "username": "userName" }' \
https://$RC_URL/api/v1/channels.kick
Migration von Server A nach Server B
Sicherstellen, dass auf Server A und B die gleiche Rocket.Chat-Version installiert ist.
# Host A
systemctl stop rocketchat
mongodump --db rocketchat --out /tmp/mongodump/
tar cvf backup.tar ~/backup
scp backup.tar hostb:...
# Host B
systemctl stop rocketchat
# deprecated synatx
# mongorestore /tmp/mongodump/rocketchat --db rocketchat --drop
mongorestore /tmp/mongodump/rocketchat --nsInclude='rocketchat.*' --drop
systemctl start rocketchat
Achtung! --drop
löscht alle Tablellen, die im Dump vorhanden sind, bevor es den Dump einfügt.
Troubleshooting
- Den einzigen Admin eines Raumes entfernt?
Schlecht, denn dann lässt sich der Raum auch vom globalen Admin-Account nicht mehr über die Rocket.Chat-Oberfläche administrieren.
Lösung: ausgewählte User per API einem Raum zuordnen, (einen) User zum Admin und Raum-Owner machen, Raum administrieren/löschen, unnötige Benutzer entfernen und zu hoch vergebene Rechte wieder entfernen.
- File-Uploads funktionieren nicht?
In
/var/log/messages
taucht folgendes auf?rocket-chat: ufs: cannot write chunk of file "YJQb5H6y7YaE9psAM" (ENOENT: no such file or directory, open '/tmp/ufs/YJQb5H6y7YaE9psAM') rocket-chat: ufs: cannot delete temp file "/tmp/ufs/YJQb5H6y7YaE9psAM" (ENOENT: no such file or directory, unlink '/tmp/ufs/YJQb5H6y7YaE9psAM') rocket-chat: [Error: FileNotFound: no file with id YJQb5H6y7YaE9psAM found]
Lösung:
mkdir /tmp/ufs chown rocketchat:rocketchat /tmp/ufs
- Login der Smartphone-App funktioniert auch nach Neuinstallation der App nicht?
2FA deaktivieren, Login, 2FA aktivieren
Client
Auf Fedora:
# https://github.com/RocketChat/Rocket.Chat.Electron/releases/
VER=3.9.14
dnf -y install https://github.com/RocketChat/Rocket.Chat.Electron/releases/download/$VER/rocketchat-$VER-linux-x86_64.rpm
Auf Fedora funktioniert auch der Flatpak-basierte Client (hatte bei mir allerdings ein paar Stabilitätsprobleme):
sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install flathub chat.rocket.RocketChat
Built on 2024-09-30