Nachrichten von FHEM zu Matrix Synapse senden

Begonnen von DecaTec, 03 Mai 2021, 12:42:21

Vorheriges Thema - Nächstes Thema

Torxgewinde

Hallo,
Das bekannte Problem, wenn der Longpoll noch aktiv ist und man dann eine Nachricht senden möchte, ist nun gelöst - man braucht also nicht zwei Devices einrichten.

Es wird das Attribut set01IExpr ein wenig ungewöhnlich genutzt um vor dem Senden ein wenig Perlcode auszuführen. So wird dann der longpoll-Aufruf vorzeitig beendet und das set01 kann seine Arbeit verrichten ohne extra warten zu müssen:
attr MatrixBot set01IExpr #cancel an active longpoll\
if ($hash->{BUSY}\
    && $hash->{HttpUtils}\
    && $hash->{HttpUtils}->{url} =~ m|^https://[^/]+/_matrix/client/v3/sync\?timeout=\d+&filter=| ) {\
    Log(3, "$name: longpoll active, cutting it off now");;\
    HttpUtils_Close($hash->{HttpUtils});;\
}\
\
#just return $val unteraltered\
$val

Warum das Probleme machte kann ich nur eingrenzen auf den Abschnitt aus der 98_HTTPMOD.pm:
    if ($hash->{BUSY}) {            # still waiting for reply to last request
        if ($now > $last + max(15, AttrVal($name, "timeout", 2) *2)) {
            Log3 $name, 5, "$name: HandleSendQueue - still waiting for reply, timeout is over twice - this should never happen. Stop waiting";
            $hash->{BUSY} = 0;      # waited long enough, clear busy flag and continue
        }
Obwohl das Timeout auf 65 Sekunden steht und auch .LASTSEND auf sinnvollen Werten steht, springt HTTPMOD in das Fehlerhandling, das einfach nur busy auf 0 setzt, ohne den ggf. noch aktiven longpoll darüber zu informieren. Als Reaktion darauf kann es passieren, dass die ReadCallback-Funktion dann zweimal aufgerufen wird, die Ergebnisse aber bei dem falschem Reading landen. Wie auch immer, so wie oben umschiffe ich das Problem.

Hier das ganze Device zum einfachen Einrichten:
defmod MatrixBot HTTPMOD none 0
attr MatrixBot userattr MatrixRoomID MatrixServer MatrixUser
attr MatrixBot MatrixRoomID !12345678901234:nope.chat
attr MatrixBot MatrixServer nope.chat
attr MatrixBot MatrixUser DeinUsername
attr MatrixBot bodyDecode utf-8
attr MatrixBot bodyEncode utf-8
attr MatrixBot comment "\
Create a room for FHEM.\
\
The room must not use encryption, a room that has encryption\
enabled, cannot be converted to a non-encrypted room anymore \
\
The room-id can be found in Element-Web at:\
Room Settings --> Advanced --> Internal room ID\
\
To store the password in FHEM in obfuscated way:\
set MatrixBot storeKeyValue MatrixPassword yourPassword123\
\
###\
To send a text:\
set MatrixBot sendText Bla Bla Bla\
\
\
###\
To longpoll for messages once:\
# 1. send special filter to Matrix:\
set MatrixBot sendFilter\
\
# 2. start one longPoll (waits up to 60 seconds\
#                        or until data is available)\
get MatrixBot longpoll\
\
#alternatively, to keep on longPolling (this also sets filter):\
set MatrixBot longpollCmd startTimer\
#to stop the timers:\
set MatrixBot longpollCmd stopTimer\
\
#############################################################\
https://spec.matrix.org/v1.14/client-server-api/#syncing\
"
attr MatrixBot get02AlwaysNum 0
attr MatrixBot get02HeaderAuthorization Authorization: Bearer $sid
attr MatrixBot get02Name longpoll
attr MatrixBot get02Regex \"next_batch\":\s*\"(?<next_batch>[^\"]+)\"(?:.*?\"timeline\":\s*{\s*\"events\":\s*(?<messages>\[.*?\])\s*)?
attr MatrixBot get02TextArg 0
attr MatrixBot get02URL https://[$name:MatrixServer]/_matrix/client/v3/sync?timeout=60000&filter=[$name:filter_id]%%next_batch_param%%
attr MatrixBot icon message_info
attr MatrixBot parseFunction1 handleAuthErrors
attr MatrixBot reAuthAlways 0
attr MatrixBot reAuthRegex M_UNKNOWN_TOKEN
attr MatrixBot replacement01Mode expression
attr MatrixBot replacement01Regex \[([^:\s\[\"\']+):([^\]\s]+)\]
attr MatrixBot replacement01Value my $device = $name if ($1 eq "\$name") // $1;;\
ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");;
attr MatrixBot replacement02Mode expression
attr MatrixBot replacement02Regex %%uuid%%
attr MatrixBot replacement02Value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15))))
attr MatrixBot replacement03Mode key
attr MatrixBot replacement03Regex %%MatrixPassword%%
attr MatrixBot replacement03Value MatrixPassword
attr MatrixBot replacement04Mode expression
attr MatrixBot replacement04Regex %%next_batch_param%%
attr MatrixBot replacement04Value #is there a reading 'next_batch'?\
my $val = ReadingsVal($name, 'next_batch', '???');;\
\
#return the GET parameter 'sync=value' for /sync Endpoint\
return "&since=$val" if ($val ne '???');;\
\
#return neither since-key nor value for it:\
return "";;
attr MatrixBot set01Data {\
  "msgtype": "m.text",\
  "body": "$val"\
}
attr MatrixBot set01HeaderAuthorization Authorization: Bearer $sid
attr MatrixBot set01HeaderContent-Type application/json
attr MatrixBot set01IExpr #cancel an active longpoll\
if ($hash->{BUSY}\
    && $hash->{HttpUtils}\
    && $hash->{HttpUtils}->{url} =~ m|^https://[^/]+/_matrix/client/v3/sync\?timeout=\d+&filter=| ) {\
    Log(3, "$name: longpoll active, cutting it off now");;\
    HttpUtils_Close($hash->{HttpUtils});;\
}\
\
#just return $val unteraltered\
$val
attr MatrixBot set01Method POST
attr MatrixBot set01Name sendText
attr MatrixBot set01ParseResponse 1
attr MatrixBot set01Regex {\"event_id\":\"(.*)\"}
attr MatrixBot set01TextArg 1
attr MatrixBot set01URL https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%
attr MatrixBot set02Data {\
  "room": {\
    "rooms": ["[$name:MatrixRoomID]"],\
    "timeline": {\
      "limit": 10,\
      "types": ["m.room.message"]\
    },\
    "include_leave": false,\
    "include_join": false,\
    "include_account_data": false,\
    "include_state": false,\
    "state": {\
      "types": []\
    },\
    "ephemeral": {\
      "types": []\
    },\
    "account_data": {\
      "types": []\
    }\
  },\
  "event_fields": [\
    "content.body",\
    "sender",\
    "origin_server_ts"\
  ],\
  "event_format": "client",\
  "presence": {\
    "types": [],\
    "not_types": ["*"]\
  },\
  "account_data": {\
    "types": [],\
    "not_types": ["*"]\
  }\
}
attr MatrixBot set02HeaderAuthorization Authorization: Bearer $sid
attr MatrixBot set02HeaderContent-Type application/json
attr MatrixBot set02Method POST
attr MatrixBot set02Name sendFilter
attr MatrixBot set02NoArg 1
attr MatrixBot set02ParseResponse 1
attr MatrixBot set02Regex \"filter_id\":\s*\"(?<filter_id>\d+)\"
attr MatrixBot set02URL https://[$name:MatrixServer]/_matrix/client/v3/user/@[$name:MatrixUser]:[$name:MatrixServer]/filter
attr MatrixBot set03Local 1
attr MatrixBot set03Name longpollCmd
attr MatrixBot set03TextArg 1
attr MatrixBot showError 1
attr MatrixBot sid01Data {\
  "type": "m.login.password",\
  "identifier": {\
    "type": "m.id.user",\
    "user": "[$name:MatrixUser]"\
  },\
  "password": "%%MatrixPassword%%"\
}
attr MatrixBot sid01HeaderContent-Type application/json
attr MatrixBot sid01IdRegex "access_token"\s*:\s*"([^"]+)"
attr MatrixBot sid01URL https://[$name:MatrixServer]/_matrix/client/v3/login
attr MatrixBot timeout 65
attr MatrixBot userReadings longpollTimer:(next_batch|longpollCmd|LAST_ERROR|sendText):.* {\
  my $longpollCmd = ReadingsVal($name, 'longpollCmd', '???');;\
  my $delay = 1;;\
  my $timeout = AttrVal($name, 'timeout', 61) + $delay + 5;;\
  \
  # stop our timers:\
  if ($longpollCmd eq "stopTimer") {\
    fhem("cancel ${name}_longpollTimer quiet");;\
    fhem("cancel ${name}_longpollTimer2 quiet");;\
    return "stopped";;\
  }\
  \
  if ($longpollCmd ne "startTimer") {\
    return "no timer set, longpollCmd is not set to 'startTimer'";;\
  }\
  \
  #if startTimer cmd was given now, set filter as well:\
  if (ReadingsAge($name, 'longpollCmd', 0) <= 1) {\
    $delay = 5;; #delay to allow for sendFilter to be answered\
    #Log(1, "🪲 $name: >>". InternalVal($name, 'httpbody', '???') ."<<");;\
    fhem("sleep 0.1 quiet;; set $name sendFilter");;\
  }\
  \
  #we handle an error reported by http-utils:\
  if (ReadingsAge($name, 'LAST_ERROR', 0) <= 1) {\
    my $last_error = ReadingsVal($name, 'LAST_ERROR', '???');;\
    $delay = 10;; #delay to allow for error reasons to improve\
    #Log(1, "🪲 $name: Dealing with error: >>$last_error<<");;\
  }\
  \
  # for testing this: { $defs{MatrixBot}{sid} = 'bla' }\
  if (!defined &HTTPMOD::handleAuthErrors) {\
    *HTTPMOD::handleAuthErrors = sub {\
      my ($hash, $header, $body, $request) = @_;;\
      my $name = $hash->{NAME};;\
      my $status;;\
      \
      if ($header =~ m{^HTTP/\d\.\d\s+(\d+)}m) {\
        $status = $1;;\
      }\
      \
      Log3($name, 4, "$name: HTTP status code is $status");;\
      \
      if ( $status == 401 || $status == 403 || $status == 500 ) {\
        Log3($name, 3, "$name: auth-error or servererror ($status), calling doAuth()");;\
        HTTPMOD::DoAuth($hash);;\
      }\
    };;\
  }\
  \
  #set timers, one regular and one fallback:\
  fhem("sleep $delay ${name}_longpollTimer quiet;; get $name longpoll");;\
  fhem("sleep $timeout ${name}_longpollTimer2 quiet;; set $name longpollCmd startTimer");;\
  \
  return strftime("next longpoll at %H:%M:%S", localtime( time()+$delay ));;\
},\
messages_list:messages:.* {\
  my $this = ReadingsVal($name, $reading, '');;\
  my @timestampArray = split("\n", $this);;\
  my $messages_ref = decode_json(ReadingsVal($name, 'messages', ''));;\
  my $length = 20;;\
  \
  my %seen_messages = map { $_ => 1 } @timestampArray;;\
  \
  foreach my $msg (@$messages_ref) {\
    my $val = $msg->{content}{body};;\
    $val = Encode::decode('utf-8', $val) unless Encode::is_utf8($val);;\
    $val =~ s/\n/ /g;; #replace newlines with spaces\
    \
    my $sender = $msg->{sender};;\
    my $ts = strftime("%Y-%m-%d %H:%M:%S", localtime($msg->{origin_server_ts} / 1000));;\
    my $new_entry = "$ts: $sender: $val";;\
    \
    next if $seen_messages{$new_entry};;\
    \
    my $inserted = 0;;\
    for (my $i = 0;; $i < @timestampArray;; $i++) {\
      my ($existing_ts) = $timestampArray[$i] =~ /^([^:]+):/;;\
      if ($ts lt $existing_ts) {\
        splice(@timestampArray, $i, 0, $new_entry);;\
        $inserted = 1;;\
        last;;\
      }\
    }\
    push(@timestampArray, encode('utf-8', $new_entry)) unless $inserted;;\
    shift(@timestampArray) while @timestampArray > $length;;\
  }\
  \
  return join("\n", @timestampArray);;\
},\
process_messages:messages:.* {\
  my $val = ReadingsVal($name, 'messages_list', '');;\
  my $this = ReadingsVal($name, $reading, '');;\
  my $latest_ts = $this;;\
  \
  foreach my $line (split(/\n/, $val)) {\
    if ($line =~ /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}):\s*(.*)$/) {\
      my ($ts, $msg) = ($1, $2);;\
      \
      if ($ts gt $this) {\
        fhem("trigger $name msg: $line");;\
        $latest_ts = $ts if ($ts gt $latest_ts);;\
      }\
    }\
  }\
  return $latest_ts;;\
}
attr MatrixBot verbose 3
attr MatrixBot widgetOverride longpollCmd:uzsuSelectRadio,startTimer,stopTimer

Torxgewinde


riker1

#17
Hi
irgendwie bin ich zu blöd.
Matrix kenne ich auch wenig, mir scheint als ob ich laufend neue Access Token erhalte.

Wo muss ich denn im Device den Token angeben, ?

muss hier attr MatrixTRBot sid01IdRegex "access_token"\s*:\s*"([^"]+)"der token rein?

laufend die meldung falscher Token
der user muss doch mit @user:server eingegeben werden? richtig?

muss der Server als matrix.tchncs.de     oder nur   tchncs.de  eingegeben werden?

Danke für die Klarstellung
FHEM    5.26.1 Ubuntu 18, FHEM    5.26.1 RPI 3 , Actoren: IT ,Tasmota, ESPEasy,
MAX CUBE, MAX HT, MAX WT, Selbstbau nanoCULs, FS 20,Tasmota, Homematic, FTK, SW. DIM, Smoke,KODI,Squeezebox

Torxgewinde

Hi,
Den Token musst du garnicht selbst erstellen, das macht das Device für dich.

Nutzername und Server werden getrennt angegeben:
- attr MatrixUser FHEM_Nutzername_WieBeimServerOhneDoppelpunktUndOhneAt
- attr MatrixServer nope.chat (oder wo auch immer dein Matrix-Synapse-Server läuft)

Bezüglich des servers (ob mit Matrix. oder ohne) musste bitte einfach probieren. Ich meine es muss mit, da es auf eine andere IP verweist:

;; ANSWER SECTION:
matrix.tchncs.de. 110 IN CNAME h2.tchncs.de.
h2.tchncs.de. 423 IN A 135.181.232.169

;; ANSWER SECTION:
tchncs.de. 600 IN A 89.58.62.32

riker1

Zitat von: Torxgewinde am 23 Juli 2025, 11:22:47Hi,
Den Token musst du garnicht selbst erstellen, das macht das Device für dich.

Nutzername und Server werden getrennt angegeben:
- attr MatrixUser FHEM_Nutzername_WieBeimServerOhneDoppelpunktUndOhneAt
- attr MatrixServer nope.chat (oder wo auch immer dein Matrix-Synapse-Server läuft)

Bezüglich des servers (ob mit Matrix. oder ohne) musste bitte einfach probieren. Ich meine es muss mit, da es auf eine andere IP verweist:

;; ANSWER SECTION:
matrix.tchncs.de. 110 IN CNAME h2.tchncs.de.
h2.tchncs.de. 423 IN A 135.181.232.169

;; ANSWER SECTION:
tchncs.de. 600 IN A 89.58.62.32

alles klar danke, aber irgendwie schaffe ich es nicht.
habe mal parallel die andere sendefunktoin mit myutils eingebunden, da klappt das senden.

Habe hier aber noch andere Fehler, eventuell ist das das Problem:
als Server habe ich : https://matrix.tchncs.de
errors:
2025.07.24 10:35:50.386 5: MatrixTRBot: calling parseFunction1 as handleAuthErrors via attr for HTTP Response to set02
2025.07.24 10:35:50.386 1: PERL ERROR: Undefined subroutine &HTTPMOD::handleAuthErrors called at ./FHEM/98_HTTPMOD.pm line 1469.

modulversion: 98_HTTPMOD.pm:0.291590/2024-09-23  ein update ergab alles ok


Wo kann ich noch schauen? was mache ich falsch?
Danke

log 2025.07.24 10:35:37.402 4: MatrixTRBot: Read callback: request type was set02 retry 0, header: HTTP/1.1 401 Unauthorized Server: openresty Date: Thu, 24 Jul 2025 08:35:33 GMT Content-Type: application/json Connection: close Content-Encoding: gzip Cache-Control: no-cache, no-store, must-revalidate Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Date Access-Control-Expose-Headers: Synapse-Trace-Id, Server Strict-Transport-Security: max-age=31536000; includeSubdomains; preload, body length 88
2025.07.24 10:35:37.403 5: MatrixTRBot: Read callback: body {"errcode":"M_UNKNOWN_TOKEN","error":"Invalid access token passed.","soft_logout":false}
2025.07.24 10:35:37.403 4: MatrixTRBot: BodyDecode is decoding the response body as utf-8 but charset header is not found
2025.07.24 10:35:37.403 5: MatrixTRBot: GetCookies is looking for Cookies
2025.07.24 10:35:37.404 5: MatrixTRBot: ExtractSid called, context set, num 02
2025.07.24 10:35:37.404 4: MatrixTRBot: checking for redirects, code=401, ignore=0
2025.07.24 10:35:37.404 4: MatrixTRBot: no redirects to handle
2025.07.24 10:35:37.404 5: MatrixTRBot: Read callback sets LAST_REQUEST to set02
2025.07.24 10:35:37.405 5: MatrixTRBot: CheckAuth is checking buffer with ReAuthRegex (?^:M_UNKNOWN_TOKEN)
2025.07.24 10:35:37.405 4: MatrixTRBot: CheckAuth decided new authentication required
2025.07.24 10:35:37.405 5: MatrixTRBot: AddToQueue prepends type set02 to URL https://[$name:MatrixServer]/_matrix/client/v3/user/@[$name:MatrixUser]:[$name:MatrixServer]/filter, data { "room": { "rooms": ["[$name:MatrixRoomID]"], "timeline": { "limit": 10, "types": ["m.room.message"] }, "include_leave": false, "include_join": false, "include_account_data": false, "include_state": false, "state": { "types": [] }, "ephemeral": { "types": [] }, "account_data": { "types": [] } }, "event_fields": [ "content.body", "sender", "origin_server_ts" ], "event_format": "client", "presence": { "types": [], "not_types": ["*"] }, "account_data": { "types": [], "not_types": ["*"] } }, header Authorization: Bearer $sid application/json, retry 1, initial queue len: 0
2025.07.24 10:35:37.405 4: MatrixTRBot: CheckAuth prepended request set02 again before auth, retryCount 0 ...
2025.07.24 10:35:37.406 4: MatrixTRBot: DoAuth called with Steps: 01
2025.07.24 10:35:37.406 5: MatrixTRBot: AddToQueue prepends type auth01 to URL https://[$name:MatrixServer]/_matrix/client/v3/login, data { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }, header application/json, retry 0, initial queue len: 1
2025.07.24 10:35:37.407 5: MatrixTRBot: HandleSendQueue called from DoAuth, qlen = 2
2025.07.24 10:35:37.407 5: MatrixTRBot: Replace called for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: application/json
2025.07.24 10:35:37.407 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: application/json
2025.07.24 10:35:37.407 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: application/json
2025.07.24 10:35:37.408 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 10:35:37.409 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: application/json
2025.07.24 10:35:37.409 5: MatrixTRBot: Replace called for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }
2025.07.24 10:35:37.409 5: MatrixTRBot: Replace: match for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value package main; my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");, input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }, result is { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "%%MatrixPassword%%" }
2025.07.24 10:35:37.410 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "%%MatrixPassword%%" }
2025.07.24 10:35:37.410 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "%%MatrixPassword%%" }
2025.07.24 10:35:37.410 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 10:35:37.411 5: MatrixTRBot: Replace: key MatrixPassword value is xxxxx
2025.07.24 10:35:37.411 5: MatrixTRBot: Replace: match for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword, input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }, result is { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "myPassWDMatrix" }
2025.07.24 10:35:37.411 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "myPassWDMatrix" }
2025.07.24 10:35:37.411 5: MatrixTRBot: Replace called for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: https://[$name:MatrixServer]/_matrix/client/v3/login
2025.07.24 10:35:37.412 5: MatrixTRBot: Replace: match for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value package main; my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");, input: https://[$name:MatrixServer]/_matrix/client/v3/login, result is https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 10:35:37.412 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 10:35:37.412 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 10:35:37.412 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 10:35:37.413 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 10:35:37.413 5: MatrixTRBot: no separator for multiple values (Context auth01, 01)
2025.07.24 10:35:37.413 4: MatrixTRBot: HandleSendQueue sends auth01 with timeout 65 to https://matrix.tchncs.de/_matrix/client/v3/login, data: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "myPassWDMatrix" }, header: application/json
2025.07.24 10:35:37.415 5: MatrixTRBot: StartQueueTimer called from HandleSendQueue sets internal timer to process queue in 1.000 seconds

2025.07.24 10:35:50.383 4: MatrixTRBot: Read callback: request type was set02 retry 1, header: HTTP/1.1 401 Unauthorized Server: openresty Date: Thu, 24 Jul 2025 08:35:48 GMT Content-Type: application/json Connection: close Content-Encoding: gzip Cache-Control: no-cache, no-store, must-revalidate Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Date Access-Control-Expose-Headers: Synapse-Trace-Id, Server Strict-Transport-Security: max-age=31536000; includeSubdomains; preload, body length 88
2025.07.24 10:35:50.383 5: MatrixTRBot: Read callback: body {"errcode":"M_UNKNOWN_TOKEN","error":"Invalid access token passed.","soft_logout":false}
2025.07.24 10:35:50.383 4: MatrixTRBot: BodyDecode is decoding the response body as utf-8 but charset header is not found
2025.07.24 10:35:50.383 5: MatrixTRBot: GetCookies is looking for Cookies
2025.07.24 10:35:50.384 5: MatrixTRBot: ExtractSid called, context set, num 02
2025.07.24 10:35:50.384 4: MatrixTRBot: checking for redirects, code=401, ignore=0
2025.07.24 10:35:50.384 4: MatrixTRBot: no redirects to handle
2025.07.24 10:35:50.384 5: MatrixTRBot: Read callback sets LAST_REQUEST to set02
2025.07.24 10:35:50.384 5: MatrixTRBot: CheckAuth is checking buffer with ReAuthRegex (?^:M_UNKNOWN_TOKEN)
2025.07.24 10:35:50.385 4: MatrixTRBot: CheckAuth decided new authentication required
2025.07.24 10:35:50.385 4: MatrixTRBot: Authentication still required but no retries left - did last authentication fail?
2025.07.24 10:35:50.385 5: MatrixTRBot: ExtractReading sendFilter with regex /(?^:\"filter_id\":\s*\"(?<filter_id>\d+)\")/...
2025.07.24 10:35:50.385 5: MatrixTRBot: ExtractReading sendFilter did not match
2025.07.24 10:35:50.385 4: MatrixTRBot: Read response to set02 didn't match any Reading
2025.07.24 10:35:50.386 5: MatrixTRBot: calling parseFunction1 as handleAuthErrors via attr for HTTP Response to set02
2025.07.24 10:35:50.386 1: PERL ERROR: Undefined subroutine &HTTPMOD::handleAuthErrors called at ./FHEM/98_HTTPMOD.pm line 1469.
2025.07.24 10:35:50.386 1: stacktrace:
2025.07.24 10:35:50.386 1: main::__ANON__ called by ./FHEM/98_HTTPMOD.pm (1469)
2025.07.24 10:35:50.386 1: (eval) called by ./FHEM/98_HTTPMOD.pm (1469)
2025.07.24 10:35:50.386 1: HTTPMOD::HandleParseFunctions called by ./FHEM/98_HTTPMOD.pm (2529)
2025.07.24 10:35:50.386 1: HTTPMOD::ReadCallback called by FHEM/HttpUtils.pm (756)
2025.07.24 10:35:50.387 1: main::__ANON__ called by fhem.pl (786)
2025.07.24 10:35:50.387 3: MatrixTRBot: error calling handleAuthErrors: Undefined subroutine &HTTPMOD::handleAuthErrors called at ./FHEM/98_HTTPMOD.pm line 1469.
2025.07.24 10:35:50.387 5: MatrixTRBot: HandleSendQueue called from ReadCallback, qlen = 0
2025.07.24 10:35:50.387 5: MatrixTRBot: HandleSendQueue found no usable entry in queue



FHEM    5.26.1 Ubuntu 18, FHEM    5.26.1 RPI 3 , Actoren: IT ,Tasmota, ESPEasy,
MAX CUBE, MAX HT, MAX WT, Selbstbau nanoCULs, FS 20,Tasmota, Homematic, FTK, SW. DIM, Smoke,KODI,Squeezebox

Torxgewinde

Danke für das ausführliche Log, ich jubel HTTPMOD eine eigene Parsefunction unter, aber das scheint nicht in der Reihenfolge zu passieren, wie ich es beabsichtigte.

Kannst du testweise bitte in myUtils folgende Funktion packen:
sub handleAuthErrorsAusMyUtils {
    my ($hash, $header, $body, $request) = @_;
    my $name = $hash->{NAME};
    my $status;

    if ($header =~ m{^HTTP/\d\.\d\s+(\d+)}m) {
        $status = $1;
    }

    Log3($name, 4, "$name: HTTP status code is $status");

    if ($status == 401 || $status == 403 || $status == 500) {
        Log3($name, 3, "$name: auth-error or servererror ($status), calling doAuth()");
        HTTPMOD::DoAuth($hash);
    }
}

Und im HTTPMOD device dann:
attr MatrixBot parseFunction1 handleAuthErrorsAusMyUtils
Wenn das so nichts wird, dann muss ich mal auf einem "frischem" FHEM debuggen.

riker1

Danke für die Hilfe

hier mal das log mit der erweiterten myUtil

hoffe habe alles gefunden


2025.07.24 21:06:40.790 5: MatrixTRBot: set called with sendText testmatrix
2025.07.24 21:06:40.790 5: MatrixTRBot: set found option sendText in attribute set01Name
2025.07.24 21:06:40.791 5: MatrixTRBot: set01IExpr evaluated package main; my @setValArr = @{$oRef->{'@setValArr'}};#cancel an active longpoll if ($hash->{BUSY} && $hash->{HttpUtils} && $hash->{HttpUtils}->{url} =~ m|^https://[^/]+/_matrix/client/v3/sync\?timeout=\d+&filter=| ) { Log(3, "$name: longpoll active, cutting it off now"); HttpUtils_Close($hash->{HttpUtils}); } #just return $val unteraltered $val to testmatrix
2025.07.24 21:06:40.791 4: MatrixTRBot: set will now set sendText -> testmatrix
2025.07.24 21:06:40.792 5: MatrixTRBot: AddToQueue adds type set01 to URL https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%, data { "msgtype": "m.text", "body": "$val" }, header Authorization: Bearer $sid application/json, retry 0, initial queue len: 0
2025.07.24 21:06:40.792 5: MatrixTRBot: HandleSendQueue called from AddToSendQueue, qlen = 1
2025.07.24 21:06:40.793 5: MatrixTRBot: HandleSendQueue - call with HTTP METHOD: POST
2025.07.24 21:06:40.793 5: MatrixTRBot: Replace called for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: Authorization: Bearer $sid application/json
2025.07.24 21:06:40.794 5: MatrixTRBot: Replace called for type set01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: Authorization: Bearer $sid application/json
2025.07.24 21:06:40.794 5: MatrixTRBot: Replace called for type set01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: Authorization: Bearer $sid application/json
2025.07.24 21:06:40.794 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:06:40.795 5: MatrixTRBot: Replace called for type set01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: Authorization: Bearer $sid application/json
2025.07.24 21:06:40.795 5: MatrixTRBot: Replace called for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:06:40.795 5: MatrixTRBot: Replace called for type set01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:06:40.796 5: MatrixTRBot: Replace called for type set01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:06:40.796 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:06:40.796 5: MatrixTRBot: Replace called for type set01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:06:40.797 5: MatrixTRBot: Replace called for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%
2025.07.24 21:06:40.797 5: MatrixTRBot: Replace: match for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value package main; my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");, input: https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%, result is https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=%%uuid%%
2025.07.24 21:06:40.797 5: MatrixTRBot: Replace called for type set01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=%%uuid%%
2025.07.24 21:06:40.798 5: MatrixTRBot: Replace: match for type set01, regex (?^:%%uuid%%), mode expression, value package main; join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))), input: https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%, result is https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=db50df5c-6d2b-b7b3-1da1-859c4803461f
2025.07.24 21:06:40.798 5: MatrixTRBot: Replace called for type set01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=db50df5c-6d2b-b7b3-1da1-859c4803461f
2025.07.24 21:06:40.798 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:06:40.798 5: MatrixTRBot: Replace called for type set01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=db50df5c-6d2b-b7b3-1da1-859c4803461f
2025.07.24 21:06:40.799 5: MatrixTRBot: no separator for multiple values (Context set01, 01)
2025.07.24 21:06:40.799 4: MatrixTRBot: HandleSendQueue sends set01 with timeout 65 to https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=db50df5c-6d2b-b7b3-1da1-859c4803461f, data: { "msgtype": "m.text", "body": "testmatrix" }, header: Authorization: Bearer $sid application/json
2025-07-24 21:06:40.808 HTTPMOD MatrixTRBot sendText testmatrix
2025.07.24 21:06:53.943 5: MatrixTRBot: ReadCallback called from __ANON__
2025.07.24 21:06:53.943 4: MatrixTRBot: Read callback: request type was set01 retry 0, header: HTTP/1.1 401 Unauthorized Server: openresty Date: Thu, 24 Jul 2025 19:06:47 GMT Content-Type: application/json Connection: close Cache-Control: no-cache, no-store, must-revalidate Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Date Access-Control-Expose-Headers: Synapse-Trace-Id, Server Strict-Transport-Security: max-age=31536000; includeSubdomains; preload, body length 88
2025.07.24 21:06:53.943 5: MatrixTRBot: Read callback: body {"errcode":"M_UNKNOWN_TOKEN","error":"Invalid access token passed.","soft_logout":false}
2025.07.24 21:06:53.943 4: MatrixTRBot: BodyDecode is decoding the response body as utf-8 but charset header is not found
2025.07.24 21:06:53.944 5: MatrixTRBot: GetCookies is looking for Cookies
2025.07.24 21:06:53.944 5: MatrixTRBot: ExtractSid called, context set, num 01
2025.07.24 21:06:53.944 4: MatrixTRBot: checking for redirects, code=401, ignore=0
2025.07.24 21:06:53.944 4: MatrixTRBot: no redirects to handle
2025.07.24 21:06:53.944 5: MatrixTRBot: Read callback sets LAST_REQUEST to set01
2025.07.24 21:06:53.945 5: MatrixTRBot: CheckAuth is checking buffer with ReAuthRegex (?^:M_UNKNOWN_TOKEN)
2025.07.24 21:06:53.945 4: MatrixTRBot: CheckAuth decided new authentication required
2025.07.24 21:06:53.945 5: MatrixTRBot: AddToQueue prepends type set01 to URL https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%, data { "msgtype": "m.text", "body": "$val" }, header Authorization: Bearer $sid application/json, retry 1, initial queue len: 0
2025.07.24 21:06:53.945 4: MatrixTRBot: CheckAuth prepended request set01 again before auth, retryCount 0 ...
2025.07.24 21:06:53.945 4: MatrixTRBot: DoAuth called with Steps: 01
2025.07.24 21:06:53.946 5: MatrixTRBot: AddToQueue prepends type auth01 to URL https://[$name:MatrixServer]/_matrix/client/v3/login, data { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }, header application/json, retry 0, initial queue len: 1
2025.07.24 21:06:53.946 5: MatrixTRBot: HandleSendQueue called from DoAuth, qlen = 2
2025.07.24 21:06:53.946 5: MatrixTRBot: Replace called for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: application/json
2025.07.24 21:06:53.947 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: application/json
2025.07.24 21:06:53.947 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: application/json
2025.07.24 21:06:53.947 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:06:53.947 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: application/json
2025.07.24 21:06:53.948 5: MatrixTRBot: Replace called for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }
2025.07.24 21:06:53.948 5: MatrixTRBot: Replace: match for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value package main; my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");, input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }, result is { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "%%MatrixPassword%%" }
2025.07.24 21:06:53.948 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "%%MatrixPassword%%" }
2025.07.24 21:06:53.948 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "%%MatrixPassword%%" }
2025.07.24 21:06:53.948 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:06:53.949 5: MatrixTRBot: Replace: key MatrixPassword value is myPassWDMatrix
2025.07.24 21:06:53.949 5: MatrixTRBot: Replace: match for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword, input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "[$name:MatrixUser]" }, "password": "%%MatrixPassword%%" }, result is { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "myPassWDMatrix" }
2025.07.24 21:06:53.949 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "myPassWDMatrix" }
2025.07.24 21:06:53.949 5: MatrixTRBot: Replace called for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: https://[$name:MatrixServer]/_matrix/client/v3/login
2025.07.24 21:06:53.950 5: MatrixTRBot: Replace: match for type auth01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value package main; my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");, input: https://[$name:MatrixServer]/_matrix/client/v3/login, result is https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 21:06:53.950 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 21:06:53.950 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 21:06:53.950 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:06:53.950 5: MatrixTRBot: Replace called for type auth01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: https://matrix.tchncs.de/_matrix/client/v3/login
2025.07.24 21:06:53.951 5: MatrixTRBot: no separator for multiple values (Context auth01, 01)
2025.07.24 21:06:53.951 4: MatrixTRBot: HandleSendQueue sends auth01 with timeout 65 to https://matrix.tchncs.de/_matrix/client/v3/login, data: { "type": "m.login.password", "identifier": { "type": "m.id.user", "user": "fhemtrbotmatrix" }, "password": "myPassWDMatrix" }, header: application/json
2025.07.24 21:06:53.952 5: MatrixTRBot: StartQueueTimer called from HandleSendQueue sets internal timer to process queue in 1.000 seconds
2025.07.24 21:06:56.212 5: MatrixTRBot: HandleSendQueue called from Fhem internal timer, qlen = 1
2025.07.24 21:06:56.213 5: MatrixTRBot: StartQueueTimer called from ReadyForSending sets internal timer to process queue in 2.000 seconds, still waiting for reply to last request

2025.07.24 21:07:05.507 5: MatrixTRBot: ReadCallback called from __ANON__
2025.07.24 21:07:05.508 4: MatrixTRBot: Read callback: request type was auth01 retry 0, header: HTTP/1.1 200 OK Server: openresty Date: Thu, 24 Jul 2025 19:06:59 GMT Content-Type: application/json Connection: close Content-Encoding: gzip Cache-Control: no-cache, no-store, must-revalidate Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Date Access-Control-Expose-Headers: Synapse-Trace-Id, Server Permissions-Policy: interest-cohort=() X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block Referrer-Policy: no-referrer Content-Security-Policy: default-src 'self' *.tchncs.de tchncs.de Strict-Transport-Security: max-age=31536000; includeSubdomains; preload, body length 232
2025.07.24 21:07:05.514 5: MatrixTRBot: Read callback: body {"user_id":"@fhemtrbotmatrix:tchncs.de","access_token":"syt_ZmhlbXRyYm90bWF0cml4_GVMmwnokCWwJjAeuXkQa_1x4dDx","home_server":"tchncs.de","device_id":"MHZTCPFVYG","well_known":{"m.homeserver":{"base_url":"https://matrix.tchncs.de/"}}}
2025.07.24 21:07:05.515 4: MatrixTRBot: BodyDecode is decoding the response body as utf-8 but charset header is not found
2025.07.24 21:07:05.515 5: MatrixTRBot: GetCookies is looking for Cookies
2025.07.24 21:07:05.515 5: MatrixTRBot: ExtractSid called, context sid, num 01
2025.07.24 21:07:05.516 5: MatrixTRBot: ExtractSid could not match buffer to IdRegex (?^:"access_toke"\s*:\s*"([^"]+)")
2025.07.24 21:07:05.516 4: MatrixTRBot: checking for redirects, code=200, ignore=0
2025.07.24 21:07:05.516 4: MatrixTRBot: no redirects to handle
2025.07.24 21:07:05.517 5: MatrixTRBot: Read callback sets LAST_REQUEST to auth01

2025.07.24 21:07:06.555 5: MatrixTRBot: HandleSendQueue called from Fhem internal timer, qlen = 1
2025.07.24 21:07:06.556 5: MatrixTRBot: HandleSendQueue - call with HTTP METHOD: POST
2025.07.24 21:07:06.557 5: MatrixTRBot: Replace called for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: Authorization: Bearer $sid application/json
2025.07.24 21:07:06.557 5: MatrixTRBot: Replace called for type set01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: Authorization: Bearer $sid application/json
2025.07.24 21:07:06.557 5: MatrixTRBot: Replace called for type set01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: Authorization: Bearer $sid application/json
2025.07.24 21:07:06.557 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:07:06.558 5: MatrixTRBot: Replace called for type set01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: Authorization: Bearer $sid application/json
2025.07.24 21:07:06.558 5: MatrixTRBot: Replace called for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:07:06.559 5: MatrixTRBot: Replace called for type set01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:07:06.559 5: MatrixTRBot: Replace called for type set01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:07:06.559 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:07:06.559 5: MatrixTRBot: Replace called for type set01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: { "msgtype": "m.text", "body": "$val" }
2025.07.24 21:07:06.559 5: MatrixTRBot: Replace called for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???"); input: https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%
2025.07.24 21:07:06.560 5: MatrixTRBot: Replace: match for type set01, regex (?^:\[([^:\s\[\"\']+):([^\]\s]+)\]), mode expression, value package main; my $device = $name if ($1 eq "\$name") // $1; ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");, input: https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%, result is https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=%%uuid%%
2025.07.24 21:07:06.560 5: MatrixTRBot: Replace called for type set01, regex (?^:%%uuid%%), mode expression, value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))) input: https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=%%uuid%%
2025.07.24 21:07:06.560 5: MatrixTRBot: Replace: match for type set01, regex (?^:%%uuid%%), mode expression, value package main; join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15)))), input: https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%, result is https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=ece21d38-071a-34e5-ba75-847bb625e773
2025.07.24 21:07:06.560 5: MatrixTRBot: Replace called for type set01, regex (?^:%%MatrixPassword%%), mode key, value MatrixPassword input: https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=ece21d38-071a-34e5-ba75-847bb625e773
2025.07.24 21:07:06.561 5: MatrixTRBot: ReadKeyValue tries to read value for MatrixPassword from file
2025.07.24 21:07:06.561 5: MatrixTRBot: Replace called for type set01, regex (?^:%%next_batch_param%%), mode expression, value #is there a reading 'next_batch'? my $val = ReadingsVal($name, 'next_batch', '???'); #return the GET parameter 'sync=value' for /sync Endpoint return "&since=$val" if ($val ne '???'); #return neither since-key nor value for it: return ""; input: https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=ece21d38-071a-34e5-ba75-847bb625e773
2025.07.24 21:07:06.561 5: MatrixTRBot: no separator for multiple values (Context set01, 01)
2025.07.24 21:07:06.561 4: MatrixTRBot: HandleSendQueue sends set01 with timeout 65 to https://matrix.tchncs.de/_matrix/client/v3/rooms/!XhbARBYHuWpihSbkCF:tchncs.de/send/m.room.message?txnId=ece21d38-071a-34e5-ba75-847bb625e773, data: { "msgtype": "m.text", "body": "testmatrix" }, header: Authorization: Bearer $sid application/json


2025.07.24 21:07:18.822 5: MatrixTRBot: ReadCallback called from __ANON__
2025.07.24 21:07:18.822 4: MatrixTRBot: Read callback: request type was set01 retry 1, header: HTTP/1.1 401 Unauthorized Server: openresty Date: Thu, 24 Jul 2025 19:07:11 GMT Content-Type: application/json Connection: close Cache-Control: no-cache, no-store, must-revalidate Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Date Access-Control-Expose-Headers: Synapse-Trace-Id, Server Strict-Transport-Security: max-age=31536000; includeSubdomains; preload, body length 88
2025.07.24 21:07:18.823 5: MatrixTRBot: Read callback: body {"errcode":"M_UNKNOWN_TOKEN","error":"Invalid access token passed.","soft_logout":false}
2025.07.24 21:07:18.823 4: MatrixTRBot: BodyDecode is decoding the response body as utf-8 but charset header is not found
2025.07.24 21:07:18.823 5: MatrixTRBot: GetCookies is looking for Cookies
2025.07.24 21:07:18.823 5: MatrixTRBot: ExtractSid called, context set, num 01
2025.07.24 21:07:18.824 4: MatrixTRBot: checking for redirects, code=401, ignore=0
2025.07.24 21:07:18.824 4: MatrixTRBot: no redirects to handle
2025.07.24 21:07:18.824 5: MatrixTRBot: Read callback sets LAST_REQUEST to set01
2025.07.24 21:07:18.824 5: MatrixTRBot: CheckAuth is checking buffer with ReAuthRegex (?^:M_UNKNOWN_TOKEN)
2025.07.24 21:07:18.825 4: MatrixTRBot: CheckAuth decided new authentication required
2025.07.24 21:07:18.825 4: MatrixTRBot: Authentication still required but no retries left - did last authentication fail?
2025.07.24 21:07:18.825 5: MatrixTRBot: ExtractReading sendText with regex /(?^:{\"event_id\":\"(.*)\"})/...
2025.07.24 21:07:18.826 5: MatrixTRBot: ExtractReading sendText did not match
2025.07.24 21:07:18.826 5: MatrixTRBot: UpdateReadingList created list of reading.* nums to parse during getUpdate as
2025.07.24 21:07:18.826 4: MatrixTRBot: Read response to set01 didn't match any Reading
2025.07.24 21:07:18.826 5: MatrixTRBot: calling parseFunction1 as handleAuthErrorsAusMyUtils via attr for HTTP Response to set01
2025.07.24 21:07:18.827 1: PERL ERROR: Undefined subroutine &HTTPMOD::handleAuthErrorsAusMyUtils called at ./FHEM/98_HTTPMOD.pm line 1469.
2025.07.24 21:07:18.827 1: stacktrace:
2025.07.24 21:07:18.827 1: main::__ANON__ called by ./FHEM/98_HTTPMOD.pm (1469)
2025.07.24 21:07:18.827 1: (eval) called by ./FHEM/98_HTTPMOD.pm (1469)
2025.07.24 21:07:18.827 1: HTTPMOD::HandleParseFunctions called by ./FHEM/98_HTTPMOD.pm (2529)
2025.07.24 21:07:18.828 1: HTTPMOD::ReadCallback called by FHEM/HttpUtils.pm (756)
2025.07.24 21:07:18.828 1: main::__ANON__ called by fhem.pl (786)
2025.07.24 21:07:18.828 3: MatrixTRBot: error calling handleAuthErrorsAusMyUtils: Undefined subroutine &HTTPMOD::handleAuthErrorsAusMyUtils called at ./FHEM/98_HTTPMOD.pm line 1469.
2025.07.24 21:07:18.828 5: MatrixTRBot: HandleSendQueue called from ReadCallback, qlen = 0
2025.07.24 21:07:18.828 5: MatrixTRBot: HandleSendQueue found no usable entry in queue
FHEM    5.26.1 Ubuntu 18, FHEM    5.26.1 RPI 3 , Actoren: IT ,Tasmota, ESPEasy,
MAX CUBE, MAX HT, MAX WT, Selbstbau nanoCULs, FS 20,Tasmota, Homematic, FTK, SW. DIM, Smoke,KODI,Squeezebox

Torxgewinde

#22
Ok, ich habe mal einen Testaccount bei Tchncs.de gemacht und das Device bei Cooltux angelegt:

Dort (https://demo-fhem.cooltux.net/fhem?detail=MatrixBot) klappt es mit dieser Defintion:
define MatrixBot HTTPMOD none 0
attr MatrixBot userattr MatrixRoomID MatrixServer MatrixUser
attr MatrixBot MatrixRoomID !dhGzyuDtJxMUAguhhc:tchncs.de
attr MatrixBot MatrixServer tchncs.de
attr MatrixBot MatrixUser fhemtest
attr MatrixBot bodyDecode utf-8
attr MatrixBot bodyEncode utf-8
attr MatrixBot comment "\
Create a room for FHEM.\
\
The room must not use encryption, a room that has encryption\
enabled, cannot be converted to a non-encrypted room anymore \
\
The room-id can be found in Element-Web at:\
Room Settings --> Advanced --> Internal room ID\
\
To store the password in FHEM in obfuscated way:\
set MatrixBot storeKeyValue MatrixPassword yourPassword123\
\
###\
To send a text:\
set MatrixBot sendText Bla Bla Bla\
\
\
###\
To longpoll for messages once:\
# 1. send special filter to Matrix:\
set MatrixBot sendFilter\
\
# 2. start one longPoll (waits up to 60 seconds\
#                        or until data is available)\
get MatrixBot longpoll\
\
#alternatively, to keep on longPolling (this also sets filter):\
set MatrixBot longpollCmd startTimer\
#to stop the timers:\
set MatrixBot longpollCmd stopTimer\
\
#############################################################\
https://spec.matrix.org/v1.14/client-server-api/#syncing\
"
attr MatrixBot get02AlwaysNum 0
attr MatrixBot get02HeaderAuthorization Authorization: Bearer $sid
attr MatrixBot get02Name longpoll
attr MatrixBot get02Regex \"next_batch\":\s*\"(?<next_batch>[^\"]+)\"(?:.*?\"timeline\":\s*{\s*\"events\":\s*(?<messages>\[.*?\])\s*)?
attr MatrixBot get02TextArg 0
attr MatrixBot get02URL https://[$name:MatrixServer]/_matrix/client/v3/sync?timeout=60000&filter=[$name:filter_id]%%next_batch_param%%
attr MatrixBot icon message_info
attr MatrixBot parseFunction1 handleAuthErrors
attr MatrixBot reAuthAlways 0
attr MatrixBot reAuthRegex M_UNKNOWN_TOKEN
attr MatrixBot replacement01Mode expression
attr MatrixBot replacement01Regex \[([^:\s\[\"\']+):([^\]\s]+)\]
attr MatrixBot replacement01Value my $device = $name if ($1 eq "\$name") // $1;;\
ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");;
attr MatrixBot replacement02Mode expression
attr MatrixBot replacement02Regex %%uuid%%
attr MatrixBot replacement02Value join("-", unpack("A8 A4 A4 A4 A12", unpack("H*", join("", map { chr(int rand 256) } 0..15))))
attr MatrixBot replacement03Mode key
attr MatrixBot replacement03Regex %%MatrixPassword%%
attr MatrixBot replacement03Value MatrixPassword
attr MatrixBot replacement04Mode expression
attr MatrixBot replacement04Regex %%next_batch_param%%
attr MatrixBot replacement04Value #is there a reading 'next_batch'?\
my $val = ReadingsVal($name, 'next_batch', '???');;\
\
#return the GET parameter 'sync=value' for /sync Endpoint\
return "&since=$val" if ($val ne '???');;\
\
#return neither since-key nor value for it:\
return "";;
attr MatrixBot set01Data {\
  "msgtype": "m.text",\
  "body": "$val"\
}
attr MatrixBot set01HeaderAuthorization Authorization: Bearer $sid
attr MatrixBot set01HeaderContent-Type application/json
attr MatrixBot set01IExpr #cancel an active longpoll\
if ($hash->{BUSY}\
    && $hash->{HttpUtils}\
    && $hash->{HttpUtils}->{url} =~ m|^https://[^/]+/_matrix/client/v3/sync\?timeout=\d+&filter=| ) {\
    Log(3, "$name: longpoll active, cutting it off now");;\
    HttpUtils_Close($hash->{HttpUtils});;\
}\
\
#just return $val unteraltered\
$val
attr MatrixBot set01Method POST
attr MatrixBot set01Name sendText
attr MatrixBot set01ParseResponse 1
attr MatrixBot set01Regex {\"event_id\":\"(.*)\"}
attr MatrixBot set01TextArg 1
attr MatrixBot set01URL https://[$name:MatrixServer]/_matrix/client/v3/rooms/[$name:MatrixRoomID]/send/m.room.message?txnId=%%uuid%%
attr MatrixBot set02Data {\
  "room": {\
    "rooms": ["[$name:MatrixRoomID]"],\
    "timeline": {\
      "limit": 10,\
      "types": ["m.room.message"]\
    },\
    "include_leave": false,\
    "include_join": false,\
    "include_account_data": false,\
    "include_state": false,\
    "state": {\
      "types": []\
    },\
    "ephemeral": {\
      "types": []\
    },\
    "account_data": {\
      "types": []\
    }\
  },\
  "event_fields": [\
    "content.body",\
    "sender",\
    "origin_server_ts"\
  ],\
  "event_format": "client",\
  "presence": {\
    "types": [],\
    "not_types": ["*"]\
  },\
  "account_data": {\
    "types": [],\
    "not_types": ["*"]\
  }\
}
attr MatrixBot set02HeaderAuthorization Authorization: Bearer $sid
attr MatrixBot set02HeaderContent-Type application/json
attr MatrixBot set02Method POST
attr MatrixBot set02Name sendFilter
attr MatrixBot set02NoArg 1
attr MatrixBot set02ParseResponse 1
attr MatrixBot set02Regex \"filter_id\":\s*\"(?<filter_id>\d+)\"
attr MatrixBot set02URL https://[$name:MatrixServer]/_matrix/client/v3/user/@[$name:MatrixUser]:[$name:MatrixServer]/filter
attr MatrixBot set03Local 1
attr MatrixBot set03Name longpollCmd
attr MatrixBot set03TextArg 1
attr MatrixBot showError 1
attr MatrixBot sid01Data {\
  "type": "m.login.password",\
  "identifier": {\
    "type": "m.id.user",\
    "user": "[$name:MatrixUser]"\
  },\
  "password": "%%MatrixPassword%%"\
}
attr MatrixBot sid01HeaderContent-Type application/json
attr MatrixBot sid01IdRegex "access_token"\s*:\s*"([^"]+)"
attr MatrixBot sid01URL https://[$name:MatrixServer]/_matrix/client/v3/login
attr MatrixBot timeout 65
attr MatrixBot userReadings longpollTimer:(next_batch|longpollCmd|LAST_ERROR|sendText):.* {\
  my $longpollCmd = ReadingsVal($name, 'longpollCmd', '???');;\
  my $delay = 1;;\
  my $timeout = AttrVal($name, 'timeout', 61) + $delay + 5;;\
  \
  # stop our timers:\
  if ($longpollCmd eq "stopTimer") {\
    fhem("cancel ${name}_longpollTimer quiet");;\
    fhem("cancel ${name}_longpollTimer2 quiet");;\
    return "stopped";;\
  }\
  \
  if ($longpollCmd ne "startTimer") {\
    return "no timer set, longpollCmd is not set to 'startTimer'";;\
  }\
  \
  #if startTimer cmd was given now, set filter as well:\
  if (ReadingsAge($name, 'longpollCmd', 0) <= 1) {\
    $delay = 5;; #delay to allow for sendFilter to be answered\
    #Log(1, "🪲 $name: >>". InternalVal($name, 'httpbody', '???') ."<<");;\
    fhem("sleep 0.1 quiet;; set $name sendFilter");;\
  }\
  \
  #we handle an error reported by http-utils:\
  if (ReadingsAge($name, 'LAST_ERROR', 0) <= 1) {\
    my $last_error = ReadingsVal($name, 'LAST_ERROR', '???');;\
    $delay = 10;; #delay to allow for error reasons to improve\
    #Log(1, "🪲 $name: Dealing with error: >>$last_error<<");;\
  }\
  \
  # for testing this: { $defs{MatrixBot}{sid} = 'bla' }\
  if (!defined &HTTPMOD::handleAuthErrors) {\
    *HTTPMOD::handleAuthErrors = sub {\
      my ($hash, $header, $body, $request) = @_;;\
      my $name = $hash->{NAME};;\
      my $status;;\
      \
      if ($header =~ m{^HTTP/\d\.\d\s+(\d+)}m) {\
        $status = $1;;\
      }\
      \
      Log3($name, 4, "$name: HTTP status code is $status");;\
      \
      if ( $status == 401 || $status == 403 || $status == 500 ) {\
        Log3($name, 3, "$name: auth-error or servererror ($status), calling doAuth()");;\
        HTTPMOD::DoAuth($hash);;\
      }\
    };;\
  }\
  \
  #set timers, one regular and one fallback:\
  fhem("sleep $delay ${name}_longpollTimer quiet;; get $name longpoll");;\
  fhem("sleep $timeout ${name}_longpollTimer2 quiet;; set $name longpollCmd startTimer");;\
  \
  return strftime("next longpoll at %H:%M:%S", localtime( time()+$delay ));;\
},\
messages_list:messages:.* {\
  my $this = ReadingsVal($name, $reading, '');;\
  my @timestampArray = split("\n", $this);;\
  my $messages_ref = decode_json(ReadingsVal($name, 'messages', ''));;\
  my $length = 20;;\
  \
  my %seen_messages = map { $_ => 1 } @timestampArray;;\
  \
  foreach my $msg (@$messages_ref) {\
    my $val = $msg->{content}{body};;\
    $val = Encode::decode('utf-8', $val) unless Encode::is_utf8($val);;\
    $val =~ s/\n/ /g;; #replace newlines with spaces\
    \
    my $sender = $msg->{sender};;\
    my $ts = strftime("%Y-%m-%d %H:%M:%S", localtime($msg->{origin_server_ts} / 1000));;\
    my $new_entry = "$ts: $sender: $val";;\
    \
    next if $seen_messages{$new_entry};;\
    \
    my $inserted = 0;;\
    for (my $i = 0;; $i < @timestampArray;; $i++) {\
      my ($existing_ts) = $timestampArray[$i] =~ /^([^:]+):/;;\
      if ($ts lt $existing_ts) {\
        splice(@timestampArray, $i, 0, $new_entry);;\
        $inserted = 1;;\
        last;;\
      }\
    }\
    push(@timestampArray, encode('utf-8', $new_entry)) unless $inserted;;\
    shift(@timestampArray) while @timestampArray > $length;;\
  }\
  \
  return join("\n", @timestampArray);;\
},\
process_messages:messages:.* {\
  my $val = ReadingsVal($name, 'messages_list', '');;\
  my $this = ReadingsVal($name, $reading, '');;\
  my $latest_ts = $this;;\
  \
  foreach my $line (split(/\n/, $val)) {\
    if ($line =~ /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}):\s*(.*)$/) {\
      my ($ts, $msg) = ($1, $2);;\
      \
      if ($ts gt $this) {\
        fhem("trigger $name msg: $line");;\
        $latest_ts = $ts if ($ts gt $latest_ts);;\
      }\
    }\
  }\
  return $latest_ts;;\
}
attr MatrixBot verbose 5
attr MatrixBot widgetOverride longpollCmd:uzsuSelectRadio,startTimer,stopTimer
#  BUSY      1
#  CFGFN     
#  DEF        none 0
#  FUUID      68828de5-f33f-124a-2018-1a84a2796f2ab96a
#  Interval  0
#  LastAuthTry 2025-07-24 22:03:12
#  MainURL   
#  ModuleVersion 4.2.0 - 11.8.2023
#  NAME      MatrixBot
#  NOTIFYDEV  global
#  NR        96
#  NTFY_ORDER 50-MatrixBot
#  STATE      ???
#  TYPE      HTTPMOD
#  eventCount 56
#  sid        syt_ZmhlbXRlc3Q_NulTSMihfMALhjZObAkG_4EJI8o
#  value     
#  CompiledRegexes:
#  HttpUtils:
#    NAME     
#    addr      https://tchncs.de:443
#    auth      0
#    code      200
#    compress  1
#    conn     
#    data     
#    displayurl https://tchncs.de/_matrix/client/v3/sync?timeout=60000&filter=1&since=s689280504_2010597770_83218_517727981_91772009_15429834_24008571_289469634_0_40109
#    header    Authorization: Bearer syt_ZmhlbXRlc3Q_NulTSMihfMALhjZObAkG_4EJI8o
#    host      tchncs.de
#    httpheader HTTP/1.1 200 OK
#Server: nginx
#Date: Thu, 24 Jul 2025 20:06:08 GMT
#Content-Type: application/json
#Connection: close
#Vary: Accept-Encoding
#Vary: Accept-Encoding
#Cache-Control: no-cache, no-store, must-revalidate
#Access-Control-Allow-Origin: *
#Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
#Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Date
#Access-Control-Expose-Headers: Synapse-Trace-Id, Server
#Permissions-Policy: interest-cohort=()
#X-Content-Type-Options: nosniff
#X-Frame-Options: SAMEORIGIN
#X-XSS-Protection: 1; mode=block
#Referrer-Policy: no-referrer
#Content-Security-Policy: default-src 'self' *.tchncs.de tchncs.de
#Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
#Permissions-Policy: interest-cohort=()
#Content-Security-Policy: default-src https: 'unsafe-inline' 'unsafe-eval' 'self' data: *.tchncs.de
#Referrer-Policy: strict-origin
#    httpversion 1.0
#    hu_blocking 0
#    hu_filecount 1
#    hu_port    443
#    hu_portSfx
#    ignoreredirects 1
#    loglevel  4
#    path      /_matrix/client/v3/sync?timeout=60000&filter=1&since=s689280504_2010597770_83218_517727981_91772009_15429834_24008571_289469634_0_40109
#    protocol  https
#    redirects  0
#    timeout    65
#    url        https://tchncs.de/_matrix/client/v3/sync?timeout=60000&filter=1&since=s689280504_2010597770_83218_517727981_91772009_15429834_24008571_289469634_0_40109
#    sslargs:
#  QUEUE:
#  READINGS:
#    2025-07-24 22:04:13  filter_id      1
#    2025-07-24 22:04:13  longpollCmd    startTimer
#    2025-07-24 22:06:08  longpollTimer  next longpoll at 22:06:18
#    2025-07-24 22:06:08  messages        [{"content":{"body":"Test um 22:06"},"sender":"@fhemtest:tchncs.de","origin_server_ts":1753387568313}]
#    2025-07-24 22:06:08  messages_list  2025-07-24 21:49:19: @fhemtest:tchncs.de: dsfsdf
#2025-07-24 21:49:44: @fhemtest:tchncs.de: und so?
#2025-07-24 21:50:24: @fhemtest:tchncs.de: mein test
#2025-07-24 21:51:10: @fhemtest:tchncs.de: únd noch einer
#2025-07-24 21:54:24: @fhemtest:tchncs.de: sfsdf
#2025-07-24 21:54:33: @fhemtest:tchncs.de: vvbh
#2025-07-24 21:58:13: @fhemtest:tchncs.de: $daeq93aPMPPCwaPwExtfGI6mzacqafwcl1JeIzTwhfo
#2025-07-24 22:01:52: @fhemtest:tchncs.de: cxvxcv
#2025-07-24 22:04:25: @fhemtest:tchncs.de: $L8PfwFSk7Zq3egXhWQglGUVlVyGC_OvMXHIarqf_GQY
#2025-07-24 22:04:37: @fhemtest:tchncs.de: fghfgh
#2025-07-24 22:06:08: @fhemtest:tchncs.de: Test um 22:06
#    2025-07-24 22:06:08  next_batch      s689280916_2010597770_83422_517728357_91772135_15429836_24008575_289469676_0_40109
#    2025-07-24 22:06:08  process_messages 2025-07-24 22:06:08
#    2025-07-24 22:04:25  sendText        $7htR9P3PCZJqZ4-P0Vkzrz7h5qrrwkKWDDYa-t8uFxo
#  REQUEST:
#    context    get
#    data     
#    header    Authorization: Bearer $sid
#    ignoreredirects 0
#    num        02
#    retryCount 0
#    type      get02
#    url        https://[$name:MatrixServer]/_matrix/client/v3/sync?timeout=60000&filter=[$name:filter_id]%%next_batch_param%%
#    value     
#  defptr:
#    readingBase:
#      filter_id  set
#      messages  get
#      next_batch get
#      sendText  set
#    readingNum:
#      filter_id  02
#      messages  02
#      next_batch 02
#      sendText  01
#    readingOutdated:
#    requestReadings:
#      get02:
#        messages  get 02
#        next_batch get 02
#      set01:
#        sendText  set 01
#      set02:
#        filter_id  set 02
#
setstate MatrixBot 2025-07-24 22:04:13 filter_id 1
setstate MatrixBot 2025-07-24 22:04:13 longpollCmd startTimer
setstate MatrixBot 2025-07-24 22:06:08 longpollTimer next longpoll at 22:06:18
setstate MatrixBot 2025-07-24 22:06:08 messages [{"content":{"body":"Test um 22:06"},"sender":"@fhemtest:tchncs.de","origin_server_ts":1753387568313}]
setstate MatrixBot 2025-07-24 22:06:08 messages_list 2025-07-24 21:49:19: @fhemtest:tchncs.de: dsfsdf\
2025-07-24 21:49:44: @fhemtest:tchncs.de: und so?\
2025-07-24 21:50:24: @fhemtest:tchncs.de: mein test\
2025-07-24 21:51:10: @fhemtest:tchncs.de: únd noch einer\
2025-07-24 21:54:24: @fhemtest:tchncs.de: sfsdf\
2025-07-24 21:54:33: @fhemtest:tchncs.de: vvbh\
2025-07-24 21:58:13: @fhemtest:tchncs.de: $daeq93aPMPPCwaPwExtfGI6mzacqafwcl1JeIzTwhfo\
2025-07-24 22:01:52: @fhemtest:tchncs.de: cxvxcv\
2025-07-24 22:04:25: @fhemtest:tchncs.de: $L8PfwFSk7Zq3egXhWQglGUVlVyGC_OvMXHIarqf_GQY\
2025-07-24 22:04:37: @fhemtest:tchncs.de: fghfgh\
2025-07-24 22:06:08: @fhemtest:tchncs.de: Test um 22:06
setstate MatrixBot 2025-07-24 22:06:08 next_batch s689280916_2010597770_83422_517728357_91772135_15429836_24008575_289469676_0_40109
setstate MatrixBot 2025-07-24 22:06:08 process_messages 2025-07-24 22:06:08
setstate MatrixBot 2025-07-24 22:04:25 sendText $7htR9P3PCZJqZ4-P0Vkzrz7h5qrrwkKWDDYa-t8uFxo


So sieht es dann aus:
Du darfst diesen Dateianhang nicht ansehen.Du darfst diesen Dateianhang nicht ansehen.

Es ist als Server also doch "tchncs.de" und nicht "matrix.tchncs.de". Kannst du das Device nochmal ganz löschen und mit der Definition neu erzeugen und auf deinen Nutzer anpassen bitte.

Dein Perl,Betriebsystem und FHEM ist aktuell?

P.S.: Das Testkonto habe ich gerade wieder gelöscht, also nicht wundern wenn es jetzt nicht mehr bei Cooltux klappt.