diff --git a/fhem/CHANGED b/fhem/CHANGED
index 4bb8240c4..8ae9e2500 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
+ - feature: 50_TelegramBot reply set command / allowedCommands as restriction
- change: 49_SSCam: get "snapfileinfo" will get back an Infomessage if
Reading "LastSnapId" isn't available
- feature: dummy attribute useSetExtensions
diff --git a/fhem/FHEM/50_TelegramBot.pm b/fhem/FHEM/50_TelegramBot.pm
index 6b29d4e1c..0e4892eb2 100644
--- a/fhem/FHEM/50_TelegramBot.pm
+++ b/fhem/FHEM/50_TelegramBot.pm
@@ -125,11 +125,19 @@
# 1.6 2016-04-08 text customization for replies/messages and favorite descriptions
# Fix: contact handling failed (/ in contact names ??)
+# Reply keyboards also for sendVoice/sendDocument ect
+# reply msg id in sendit - new set cmd reply
+# Fix: reset also removes retry timer
+# TEMP: SNAME in hash is needed for allowed (SNAME reflects if the TCPServer device name)
+# Remove unnecessary attribute setters
+# added allowedCommands and doc (with modification of allowed_... device)
+# allowedCommands only modified on the allowed_... device
+# 1.7 2016-05-05 reply set command / allowedCommands as restriction
#
#
##############################################################################
# TASKS
-#
+#
# Look for solution on space at beginning of line --> checked that data is sent correctly to telegram but does not end up in the message
#
# allow keyboards in the device api
@@ -138,7 +146,6 @@
#
##############################################################################
# Ideas / Future
-# add replyTo
#
##############################################################################
@@ -164,7 +171,7 @@ sub TelegramBot_Set($@);
sub TelegramBot_Get($@);
sub TelegramBot_Callback($$$);
-sub TelegramBot_SendIt($$$$$;$);
+sub TelegramBot_SendIt($$$$$;$$);
sub TelegramBot_checkAllowedPeer($$$);
sub TelegramBot_SplitFavoriteDef($$);
@@ -189,6 +196,8 @@ my %sets = (
"replaceContacts" => "textField",
"reset" => undef,
+ "reply" => "textField",
+
"zDebug" => "textField"
);
@@ -250,7 +259,7 @@ sub TelegramBot_Initialize($) {
$hash->{SetFn} = "TelegramBot_Set";
$hash->{AttrFn} = "TelegramBot_Attr";
$hash->{AttrList} = "defaultPeer defaultPeerCopy:0,1 pollingTimeout cmdKeyword cmdSentCommands favorites:textField-long cmdFavorites cmdRestrictedPeer ". "cmdTriggerOnly:0,1 saveStateOnContactChange:1,0 maxFileSize maxReturnSize cmdReturnEmptyResult:1,0 pollingVerbose:1_Digest,2_Log,0_None ".
- "allowUnknownContacts:1,0 textResponseConfirm:textField textResponseCommands:textField ".
+ "allowUnknownContacts:1,0 textResponseConfirm:textField textResponseCommands:textField allowedCommands ".
"textResponseFavorites:textField textResponseResult:textField textResponseUnauthorized:textField ".
" maxRetries:0,1,2,3,4,5 ".$readingFnAttributes;
}
@@ -385,8 +394,16 @@ sub TelegramBot_Set($@)
my $ret = undef;
- if( ($cmd eq 'message') || ($cmd eq 'msg') || ($cmd =~ /^send.*/ ) ) {
+ if( ($cmd eq 'message') || ($cmd eq 'msg') || ($cmd eq 'reply') || ($cmd =~ /^send.*/ ) ) {
+ my $msgid;
+
+ if ($cmd eq 'reply') {
+ return "TelegramBot_Set: Command $cmd, no peer, msgid and no text/file specified" if ( $numberOfArgs < 3 );
+ $msgid = shift @args;
+ $numberOfArgs--;
+ }
+
return "TelegramBot_Set: Command $cmd, no peers and no text/file specified" if ( $numberOfArgs < 2 );
my $sendType = 0;
@@ -394,7 +411,9 @@ sub TelegramBot_Set($@)
my $peers;
while ( $args[0] =~ /^@(..+)$/ ) {
my $ppart = $1;
+ return "TelegramBot_Set: Command $cmd, need exactly one peer" if ( ($cmd eq 'reply') && ( defined( $peers ) ) );
$peers .= " " if ( defined( $peers ) );
+ $peers = "" if ( ! defined( $peers ) );
$peers .= $ppart;
shift @args;
@@ -435,7 +454,7 @@ sub TelegramBot_Set($@)
}
Log3 $name, 5, "TelegramBot_Set $name: start send for cmd :$cmd: and sendType :$sendType:";
- $ret = TelegramBot_SendIt( $hash, $peers, $msg, $addPar, $sendType );
+ $ret = TelegramBot_SendIt( $hash, $peers, $msg, $addPar, $sendType, $msgid );
} elsif($cmd eq 'zDebug') {
# for internal testing only
@@ -564,19 +583,7 @@ sub TelegramBot_Attr(@) {
# $name is device name
# aName and aVal are Attribute name and value
if ($cmd eq "set") {
- if ($aName eq 'defaultPeer') {
- $attr{$name}{'defaultPeer'} = $aVal;
-
- } elsif ($aName eq 'cmdKeyword') {
- $attr{$name}{'cmdKeyword'} = $aVal;
-
- } elsif ($aName eq 'cmdSentCommands') {
- $attr{$name}{'cmdSentCommands'} = $aVal;
-
- } elsif ($aName eq 'cmdFavorites') {
- $attr{$name}{'cmdFavorites'} = $aVal;
-
- } elsif ($aName eq 'favorites') {
+ if ($aName eq 'favorites') {
$attr{$name}{'favorites'} = $aVal;
# Empty current alias list in hash
@@ -604,7 +611,6 @@ sub TelegramBot_Attr(@) {
} elsif ($aName eq 'cmdRestrictedPeer') {
$aVal =~ s/^\s+|\s+$//g;
- $attr{$name}{'cmdRestrictedPeer'} = $aVal;
} elsif ( ($aName eq 'defaultPeerCopy') ||
($aName eq 'saveStateOnContactChange') ||
@@ -613,25 +619,13 @@ sub TelegramBot_Attr(@) {
($aName eq 'allowUnknownContacts') ) {
$aVal = ($aVal eq "1")? "1": "0";
- } elsif ($aName eq 'maxFileSize') {
- if ( $aVal !~ /^[[:digit:]]+$/ ) {
- return "\"TelegramBot_Attr: \" maxFileSize needs to be given in digits only";
- }
-
- } elsif ($aName eq 'maxReturnSize') {
- if ( $aVal !~ /^[[:digit:]]+$/ ) {
- return "\"TelegramBot_Attr: \" maxReturnSize needs to be given in digits only";
- }
-
- } elsif ($aName eq 'maxRetries') {
- if ( $aVal !~ /^[[:digit:]]$/ ) {
- return "\"TelegramBot_Attr: \" maxRetries needs to be given in digits only";
- }
+ } elsif ( ($aName eq 'maxFileSize') ||
+ ($aName eq 'maxReturnSize') ||
+ ($aName eq 'maxRetries') ) {
+ return "\"TelegramBot_Attr: \" $aName needs to be given in digits only" if ( $aVal !~ /^[[:digit:]]+$/ );
} elsif ($aName eq 'pollingTimeout') {
- if ( $aVal !~ /^[[:digit:]]+$/ ) {
- return "\"TelegramBot_Attr: \" pollingTimeout needs to be given in digits only";
- }
+ return "\"TelegramBot_Attr: \" $aName needs to be given in digits only" if ( $aVal !~ /^[[:digit:]]+$/ );
# let all existing methods run into block
RemoveInternalTimer($hash);
$hash->{POLLING} = -1;
@@ -641,7 +635,17 @@ sub TelegramBot_Attr(@) {
} elsif ($aName eq 'pollingVerbose') {
return "\"TelegramBot_Attr: \" Incorrect value given for pollingVerbose" if ( $aVal !~ /^((1_Digest)|(2_Log)|(0_None))$/ );
- $attr{$name}{'pollingVerbose'} = $aVal;
+
+ } elsif ($aName eq 'allowedCommands') {
+ my $allowedName = "allowed_$name";
+ my $exists = ($defs{$allowedName} ? 1 : 0);
+ AnalyzeCommand(undef, "defmod $allowedName allowed");
+ AnalyzeCommand(undef, "attr $allowedName validFor $name");
+ AnalyzeCommand(undef, "attr $allowedName $aName ".$aVal);
+ Log3 $name, 3, "TelegramBot_Attr $name: ".($exists ? "modified":"created")." $allowedName with commands :$aVal:";
+ # allowedCommands only set on the corresponding allowed_device
+ return "\"TelegramBot_Attr: \" $aName ".($exists ? "modified":"created")." $allowedName with commands :$aVal:"
+
}
$_[3] = $aVal;
@@ -818,22 +822,6 @@ sub TelegramBot_SentFavorites($$$$) {
$ret = TelegramBot_SendIt( $hash, $mpeernorm, $ret, $jsonkb, 0 );
-
-############ OLD Favorites sent as message
-# Log3 $name, 3, "TelegramBot_SentFavorites Favorites :".scalar(@clist).": ";
- # my $cnt = 0;
- # $slc = "";
- # my $ck = AttrVal($name,'cmdKeyword',"");
-
- # foreach my $cs ( @clist ) {
- # $cnt += 1;
- # $slc .= $cnt."\n $ck ".$cs."\n";
- # }
-
- # my $defpeer = AttrVal($name,'defaultPeer',undef);
- # $defpeer = TelegramBot_GetIdForPeer( $hash, $defpeer ) if ( defined( $defpeer ) );
- # $ret = "TelegramBot fhem : ($mpeernorm)\n Favorites \n\n".$slc;
- # $ret = TelegramBot_SendIt( $hash, $defpeer, $ret, $mid, 0 );
}
return $ret;
@@ -938,7 +926,7 @@ sub TelegramBot_ExecuteCommand($$$) {
my $isMediaStream = 0;
if ( ! defined( $ret ) ) {
- $ret = AnalyzeCommand( undef, $cmd, "" );
+ $ret = AnalyzeCommand( $hash, $cmd );
# Check for image/doc/audio stream in return (-1 image
( $isMediaStream ) = TelegramBot_IdentifyStream( $hash, $ret ) if ( defined( $ret ) );
@@ -1172,11 +1160,11 @@ sub TelegramBot_DoUrlCommand($$)
#####################################
# INTERNAL: Function to send a photo (and text message) to a peer and handle result
# addPar is caption for images / keyboard for text
-sub TelegramBot_SendIt($$$$$;$)
+sub TelegramBot_SendIt($$$$$;$$)
{
my ( $hash, @args) = @_;
- my ( $peers, $msg, $addPar, $isMedia, $retryCount) = @args;
+ my ( $peers, $msg, $addPar, $isMedia, $replyid, $retryCount) = @args;
my $name = $hash->{NAME};
if ( ! defined( $retryCount ) ) {
@@ -1184,7 +1172,7 @@ sub TelegramBot_SendIt($$$$$;$)
}
# increase retrycount for next try
- $args[4] = $retryCount+1;
+ $args[5] = $retryCount+1;
Log3 $name, 5, "TelegramBot_SendIt $name: called ";
@@ -1260,10 +1248,6 @@ sub TelegramBot_SendIt($$$$$;$)
# add msg (no file)
$ret = TelegramBot_AddMultipart($hash, \%TelegramBot_hu_do_params, "text", undef, $msg, 0 ) if ( ! defined( $ret ) );
- if ( defined( $addPar ) ) {
- $ret = TelegramBot_AddMultipart($hash, \%TelegramBot_hu_do_params, "reply_markup", undef, $addPar, 0 ) if ( ! defined( $ret ) );
- }
-
} elsif ( abs($isMedia) == 1 ) {
# Photo send
$hash->{sentMsgText} = "Image: ".TelegramBot_MsgForLog($msg, ($isMedia<0) ).
@@ -1302,6 +1286,14 @@ sub TelegramBot_SendIt($$$$$;$)
$ret = TelegramBot_AddMultipart($hash, \%TelegramBot_hu_do_params, "document", undef, $msg, $isMedia ) if ( ! defined( $ret ) );
}
+ if ( defined( $replyid ) ) {
+ $ret = TelegramBot_AddMultipart($hash, \%TelegramBot_hu_do_params, "reply_to_message_id", undef, $replyid, 0 ) if ( ! defined( $ret ) );
+ }
+
+ if ( defined( $addPar ) ) {
+ $ret = TelegramBot_AddMultipart($hash, \%TelegramBot_hu_do_params, "reply_markup", undef, $addPar, 0 ) if ( ! defined( $ret ) );
+ }
+
# finalize multipart
$ret = TelegramBot_AddMultipart($hash, \%TelegramBot_hu_do_params, undef, undef, undef, 0 ) if ( ! defined( $ret ) );
@@ -1491,11 +1483,9 @@ sub TelegramBot_RetrySend($)
my $name = $hash->{NAME};
- my $args = $param->{args};
-
my $ref = $param->{args};
- Log3 $name, 4, "TelegramBot_Retrysend $name: retry @$ref[4] :@$ref[0]: -:@$ref[1]: ";
- TelegramBot_SendIt( $hash, @$ref[0], @$ref[1], @$ref[2], @$ref[3], @$ref[4] );
+ Log3 $name, 4, "TelegramBot_Retrysend $name: reply @$ref[4] retry @$ref[5] :@$ref[0]: -:@$ref[1]: ";
+ TelegramBot_SendIt( $hash, @$ref[0], @$ref[1], @$ref[2], @$ref[3], @$ref[4], @$ref[5] );
}
@@ -1649,14 +1639,14 @@ sub TelegramBot_Callback($$$)
# handle retry
# ret defined / args defined in params
if ( ( $ret ne "SUCCESS" ) && ( defined( $param->{args} ) ) ) {
- my $wait = $param->{args}[4];
+ my $wait = $param->{args}[5];
my $maxRetries = AttrVal($name,'maxRetries',0);
if ( $wait <= $maxRetries ) {
# calculate wait time 10s / 100s / 1000s ~ 17min / 10000s ~ 3h / 100000s ~ 30h
$wait = 10**$wait;
- Log3 $name, 4, "TelegramBot_Callback $name: do retry ".$param->{args}[4]." timer: $wait (ret: $ret) for msg ".
+ Log3 $name, 4, "TelegramBot_Callback $name: do retry ".$param->{args}[5]." timer: $wait (ret: $ret) for msg ".
$param->{args}[0]." : ".$param->{args}[1];
# set timer
@@ -1682,7 +1672,7 @@ sub TelegramBot_Callback($$$)
if ( scalar( @{ $hash->{sentQueue} } ) ) {
my $ref = shift @{ $hash->{sentQueue} };
Log3 $name, 5, "TelegramBot_Callback $name: handle queued send with :@$ref[0]: -:@$ref[1]: ";
- TelegramBot_SendIt( $hash, @$ref[0], @$ref[1], @$ref[2], @$ref[3], @$ref[4] );
+ TelegramBot_SendIt( $hash, @$ref[0], @$ref[1], @$ref[2], @$ref[3], @$ref[4], @$ref[5] );
}
}
@@ -1930,10 +1920,16 @@ sub TelegramBot_Setup($) {
$hash->{STATE} = "Undefined";
$hash->{POLLING} = -1;
+
+ # Temp?? SNAME is required for allowed (normally set in TCPServerUtils)
+ $hash->{SNAME} = $name;
# Ensure queueing is not happening
delete( $hash->{sentQueue} );
delete( $hash->{sentMsgResult} );
+
+ # remove timer for retry
+ RemoveInternalTimer(\%TelegramBot_hu_do_params);
$hash->{URL} = "https://api.telegram.org/bot".$hash->{Token}."/";
@@ -2305,7 +2301,7 @@ sub TelegramBot_checkAllowedPeer($$$) {
# send unauthorized to defaultpeer
my $defpeer = AttrVal($name,'defaultPeer',undef);
if ( defined( $defpeer ) ) {
- AnalyzeCommand( undef, "set $name message $ret", "" );
+ AnalyzeCommand( undef, "set $name message $ret" );
}
return 0;
@@ -2490,7 +2486,7 @@ sub TelegramBot_BinaryFileWrite($$$) {
define <name> TelegramBot <token>
Defines a TelegramBot device using the specified token perceived from botfather
-
+
Example:
set <name> <what> [<value>]
- message|msg|send [ @<peer1> ... @<peerN> ] <text>reply <msgid> [ @<peer1> ] <text>sendImage|image [ @<peer1> ... @<peerN>] <file> [<caption>]sendVoice [ @<peer1> ... @<peerN>] <file>replaceContacts <text>resetdefaultPeerCopy <1 (default) or 0>cmdKeyword <keyword>ok fhem then a message starting with this string will be executed as fhem command
(see also cmdTriggerOnly).cmdFavorites <keyword>favorites).
favorite a message of favorite to the bot will return a list of defined favorite commands and their index number. In the same case the message favorite <n> (with n being a number) would execute the command that is the n-th command in the favorites list. The result of the command will be returned as in other command executions.
@@ -2598,27 +2592,35 @@ sub TelegramBot_BinaryFileWrite($$$) {
Meaning the full format for a single favorite is /alias[description]=command where the alias can be empty or /alias=command or just the command. In any case the command can be also prefixed with a '?'.
cmdRestrictedPeer <peername(s)>cmdTriggerOnly <0 or 1>ok fhem and cmdTriggerOnly is set, then a message of ok fhem someMacro would execute the fhem command trigger someMacro.
+ allowUnknownContacts <1 or 0>saveStateOnContactChange <1 or 0>cmdReturnEmptyResult <1 or 0>allowedCommands <list of command>cmdTriggerOnly <0 or 1>ok fhem and cmdTriggerOnly is set, then a message of ok fhem someMacro would execute the fhem command trigger someMacro.pollingTimeout <number>pollingVerbose <0_None 1_Digest 2_Log>PollingErrCount and PollingLastError maxFileSize <number of bytes>maxReturnSize <number of chars>maxRetries <0,1,2,3,4,5>saveStateOnContactChange <1 or 0>allowUnknownContacts <1 or 0>textResponseConfirm <TelegramBot FHEM : $peer\n Bestätigung \n>textResponseFavorites <TelegramBot FHEM : $peer\n Favoriten \n>