mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
50_SSChatBot.pm: more code refactoring and little improvements
git-svn-id: https://svn.fhem.de/fhem/trunk@22633 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
873944df8c
commit
1fc46f6fd6
@ -106,6 +106,7 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"1.10.2" => "19.08.2020 more code refactoring and little improvements ",
|
||||
"1.10.1" => "18.08.2020 more code changes according PBP ",
|
||||
"1.10.0" => "17.08.2020 switch to packages, finalise for repo checkin ",
|
||||
"1.9.0" => "30.07.2020 restartSendqueue option 'force' added ",
|
||||
@ -950,6 +951,20 @@ sub addQueue {
|
||||
return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# asynchrone Queue starten
|
||||
# $rst = resend Timer
|
||||
################################################################
|
||||
sub startQueue {
|
||||
my $name = shift // return;
|
||||
my $rst = shift // return;
|
||||
my $hash = $defs{$name};
|
||||
|
||||
RemoveInternalTimer ($hash, "FHEM::SSChatBot::getApiSites");
|
||||
InternalTimer ($rst, "FHEM::SSChatBot::getApiSites", "$name", 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#############################################################################################
|
||||
# Erfolg einer Rückkehrroutine checken und ggf. Send-Retry ausführen
|
||||
@ -974,7 +989,7 @@ sub checkRetry {
|
||||
if(!$retry) { # Befehl erfolgreich, Senden nur neu starten wenn weitere Einträge in SendQueue
|
||||
delete $hash->{OPIDX};
|
||||
delete $data{SSChatBot}{$name}{sendqueue}{entries}{$idx};
|
||||
Log3($name, 4, "$name - Opmode \"$hash->{OPMODE}\" finished successfully, Sendqueue index \"$idx\" deleted.");
|
||||
Log3($name, 4, qq{$name - Opmode "$hash->{OPMODE}" finished successfully, Sendqueue index "$idx" deleted.});
|
||||
updQLength ($hash);
|
||||
return getApiSites($name); # nächsten Eintrag abarbeiten (wenn SendQueue nicht leer)
|
||||
|
||||
@ -999,21 +1014,19 @@ sub checkRetry {
|
||||
|
||||
if(!$forbidSend) {
|
||||
my $rs = 0;
|
||||
$rs = $rc <= 1 ? 5
|
||||
: $rc < 3 ? 20
|
||||
: $rc < 5 ? 60
|
||||
: $rc < 7 ? 1800
|
||||
: $rc < 30 ? 3600
|
||||
: 86400
|
||||
;
|
||||
$rs = $rc <= 1 ? 5
|
||||
: $rc < 3 ? 20
|
||||
: $rc < 5 ? 60
|
||||
: $rc < 7 ? 1800
|
||||
: $rc < 30 ? 3600
|
||||
: 86400
|
||||
;
|
||||
|
||||
Log3($name, 2, "$name - ERROR - \"$hash->{OPMODE}\" SendQueue index \"$idx\" not executed. Restart SendQueue in $rs seconds (retryCount $rc).");
|
||||
|
||||
my $rst = gettimeofday()+$rs; # resend Timer
|
||||
updQLength ($hash,$rst); # updaten Länge der Sendequeue mit resend Timer
|
||||
|
||||
RemoveInternalTimer($hash, "FHEM::SSChatBot::getApiSites");
|
||||
InternalTimer($rst, "FHEM::SSChatBot::getApiSites", "$name", 0);
|
||||
startQueue ($name,$rst);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1902,105 +1915,43 @@ return ("text/plain; charset=utf-8", "Missing data");
|
||||
# Common Gateway data receive
|
||||
# parsen von outgoing Messages Chat -> FHEM
|
||||
#############################################################################################
|
||||
sub _botCGIdata { ## no critic 'complexity'
|
||||
sub _botCGIdata {
|
||||
my $request = shift;
|
||||
|
||||
my ($text,$timestamp,$channelid,$channelname,$userid,$username,$postid,$triggerword) = ("","","","","","","","");
|
||||
my ($command,$cr,$au,$arg,$callbackid,$actions,$actval,$avToExec) = ("","","","","","","","");
|
||||
my $state = "active";
|
||||
my $do = 0;
|
||||
my $ret = "success";
|
||||
my $success;
|
||||
my @aul;
|
||||
my ($text,$triggerword,$command,$cr) = ("","","","");
|
||||
my ($actions,$actval,$avToExec) = ("","","");
|
||||
|
||||
my $args = (split(/outchat\?/x, $request))[1]; # GET-Methode empfangen
|
||||
my ($mime, $err, $dat) = __botCGIcheckData ($request);
|
||||
return ($mime, $err) if($err);
|
||||
|
||||
if(!$args) { # POST-Methode empfangen wenn keine GET_Methode ?
|
||||
$args = (split(/outchat&/x, $request))[1];
|
||||
if(!$args) {
|
||||
Log 1, "TYPE SSChatBot - ERROR - no expected data received";
|
||||
return ("text/plain; charset=utf-8", "no expected data received");
|
||||
}
|
||||
}
|
||||
my $name = $dat->{name};
|
||||
my $args = $dat->{args};
|
||||
my $h = $dat->{h};
|
||||
|
||||
$args =~ s/&/" /gx;
|
||||
$args =~ s/=/="/gx;
|
||||
$args .= "\"";
|
||||
|
||||
$args = urlDecode($args);
|
||||
my($a,$h) = parseParams($args);
|
||||
|
||||
if (!defined($h->{botname})) {
|
||||
Log 1, "TYPE SSChatBot - ERROR - no Botname received";
|
||||
return ("text/plain; charset=utf-8", "no FHEM SSChatBot name in message");
|
||||
}
|
||||
|
||||
# check ob angegebenes SSChatBot Device definiert, wenn ja Kontext auf botname setzen
|
||||
my $name = $h->{botname}; # das SSChatBot Device
|
||||
if(!IsDevice($name, 'SSChatBot')) {
|
||||
Log 1, qq{ERROR - No SSChatBot device "$name" of Type "SSChatBot" exists};
|
||||
return ( "text/plain; charset=utf-8", "No SSChatBot device for webhook \"/outchat\" exists" );
|
||||
}
|
||||
|
||||
my $hash = $defs{$name}; # hash des SSChatBot Devices
|
||||
Log3($name, 4, "$name - ####################################################");
|
||||
Log3($name, 4, "$name - ### start Chat operation Receive ");
|
||||
Log3($name, 4, "$name - ####################################################");
|
||||
Log3($name, 5, "$name - raw data received (urlDecoded):\n".Dumper($args));
|
||||
|
||||
my $hash = $defs{$name}; # hash des SSChatBot Devices
|
||||
my $rst = gettimeofday()+1; # Standardwert resend Timer
|
||||
my $state = "active"; # Standardwert state
|
||||
my $ret = "success";
|
||||
|
||||
# eine Antwort auf ein interaktives Objekt
|
||||
if (defined($h->{payload})) {
|
||||
# ein Benutzer hat ein interaktives Objekt ausgelöst (Button). Die Datenfelder sind nachfolgend beschrieben:
|
||||
# "actions": Array des Aktionsobjekts, das sich auf die vom Benutzer ausgelöste Aktion bezieht
|
||||
# "callback_id": Zeichenkette, die sich auf die Callback_id des Anhangs bezieht, in dem sich die vom Benutzer ausgelöste Aktion befindet
|
||||
# "post_id"
|
||||
# "token"
|
||||
# "user": { "user_id","username" }
|
||||
my $pldata = $h->{payload};
|
||||
(undef, $success) = evalJSON($hash,$pldata);
|
||||
|
||||
if (!$success) {
|
||||
Log3($name, 1, "$name - ERROR - invalid JSON data received:\n".Dumper $pldata);
|
||||
return ("text/plain; charset=utf-8", "invalid JSON data received");
|
||||
}
|
||||
|
||||
my $data = decode_json ($pldata);
|
||||
Log3($name, 5, "$name - interactive object data (JSON decoded):\n". Dumper $data);
|
||||
|
||||
$h->{token} = $data->{token};
|
||||
$h->{post_id} = $data->{post_id};
|
||||
$h->{user_id} = $data->{user}{user_id};
|
||||
$h->{username} = $data->{user}{username};
|
||||
$h->{callback_id} = $data->{callback_id};
|
||||
$h->{actions} = "type: ".$data->{actions}[0]{type}.", ".
|
||||
"name: ".$data->{actions}[0]{name}.", ".
|
||||
"value: ".$data->{actions}[0]{value}.", ".
|
||||
"text: ".$data->{actions}[0]{text}.", ".
|
||||
"style: ".$data->{actions}[0]{style};
|
||||
if (defined($h->{payload})) { # Antwort auf ein interaktives Objekt
|
||||
($mime, $err) = __botCGIcheckPayload ($hash, $h);
|
||||
return ($mime, $err) if($err);
|
||||
}
|
||||
|
||||
if (!defined($h->{token})) {
|
||||
Log3($name, 5, "$name - received insufficient data:\n".Dumper($args));
|
||||
Log3 ($name, 5, "$name - received insufficient data:\n".Dumper($args));
|
||||
return ("text/plain; charset=utf-8", "Insufficient data");
|
||||
}
|
||||
|
||||
# CSRF Token check
|
||||
my $FWdev = $hash->{FW}; # das FHEMWEB Device für SSChatBot Device -> ist das empfangene Device
|
||||
my $FWhash = $defs{$FWdev};
|
||||
my $want = $FWhash->{CSRFTOKEN};
|
||||
$want = $want?$want:"none";
|
||||
my $supplied = $h->{fwcsrf};
|
||||
|
||||
if($want eq "none" || $want ne $supplied) { # $FW_wname enthält ebenfalls das aufgerufenen FHEMWEB-Device
|
||||
Log3 ($FW_wname, 2, "$FW_wname - WARNING - FHEMWEB CSRF error for client \"$FWdev\": ".
|
||||
"received $supplied token is not $want. ".
|
||||
"For details see the csrfToken FHEMWEB attribute. ".
|
||||
"The csrfToken must be identical to the token in OUTDEF of $name device.");
|
||||
return ("text/plain; charset=utf-8", "400 Bad Request");
|
||||
}
|
||||
my $neg = __botCGIcheckToken ($name, $h, $rst); # CSRF Token check
|
||||
return $neg if($neg);
|
||||
|
||||
# Timestamp dekodieren
|
||||
if ($h->{timestamp}) {
|
||||
if ($h->{timestamp}) { # Timestamp dekodieren
|
||||
$h->{timestamp} = FmtDateTime(($h->{timestamp})/1000);
|
||||
}
|
||||
|
||||
@ -2021,114 +1972,36 @@ sub _botCGIdata { ## no critic
|
||||
# trigger_word: which trigger word is matched
|
||||
#
|
||||
|
||||
$channelid = $h->{channel_id} if($h->{channel_id});
|
||||
$channelname = $h->{channel_name} if($h->{channel_name});
|
||||
$userid = $h->{user_id} if($h->{user_id});
|
||||
$username = $h->{username} if($h->{username});
|
||||
$postid = $h->{post_id} if($h->{post_id});
|
||||
$callbackid = $h->{callback_id} if($h->{callback_id});
|
||||
$timestamp = $h->{timestamp} if($h->{timestamp});
|
||||
my $channelid = $h->{channel_id} // q{};
|
||||
my $channelname = $h->{channel_name} // q{};
|
||||
my $userid = $h->{user_id} // q{};
|
||||
my $username = $h->{username} // q{};
|
||||
my $postid = $h->{post_id} // q{};
|
||||
my $callbackid = $h->{callback_id} // q{};
|
||||
my $timestamp = $h->{timestamp} // q{};
|
||||
|
||||
# interaktive Schaltflächen (Aktionen) auswerten
|
||||
if ($h->{actions}) {
|
||||
if ($h->{actions}) { # interaktive Schaltflächen (Aktionen) auswerten
|
||||
$actions = $h->{actions};
|
||||
($actval) = $actions =~ m/^type:\s+button.*?value:\s+(.*?),\s+text:/x;
|
||||
|
||||
if($actval =~ /^\//x) {
|
||||
Log3($name, 4, "$name - slash command \"$actval\" got from interactive data and execute it with priority");
|
||||
Log3 ($name, 4, "$name - slash command \"$actval\" got from interactive data and execute it with priority");
|
||||
$avToExec = $actval;
|
||||
}
|
||||
}
|
||||
|
||||
if ($h->{text} || $avToExec) {
|
||||
$text = $h->{text};
|
||||
$text = $avToExec if($avToExec); # Vorrang für empfangene interaktive Data (Schaltflächenwerte) die Slash-Befehle enthalten
|
||||
if($text =~ /^\/(set.*?|get.*?|code.*?)\s+(.*)$/ix) { # vordefinierte Befehle in FHEM ausführen
|
||||
my $p1 = substr lc $1, 0, 3;
|
||||
my $p2 = $2;
|
||||
|
||||
my $pars = {
|
||||
name => $name,
|
||||
username => $username,
|
||||
state => $state,
|
||||
p2 => $p2,
|
||||
};
|
||||
|
||||
if($hrecbot{$p1} && defined &{$hrecbot{$p1}{fn}}) {
|
||||
$do = 1;
|
||||
no strict "refs"; ## no critic 'NoStrict'
|
||||
($command, $cr, $state) = &{$hrecbot{$p1}{fn}} ($pars);
|
||||
use strict "refs";
|
||||
}
|
||||
|
||||
$cr = $cr ne q{} ? $cr : qq{command '$command' executed};
|
||||
Log3($name, 4, "$name - FHEM command return: ".$cr);
|
||||
|
||||
$cr = formString($cr, "command");
|
||||
|
||||
my $params = {
|
||||
name => $name,
|
||||
opmode => "sendItem",
|
||||
method => "chatbot",
|
||||
userid => $userid,
|
||||
text => $cr,
|
||||
fileUrl => "",
|
||||
channel => "",
|
||||
attachment => ""
|
||||
};
|
||||
addQueue ($params);
|
||||
}
|
||||
|
||||
my $ua = $attr{$name}{userattr}; # Liste aller ownCommandxx zusammenstellen
|
||||
$ua = "" if(!$ua);
|
||||
my %hc = map { ($_ => 1) } grep { "$_" =~ m/ownCommand(\d+)/x } split(" ","ownCommand1 $ua");
|
||||
|
||||
for my $ca (sort keys %hc) {
|
||||
my $uc = AttrVal($name, $ca, "");
|
||||
next if (!$uc);
|
||||
($uc,$arg) = split(/\s+/x, $uc, 2);
|
||||
|
||||
if($uc && $text =~ /^$uc\s*?$/x) { # User eigener Slash-Befehl, z.B.: /Wetter
|
||||
$do = 1;
|
||||
|
||||
$command = $arg;
|
||||
$au = AttrVal($name,"allowedUserForOwn", "all"); # Berechtgung des Chat-Users checken
|
||||
@aul = split(",",$au);
|
||||
|
||||
if($au eq "all" || $username ~~ @aul) {
|
||||
Log3($name, 4, qq{$name - Synology Chat user "$username" execute FHEM command: }.$arg);
|
||||
$cr = AnalyzeCommandChain(undef, $arg); # FHEM Befehlsketten ausführen
|
||||
|
||||
} else {
|
||||
$cr = qq{User "$username" is not allowed execute "$arg" command};
|
||||
$state = qq{command execution denied};
|
||||
Log3($name, 2, qq{$name - WARNING - Chat user "$username" is not authorized for "$arg" command. Execution denied !});
|
||||
}
|
||||
|
||||
$cr = $cr ne q{} ? $cr : qq{command '$arg' executed};
|
||||
Log3($name, 4, "$name - FHEM command return: ".$cr);
|
||||
|
||||
$cr = formString($cr, "command");
|
||||
|
||||
my $params = {
|
||||
name => $name,
|
||||
opmode => "sendItem",
|
||||
method => "chatbot",
|
||||
userid => $userid,
|
||||
text => $cr,
|
||||
fileUrl => "",
|
||||
channel => "",
|
||||
attachment => ""
|
||||
};
|
||||
addQueue ($params);
|
||||
}
|
||||
}
|
||||
if ($h->{text} || $avToExec) { # Interpretation empfangener Daten als auszuführende Kommandos
|
||||
my $params = {
|
||||
name => $name,
|
||||
username => $username,
|
||||
userid => $userid,
|
||||
rst => $rst,
|
||||
state => $state,
|
||||
h => $h,
|
||||
avToExec => $avToExec
|
||||
};
|
||||
|
||||
# Wenn Kommando ausgeführt wurde Ergebnisse aus Queue übertragen
|
||||
if($do) {
|
||||
RemoveInternalTimer ($hash, "FHEM::SSChatBot::getApiSites");
|
||||
InternalTimer (gettimeofday()+1, "FHEM::SSChatBot::getApiSites", "$name", 0);
|
||||
}
|
||||
($command, $cr, $text) = __botCGIdataInterprete ($params);
|
||||
}
|
||||
|
||||
if ($h->{trigger_word}) {
|
||||
@ -2155,7 +2028,247 @@ sub _botCGIdata { ## no critic
|
||||
readingsBulkUpdate ($hash, "state", $state );
|
||||
readingsEndUpdate ($hash,1);
|
||||
|
||||
return ("text/plain; charset=utf-8", $ret);
|
||||
return ("text/plain; charset=utf-8", $ret);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# botCGI
|
||||
# Daten auf Validität checken
|
||||
################################################################
|
||||
sub __botCGIcheckData {
|
||||
my $request = shift;
|
||||
|
||||
my $args = (split(/outchat\?/x, $request))[1]; # GET-Methode empfangen
|
||||
|
||||
if(!$args) { # POST-Methode empfangen wenn keine GET_Methode ?
|
||||
$args = (split(/outchat&/x, $request))[1];
|
||||
if(!$args) {
|
||||
Log 1, "TYPE SSChatBot - ERROR - no expected data received";
|
||||
return ("text/plain; charset=utf-8", "no expected data received");
|
||||
}
|
||||
}
|
||||
|
||||
$args =~ s/&/" /gx;
|
||||
$args =~ s/=/="/gx;
|
||||
$args .= "\"";
|
||||
|
||||
$args = urlDecode($args);
|
||||
my($a,$h) = parseParams($args);
|
||||
|
||||
if (!defined($h->{botname})) {
|
||||
Log 1, "TYPE SSChatBot - ERROR - no Botname received";
|
||||
return ("text/plain; charset=utf-8", "no FHEM SSChatBot name in message");
|
||||
}
|
||||
|
||||
# check ob angegebenes SSChatBot Device definiert
|
||||
# wenn ja, Kontext auf botname setzen
|
||||
my $name = $h->{botname}; # das SSChatBot Device
|
||||
if(!IsDevice($name, 'SSChatBot')) {
|
||||
Log 1, qq{ERROR - No SSChatBot device "$name" of Type "SSChatBot" exists};
|
||||
return ( "text/plain; charset=utf-8", "No SSChatBot device for webhook \"/outchat\" exists" );
|
||||
}
|
||||
|
||||
my $dat = {
|
||||
name => $name,
|
||||
args => $args,
|
||||
h => $h,
|
||||
};
|
||||
|
||||
return ('','',$dat);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# botCGI
|
||||
# check CSRF Token
|
||||
################################################################
|
||||
sub __botCGIcheckToken {
|
||||
my $name = shift;
|
||||
my $h = shift;
|
||||
my $rst = shift;
|
||||
my $hash = $defs{$name};
|
||||
|
||||
my $FWdev = $hash->{FW}; # das FHEMWEB Device für SSChatBot Device -> ist das empfangene Device
|
||||
my $FWhash = $defs{$FWdev};
|
||||
my $want = $FWhash->{CSRFTOKEN} // "none";
|
||||
my $supplied = $h->{fwcsrf};
|
||||
|
||||
if($want eq "none" || $want ne $supplied) { # $FW_wname enthält ebenfalls das aufgerufenen FHEMWEB-Device
|
||||
Log3 ($FW_wname, 2, "$FW_wname - ERROR - FHEMWEB CSRF error for client $FWdev: ".
|
||||
"received $supplied token is not $want. ".
|
||||
"For details see the FHEMWEB csrfToken attribute. ".
|
||||
"The csrfToken must be identical to the token in OUTDEF of the $name device.");
|
||||
|
||||
my $cr = formString("CSRF error in client '$FWdev' - see logfile", "text");
|
||||
my $userid = $h->{user_id} // q{};
|
||||
|
||||
my $params = {
|
||||
name => $name,
|
||||
opmode => "sendItem",
|
||||
method => "chatbot",
|
||||
userid => $userid,
|
||||
text => $cr,
|
||||
fileUrl => "",
|
||||
channel => "",
|
||||
attachment => ""
|
||||
};
|
||||
addQueue ($params);
|
||||
startQueue ($name, $rst);
|
||||
|
||||
return ("text/plain; charset=utf-8", "400 Bad Request");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# botCGI
|
||||
# Payload checken (interaktives Element ausgelöst ?)
|
||||
#
|
||||
# ein Benutzer hat ein interaktives Objekt ausgelöst (Button).
|
||||
# Die Datenfelder sind nachfolgend beschrieben:
|
||||
# "actions": Array des Aktionsobjekts, das sich auf die
|
||||
# vom Benutzer ausgelöste Aktion bezieht
|
||||
# "callback_id": Zeichenkette, die sich auf die Callback_id
|
||||
# des Anhangs bezieht, in dem sich die vom
|
||||
# Benutzer ausgelöste Aktion befindet
|
||||
# "post_id"
|
||||
# "token"
|
||||
# "user": { "user_id","username" }
|
||||
################################################################
|
||||
sub __botCGIcheckPayload {
|
||||
my $hash = shift;
|
||||
my $h = shift;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $pldata = $h->{payload};
|
||||
my (undef, $success) = evalJSON($hash,$pldata);
|
||||
|
||||
if (!$success) {
|
||||
Log3($name, 1, "$name - ERROR - invalid JSON data received:\n".Dumper $pldata);
|
||||
return ("text/plain; charset=utf-8", "invalid JSON data received");
|
||||
}
|
||||
|
||||
my $data = decode_json ($pldata);
|
||||
Log3($name, 5, "$name - interactive object data (JSON decoded):\n". Dumper $data);
|
||||
|
||||
$h->{token} = $data->{token};
|
||||
$h->{post_id} = $data->{post_id};
|
||||
$h->{user_id} = $data->{user}{user_id};
|
||||
$h->{username} = $data->{user}{username};
|
||||
$h->{callback_id} = $data->{callback_id};
|
||||
$h->{actions} = "type: ".$data->{actions}[0]{type}.", ".
|
||||
"name: ".$data->{actions}[0]{name}.", ".
|
||||
"value: ".$data->{actions}[0]{value}.", ".
|
||||
"text: ".$data->{actions}[0]{text}.", ".
|
||||
"style: ".$data->{actions}[0]{style};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# botCGI
|
||||
# Interpretiere empfangene Daten als Kommandos
|
||||
################################################################
|
||||
sub __botCGIdataInterprete {
|
||||
my $paref = shift;
|
||||
my $name = $paref->{name};
|
||||
my $username = $paref->{username};
|
||||
my $userid = $paref->{userid};
|
||||
my $rst = $paref->{rst};
|
||||
my $state = $paref->{state};
|
||||
my $h = $paref->{h};
|
||||
my $avToExec = $paref->{avToExec};
|
||||
|
||||
my $do = 0;
|
||||
my $cr = q{};
|
||||
my $command = q{};
|
||||
my $text = $h->{text};
|
||||
$text = $avToExec if($avToExec); # Vorrang für empfangene interaktive Data (Schaltflächenwerte) die Slash-Befehle enthalten
|
||||
|
||||
if($text =~ /^\/(set.*?|get.*?|code.*?)\s+(.*)$/ix) { # vordefinierte Befehle in FHEM ausführen
|
||||
my $p1 = substr lc $1, 0, 3;
|
||||
my $p2 = $2;
|
||||
|
||||
my $pars = {
|
||||
name => $name,
|
||||
username => $username,
|
||||
state => $state,
|
||||
p2 => $p2,
|
||||
};
|
||||
|
||||
if($hrecbot{$p1} && defined &{$hrecbot{$p1}{fn}}) {
|
||||
$do = 1;
|
||||
no strict "refs"; ## no critic 'NoStrict'
|
||||
($command, $cr, $state) = &{$hrecbot{$p1}{fn}} ($pars);
|
||||
use strict "refs";
|
||||
}
|
||||
|
||||
$cr = $cr ne q{} ? $cr : qq{command '$command' executed};
|
||||
Log3($name, 4, "$name - FHEM command return: ".$cr);
|
||||
|
||||
$cr = formString($cr, "command");
|
||||
|
||||
my $params = {
|
||||
name => $name,
|
||||
opmode => "sendItem",
|
||||
method => "chatbot",
|
||||
userid => $userid,
|
||||
text => $cr,
|
||||
fileUrl => "",
|
||||
channel => "",
|
||||
attachment => ""
|
||||
};
|
||||
addQueue ($params);
|
||||
}
|
||||
|
||||
my $ua = $attr{$name}{userattr}; # Liste aller ownCommandxx zusammenstellen
|
||||
$ua = "" if(!$ua);
|
||||
my %hc = map { ($_ => 1) } grep { "$_" =~ m/ownCommand(\d+)/x } split(" ","ownCommand1 $ua");
|
||||
|
||||
for my $ca (sort keys %hc) {
|
||||
my $uc = AttrVal($name, $ca, "");
|
||||
next if (!$uc);
|
||||
|
||||
my $arg = q{};
|
||||
($uc,$arg) = split(/\s+/x, $uc, 2);
|
||||
|
||||
if($uc && $text =~ /^$uc\s*?$/x) { # User eigener Slash-Befehl, z.B.: /Wetter
|
||||
$do = 1;
|
||||
|
||||
my $pars = {
|
||||
name => $name,
|
||||
username => $username,
|
||||
state => $state,
|
||||
arg => $arg,
|
||||
uc => $uc,
|
||||
};
|
||||
|
||||
($cr, $state) = __botCGIownCommand ($pars);
|
||||
|
||||
$cr = $cr ne q{} ? $cr : qq{command '$arg' executed};
|
||||
Log3($name, 4, "$name - FHEM command return: ".$cr);
|
||||
|
||||
$cr = formString($cr, "command");
|
||||
|
||||
my $params = {
|
||||
name => $name,
|
||||
opmode => "sendItem",
|
||||
method => "chatbot",
|
||||
userid => $userid,
|
||||
text => $cr,
|
||||
fileUrl => "",
|
||||
channel => "",
|
||||
attachment => ""
|
||||
};
|
||||
addQueue ($params);
|
||||
}
|
||||
}
|
||||
|
||||
if($do) { # Wenn Kommando ausgeführt wurde -> Queue übertragen
|
||||
startQueue ($name, $rst);
|
||||
}
|
||||
|
||||
return ($command, $cr, $text);
|
||||
}
|
||||
|
||||
################################################################
|
||||
@ -2230,6 +2343,36 @@ sub __botCGIrecCod { ## no critic "not used"
|
||||
return ($command, $cr, $state);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# botCGI
|
||||
# User ownCommand in FHEM ausführen
|
||||
################################################################
|
||||
sub __botCGIownCommand {
|
||||
my $paref = shift;
|
||||
my $name = $paref->{name};
|
||||
my $username = $paref->{username};
|
||||
my $state = $paref->{state};
|
||||
my $arg = $paref->{arg};
|
||||
my $uc = $paref->{uc};
|
||||
|
||||
my $cr = q{};
|
||||
|
||||
if(!$arg) {
|
||||
$cr = qq{format error: your own command '$uc' doesn't have a mandatory argument};
|
||||
return ($cr, $state);
|
||||
}
|
||||
|
||||
my $au = AttrVal($name,"allowedUserForOwn", "all"); # Berechtgung des Chat-Users checken
|
||||
|
||||
$paref->{au} = $au;
|
||||
$paref->{order} = "Own";
|
||||
$paref->{cmd} = $arg;
|
||||
|
||||
($cr, $state) = ___botCGIorder ($paref);
|
||||
|
||||
return ($cr, $state);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Order ausführen und Ergebnis zurückliefern
|
||||
################################################################
|
||||
@ -2243,7 +2386,7 @@ sub ___botCGIorder {
|
||||
my $order = $paref->{order}; # Kommandotyp, z.B. "set"
|
||||
my $cmd = $paref->{cmd}; # komplettes Kommando
|
||||
|
||||
my @aul = split(",",$au);
|
||||
my @aul = split ",", $au;
|
||||
my $cr = q{};
|
||||
|
||||
if($au eq "all" || $username ~~ @aul) {
|
||||
@ -2263,7 +2406,12 @@ sub ___botCGIorder {
|
||||
} else {
|
||||
$cr = qq{function format error: may be you didn't use the format {...}};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($order eq "Own") { # FHEM ownCommand Befehlsketten ausführen
|
||||
Log3($name, 4, qq{$name - Synology Chat user "$username" execute FHEM command: }.$cmd);
|
||||
$cr = AnalyzeCommandChain(undef, $cmd);
|
||||
}
|
||||
|
||||
} else {
|
||||
$cr = qq{User "$username" is not allowed execute "$cmd" command};
|
||||
|
Loading…
x
Reference in New Issue
Block a user