Experimental matrix support

This commit is contained in:
2026-05-02 12:59:30 +02:00
parent aaf516bcd5
commit 4033d214ff
7 changed files with 96 additions and 16 deletions

View File

@@ -1,10 +1,10 @@
# TellMe # TellMe
A server and client notifications system written in Python that alerts you of events via SimpleX chat. A server and client notifications system written in Python that alerts you of events via SimpleX chat or Matrix.
## Overview ## Overview
TellMe monitors for events (completed processes, server uptime, etc.) and sends notifications through a built-in server to SimpleX chat over websockets. Starting from version 2.2, TellMe supports [GoAlert](https://goalert.io) messages natively. TellMe monitors for events (completed processes, server uptime, etc.) and sends notifications through a built-in server to SimpleX chat or Matrix over websockets. Starting from version 2.2, TellMe supports [GoAlert](https://goalert.io) messages natively.
## Client Features ## Client Features
@@ -13,21 +13,59 @@ TellMe monitors for events (completed processes, server uptime, etc.) and sends
- **Watch commands**: `-w "command"` - Run a command periodically and notify on output - **Watch commands**: `-w "command"` - Run a command periodically and notify on output
- **Ping hosts**: `-P <host>` - Monitor host availability until it's reachable - **Ping hosts**: `-P <host>` - Monitor host availability until it's reachable
## Setup ## Server Setup
1. Configure the client in `~/.config/tellme/config.json`: ### Installation
```json
{ ```bash
"url": "http://your-server:8000", cd server/src
"webhook": "your-webhook-name" pip install -r requirements.txt
}
``` ```
2. Run the SimpleX CLI chat as a daemon. ### Configuration
3. Configure `/etc/tellme/hooks.yml` to map webhooks to SimpleX chatrooms. 1. Configure hooks in `/etc/tellme/hooks.yml`:
```yaml
2345555XE:
transport: "simplex"
target: "#Bottest"
```
4. Run the server and use the client CLI to send notifications. Supported transports: `simplex`, `matrix`
2. (Optional) Configure Matrix credentials in `/etc/tellme/config.yml`:
```yaml
matrix_homeserver: "https://matrix.org"
matrix_access_token: "syt_your_token_here"
matrix_user_id: "@yourbot:matrix.org"
```
#### Obtaining a Matrix Access Token
**Via Element Web (easiest):**
1. Log into Element (https://app.element.io or your homeserver's Element instance)
2. Go to **Settings** (gear icon) → **Help & About**
3. Scroll to **Access Token** → click "Reveal Access Token" → copy it
**Via Matrix API (curl):**
```bash
curl -X POST "https://your-homeserver.url/_matrix/client/v3/login" \
-H "Content-Type: application/json" \
-d '{"type":"m.login.password","user":"@youruser:homeserver","password":"yourpassword"}'
```
The response includes `access_token`.
**Important:**
- Use a dedicated bot account, not your personal one
- Keep the token secure (don't commit to git)
- Revoke it in Element settings if compromised
3. Run the SimpleX CLI chat as a daemon (for SimpleX transport).
4. Start the server:
```bash
python tellmesrv.py
```
## Ansible ## Ansible

View File

@@ -1,6 +1,6 @@
{ {
"name": "TellMe", "name": "TellMe",
"version": "2.2.0", "version": "3.0.0",
"description": "TellMe CLI", "description": "TellMe CLI",
"scripts": { "scripts": {
"dev": "webpack-dev-server --inline --hot" "dev": "webpack-dev-server --inline --hot"

View File

@@ -39,7 +39,7 @@ def sendmessage(message):
ran = True ran = True
__version__ = "2.2.0" __version__ = "3.0.0"
versionstring='Taurix TellMe v' + __version__ versionstring='Taurix TellMe v' + __version__
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)

View File

@@ -1,6 +1,6 @@
{ {
"name": "TellMe Server", "name": "TellMe Server",
"version": "2.2.0", "version": "3.0.0",
"description": "TellMe Server", "description": "TellMe Server",
"scripts": { "scripts": {
"dev": "webpack-dev-server --inline --hot" "dev": "webpack-dev-server --inline --hot"

0
server/src/config.yml Normal file
View File

View File

@@ -0,0 +1,4 @@
flask
websocket-client
pyyaml
matrix-client

View File

@@ -7,8 +7,9 @@ import random
import logging import logging
import os import os
from pprint import pprint from pprint import pprint
from matrix_client.client import MatrixClient
__version__ = "2.2.0" __version__ = "3.0.0"
versionstring='Taurix TellMe server v' + __version__ versionstring='Taurix TellMe server v' + __version__
log_dir = '/var/log/tellme' log_dir = '/var/log/tellme'
@@ -70,6 +71,30 @@ def send_smp_message(target, message):
return False return False
def send_matrix_message(target, message):
try:
homeserver = config.get('matrix_homeserver', 'https://matrix.org')
access_token = config.get('matrix_access_token')
user_id = config.get('matrix_user_id')
if not access_token or not user_id:
log.error("Matrix credentials not configured")
return False
client = MatrixClient(homeserver)
client.login(token=access_token, user_id=user_id)
room = client.join_room(target)
room.send_text(message)
client.logout()
log.info("Sent message to Matrix room %s" % (target))
return True
except Exception as e:
log.error("Failed to send message to Matrix: %s" % (e))
return False
def get_hook(hook_id): def get_hook(hook_id):
return hooks.get(str(hook_id)) return hooks.get(str(hook_id))
@@ -122,6 +147,19 @@ def webhook_receiver(id):
else: else:
log.error("No target found, dropping message") log.error("No target found, dropping message")
return jsonify({'message': 'No target found, dropping message'}), 400 return jsonify({'message': 'No target found, dropping message'}), 400
elif transport == 'matrix':
if target is not None:
log.info(target)
if message is not None:
send_matrix_message(target, message)
else:
log.error("No message, dropping")
else:
log.error("No target found, dropping message")
return jsonify({'message': 'No target found, dropping message'}), 400
else:
log.error("Unknown transport: %s" % (transport))
return jsonify({'message': 'Unknown transport'}), 400
else: else:
log.error("No transport found, dropping message") log.error("No transport found, dropping message")
return jsonify({'message': 'No transport found, dropping message'}), 400 return jsonify({'message': 'No transport found, dropping message'}), 400