Compare commits

..

3 Commits

Author SHA1 Message Date
80ba03fdf9 Add Nextcloud Talk support 2026-05-14 13:14:44 +02:00
3c4acd0a47 Fix formatting 2026-05-13 14:24:37 +02:00
c8624e4799 Add support for Goalert rotations 2026-05-13 13:45:07 +02:00
5 changed files with 75 additions and 4 deletions

View File

@@ -1,5 +1,13 @@
# Changelog # Changelog
## [2.5.0] - 2026-05-14
### Added
- Added Nextcloud Talk support via OCS Chat API
## [2.4.0] - 2026-05-13
### Added
- Added support for GoAlert Rotation shift changes
## [2.3.0] - 2026-05-04 ## [2.3.0] - 2026-05-04
### Added ### Added
- Matrix/Element support via matrix-nio - Matrix/Element support via matrix-nio

View File

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

View File

@@ -1,4 +1,8 @@
--- ---
matrix_homeserver: "" matrix_homeserver: ""
matrix_access_token": "" matrix_access_token: ""
matrix_user_id: "" matrix_user_id: ""
nextcloud_server: ""
nextcloud_username: ""
nextcloud_password: ""

View File

@@ -2,3 +2,8 @@
2345555XE: 2345555XE:
transport: "simplex" transport: "simplex"
target: "#Bottest" target: "#Bottest"
# Nextcloud Talk example:
# myhook:
# transport: "nextcloud"
# target: "conversation_token_here"

View File

@@ -10,8 +10,12 @@ from pprint import pprint
from nio import AsyncClient, MatrixRoom, RoomMessageText from nio import AsyncClient, MatrixRoom, RoomMessageText
from nio.exceptions import OlmUnverifiedDeviceError from nio.exceptions import OlmUnverifiedDeviceError
import asyncio import asyncio
import urllib.request
import urllib.parse
import urllib.error
import base64
__version__ = "2.3.0" __version__ = "2.5.0"
versionstring='Taurix TellMe server v' + __version__ versionstring='Taurix TellMe server v' + __version__
log_dir = '/var/log/tellme' log_dir = '/var/log/tellme'
@@ -198,6 +202,38 @@ def send_matrix_message(target, message):
return False return False
def send_nextcloud_message(target, message):
try:
server = config.get('nextcloud_server')
username = config.get('nextcloud_username')
password = config.get('nextcloud_password')
if not server or not username or not password:
log.error("Nextcloud Talk credentials not configured")
return False
url = f"{server.rstrip('/')}/ocs/v2.php/apps/spreed/api/v1/chat/{target}"
credentials = base64.b64encode(f"{username}:{password}".encode()).decode()
data = urllib.parse.urlencode({'message': message}).encode()
req = urllib.request.Request(url, data=data)
req.add_header('OCS-APIRequest', 'true')
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
req.add_header('Authorization', f'Basic {credentials}')
response = urllib.request.urlopen(req)
log.info("Nextcloud Talk message sent to conversation %s, response: %d" % (target, response.status))
return True
except urllib.error.HTTPError as e:
log.error("Nextcloud Talk HTTP error: %d %s" % (e.code, e.reason))
return False
except Exception as e:
log.error("Failed to send Nextcloud Talk message: %s" % (e))
return False
def get_hook(hook_id): def get_hook(hook_id):
global hooks global hooks
hook = hooks.get(str(hook_id)) hook = hooks.get(str(hook_id))
@@ -234,6 +270,12 @@ def webhook_receiver(id):
if type == 'AlertStatus': if type == 'AlertStatus':
message = ("Alert %s: %s" % (data.get('AlertID'), data.get('LogEntry'))) message = ("Alert %s: %s" % (data.get('AlertID'), data.get('LogEntry')))
if type == 'ScheduleOnCallUsers':
message = ("On call rotation for schedule %s changed to user(s):" % (data.get('ScheduleName')))
users = data.get('Users')
for user in users:
message = ("%s %s" % (message, user.get('Name')))
hook = get_hook(id) hook = get_hook(id)
if hook is None: if hook is None:
@@ -268,6 +310,18 @@ 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 == 'nextcloud':
if target is not None:
log.info(target)
if message is not None:
if not send_nextcloud_message(target, message):
return jsonify({'message': 'Failed to send Nextcloud Talk message'}), 500
else:
log.error("No message, dropping")
return jsonify({'message': 'No message, dropping'}), 400
else:
log.error("No target found, dropping message")
return jsonify({'message': 'No target found, dropping message'}), 400
else: else:
log.error("Unknown transport: %s" % (transport)) log.error("Unknown transport: %s" % (transport))
return jsonify({'message': 'Unknown transport'}), 400 return jsonify({'message': 'Unknown transport'}), 400