mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-16 10:46:03 +00:00
50_Signalbot: Trust handling, Chat history
git-svn-id: https://svn.fhem.de/fhem/trunk@27833 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a66bb6db9d
commit
7e9a0bc0d4
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- feature: 50_Signalbot: Trust handling, Chat history
|
||||||
- change: 74_AutomowerConnect: Common.pm pervent JSON decoding error if more
|
- change: 74_AutomowerConnect: Common.pm pervent JSON decoding error if more
|
||||||
than one complete JSON string is in DevIo buffer,
|
than one complete JSON string is in DevIo buffer,
|
||||||
addPositionPolling is only settable if addPollingMinInterval > 0
|
addPositionPolling is only settable if addPollingMinInterval > 0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##############################################
|
##############################################
|
||||||
#$Id$
|
#$Id$
|
||||||
my $Signalbot_VERSION="3.13";
|
my $Signalbot_VERSION="3.15";
|
||||||
# Simple Interface to Signal CLI running as Dbus service
|
# Simple Interface to Signal CLI running as Dbus service
|
||||||
# Author: Adimarantis
|
# Author: Adimarantis
|
||||||
# License: GPL
|
# License: GPL
|
||||||
@ -23,6 +23,7 @@ use Encode;
|
|||||||
use Time::HiRes qw( usleep );
|
use Time::HiRes qw( usleep );
|
||||||
use URI::Escape;
|
use URI::Escape;
|
||||||
use HttpUtils;
|
use HttpUtils;
|
||||||
|
use MIME::Base64;
|
||||||
|
|
||||||
eval "use Protocol::DBus;1";
|
eval "use Protocol::DBus;1";
|
||||||
eval "use Protocol::DBus::Client;1" or my $DBus_missing = "yes";
|
eval "use Protocol::DBus::Client;1" or my $DBus_missing = "yes";
|
||||||
@ -63,8 +64,10 @@ use vars qw($FW_wname);
|
|||||||
"setPin" => "s", #V0.10.0
|
"setPin" => "s", #V0.10.0
|
||||||
"removePin" => "", #V0.10.0
|
"removePin" => "", #V0.10.0
|
||||||
"getGroup" => "ay", #V0.10.0
|
"getGroup" => "ay", #V0.10.0
|
||||||
|
"getIdentity" => "s", #V0.12.0
|
||||||
"addDevice" => "s",
|
"addDevice" => "s",
|
||||||
"listDevices" => "",
|
"listDevices" => "",
|
||||||
|
"listIdentities" => "", #V0.12.0
|
||||||
"unregister" => "",
|
"unregister" => "",
|
||||||
"sendEndSessionMessage" => "as", #unused
|
"sendEndSessionMessage" => "as", #unused
|
||||||
"sendRemoteDeleteMessage" => "xas", #unused
|
"sendRemoteDeleteMessage" => "xas", #unused
|
||||||
@ -83,6 +86,12 @@ use vars qw($FW_wname);
|
|||||||
"removeAdmins" => "as",
|
"removeAdmins" => "as",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
my %identitysignatures = (
|
||||||
|
#methods in the "Identities" object from V0.11.12
|
||||||
|
"trust" => "",
|
||||||
|
"trustVerified" => "s",
|
||||||
|
);
|
||||||
|
|
||||||
#dbus interfaces that only exist in registration mode
|
#dbus interfaces that only exist in registration mode
|
||||||
my %regsig = (
|
my %regsig = (
|
||||||
"listAccounts" => "",
|
"listAccounts" => "",
|
||||||
@ -115,6 +124,7 @@ sub Signalbot_Initialize($) {
|
|||||||
$hash->{createGroup} = "Signalbot_UpdateGroup_cb";
|
$hash->{createGroup} = "Signalbot_UpdateGroup_cb";
|
||||||
$hash->{joinGroup} = "Signalbot_UpdateGroup_cb";
|
$hash->{joinGroup} = "Signalbot_UpdateGroup_cb";
|
||||||
$hash->{listNumbers} = "Signalbot_ListNumbers_cb";
|
$hash->{listNumbers} = "Signalbot_ListNumbers_cb";
|
||||||
|
$hash->{listIdentities} = "Signalbot_ListIdentities_cb";
|
||||||
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:1,0 showtime:1,0 ".
|
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:1,0 showtime:1,0 ".
|
||||||
"defaultPeer: ".
|
"defaultPeer: ".
|
||||||
"allowedPeer ".
|
"allowedPeer ".
|
||||||
@ -123,6 +133,7 @@ sub Signalbot_Initialize($) {
|
|||||||
"babbleExclude ".
|
"babbleExclude ".
|
||||||
"authTimeout ".
|
"authTimeout ".
|
||||||
"authDev ".
|
"authDev ".
|
||||||
|
"authTrusted:yes,no ".
|
||||||
"cmdKeyword ".
|
"cmdKeyword ".
|
||||||
"cmdFavorite ".
|
"cmdFavorite ".
|
||||||
"favorites:textField-long ".
|
"favorites:textField-long ".
|
||||||
@ -181,6 +192,22 @@ sub Signalbot_Set($@) { #
|
|||||||
"updateGroup:textField ".
|
"updateGroup:textField ".
|
||||||
"quitGroup:textField ".
|
"quitGroup:textField ".
|
||||||
"joinGroup:textField " if $version <1000;
|
"joinGroup:textField " if $version <1000;
|
||||||
|
if ($version>=1200) {
|
||||||
|
my $ident_t="";
|
||||||
|
my $idcnt_t=1;
|
||||||
|
my $ident_u="";
|
||||||
|
foreach my $ids (keys %{$hash->{helper}{identities}}) {
|
||||||
|
if ($hash->{helper}{identities}{$ids}{TrustLevel} ne "TRUSTED_VERIFIED") {
|
||||||
|
$ident_t.= ",".$ids;
|
||||||
|
$idcnt_t++;
|
||||||
|
}
|
||||||
|
if ($hash->{helper}{identities}{$ids}{TrustLevel} eq "UNTRUSTED") {
|
||||||
|
$ident_u.= ",".$ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sets.= "trustVerified:widgetList,".$idcnt_t.",select".$ident_t.",1,textField ";
|
||||||
|
$sets.= "trust:all".$ident_u." ";
|
||||||
|
}
|
||||||
$sets.= "group:widgetList,13,select,addMembers,removeMembers,addAdmins,removeAdmins,invite,".
|
$sets.= "group:widgetList,13,select,addMembers,removeMembers,addAdmins,removeAdmins,invite,".
|
||||||
"create,delete,block,unblock,update,".
|
"create,delete,block,unblock,update,".
|
||||||
"quit,join,1,textField contact:widgetList,5,select,add,delete,block,unblock,1,textField " if $version >=1000;
|
"quit,join,1,textField contact:widgetList,5,select,add,delete,block,unblock,1,textField " if $version >=1000;
|
||||||
@ -200,10 +227,6 @@ sub Signalbot_Set($@) { #
|
|||||||
|
|
||||||
# Works always
|
# Works always
|
||||||
if ( $cmd eq "reinit") {
|
if ( $cmd eq "reinit") {
|
||||||
$hash->{helper}{qr}=undef;
|
|
||||||
$hash->{helper}{register}=undef;
|
|
||||||
$hash->{helper}{verification}=undef;
|
|
||||||
$hash->{helper}{captcha}=undef;
|
|
||||||
my $ret = Signalbot_setup($hash);
|
my $ret = Signalbot_setup($hash);
|
||||||
$hash->{STATE} = $ret if defined $ret;
|
$hash->{STATE} = $ret if defined $ret;
|
||||||
Signalbot_createRegfiles($hash);
|
Signalbot_createRegfiles($hash);
|
||||||
@ -230,9 +253,6 @@ sub Signalbot_Set($@) { #
|
|||||||
my $ret = Signalbot_setAccount($hash, $number);
|
my $ret = Signalbot_setAccount($hash, $number);
|
||||||
# undef is success
|
# undef is success
|
||||||
if (!defined $ret) {
|
if (!defined $ret) {
|
||||||
$hash->{helper}{qr}=undef;
|
|
||||||
$hash->{helper}{register}=undef;
|
|
||||||
$hash->{helper}{verification}=undef;
|
|
||||||
$ret=Signalbot_setup($hash);
|
$ret=Signalbot_setup($hash);
|
||||||
$hash->{STATE} = $ret if defined $ret;
|
$hash->{STATE} = $ret if defined $ret;
|
||||||
return undef;
|
return undef;
|
||||||
@ -270,10 +290,6 @@ sub Signalbot_Set($@) { #
|
|||||||
#delete account and do a reinit
|
#delete account and do a reinit
|
||||||
Signalbot_disconnect($hash);
|
Signalbot_disconnect($hash);
|
||||||
readingsSingleUpdate($hash, 'account', "none", 0);
|
readingsSingleUpdate($hash, 'account', "none", 0);
|
||||||
$hash->{helper}{qr}=undef;
|
|
||||||
$hash->{helper}{register}=undef;
|
|
||||||
$hash->{helper}{verification}=undef;
|
|
||||||
$hash->{helper}{captcha}=undef;
|
|
||||||
$ret = Signalbot_setup($hash);
|
$ret = Signalbot_setup($hash);
|
||||||
$hash->{STATE} = $ret if defined $ret;
|
$hash->{STATE} = $ret if defined $ret;
|
||||||
Signalbot_createRegfiles($hash);
|
Signalbot_createRegfiles($hash);
|
||||||
@ -441,6 +457,15 @@ sub Signalbot_Set($@) { #
|
|||||||
return $ret if defined $ret;
|
return $ret if defined $ret;
|
||||||
}
|
}
|
||||||
return undef;
|
return undef;
|
||||||
|
} elsif ( $cmd eq "trust" ) {
|
||||||
|
my $number = shift @args;
|
||||||
|
return "not implemented" if $number eq "all";
|
||||||
|
my $ret=Signalbot_CallSI($hash,"trust",$number);
|
||||||
|
return $ret;
|
||||||
|
} elsif ( $cmd eq "trustVerified") {
|
||||||
|
my @cm = split(",",$args[0]);
|
||||||
|
my $ret=Signalbot_CallSI($hash,"trustVerified",$cm[0],$cm[1]);
|
||||||
|
return $ret;
|
||||||
} elsif ( $cmd eq "send" || $cmd eq "reply" || $cmd eq "msg") {
|
} elsif ( $cmd eq "send" || $cmd eq "reply" || $cmd eq "msg") {
|
||||||
return "Usage: set ".$hash->{NAME}." send [@<Recipient1> ... @<RecipientN>] [#<GroupId1> ... #<GroupIdN>] [&<Attachment1> ... &<AttachmentN>] [<Text>]" if ( @args==0);
|
return "Usage: set ".$hash->{NAME}." send [@<Recipient1> ... @<RecipientN>] [#<GroupId1> ... #<GroupIdN>] [&<Attachment1> ... &<AttachmentN>] [<Text>]" if ( @args==0);
|
||||||
|
|
||||||
@ -539,6 +564,7 @@ sub Signalbot_prepareSend($@) {
|
|||||||
return "Specify either a message text or an attachment" if((@attachments==0) && (@args==0));
|
return "Specify either a message text or an attachment" if((@attachments==0) && (@args==0));
|
||||||
|
|
||||||
$message = join(" ", @args);
|
$message = join(" ", @args);
|
||||||
|
my @orgatt=@attachments;
|
||||||
if (@attachments>0) {
|
if (@attachments>0) {
|
||||||
#create copy in /tmp to mitigate incomplete files and relative paths in fhem
|
#create copy in /tmp to mitigate incomplete files and relative paths in fhem
|
||||||
my @newatt;
|
my @newatt;
|
||||||
@ -570,11 +596,15 @@ sub Signalbot_prepareSend($@) {
|
|||||||
#Send message to individuals (bulk)
|
#Send message to individuals (bulk)
|
||||||
if (@recipients > 0) {
|
if (@recipients > 0) {
|
||||||
$ret=Signalbot_sendMessage($hash,join(",",@recipients),join(",",@attachments),$message);
|
$ret=Signalbot_sendMessage($hash,join(",",@recipients),join(",",@attachments),$message);
|
||||||
|
foreach my $sender (@recipients) {
|
||||||
|
Signalbot_AddToChat($hash,"Me",$sender,"",$message.(@attachments>0?"(".join(",",@orgatt).")":""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (@groups > 0) {
|
if (@groups > 0) {
|
||||||
#Send message to groups (one at time)
|
#Send message to groups (one at time)
|
||||||
while(my $currgroup = shift @groups){
|
while(my $currgroup = shift @groups){
|
||||||
$ret=Signalbot_sendGroupMessage($hash,$currgroup,join(",",@attachments),$message);
|
$ret=Signalbot_sendGroupMessage($hash,$currgroup,join(",",@attachments),$message);
|
||||||
|
Signalbot_AddToChat($hash,"Me","",$currgroup,$message.(@attachments>0?"(".join(",",@orgatt).")":""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#Remember temp files
|
#Remember temp files
|
||||||
@ -603,7 +633,46 @@ sub Signalbot_Get($@) {
|
|||||||
my $gets="favorites:noArg accounts:noArg helpUnicode:noArg ";
|
my $gets="favorites:noArg accounts:noArg helpUnicode:noArg ";
|
||||||
$gets.="contacts:all,nonblocked ".
|
$gets.="contacts:all,nonblocked ".
|
||||||
"groups:all,active,nonblocked devices:noArg " if $account ne "none";
|
"groups:all,active,nonblocked devices:noArg " if $account ne "none";
|
||||||
$gets .="groupProperties:textField " if $version >= 1000;
|
|
||||||
|
my $chat_t="";
|
||||||
|
my $chat_cnt=0;
|
||||||
|
foreach my $chat (keys %{$hash->{helper}{chat}}) {
|
||||||
|
$chat_t.="," if $chat_cnt>0;
|
||||||
|
$chat_t.=$chat;
|
||||||
|
$chat_cnt++;
|
||||||
|
}
|
||||||
|
if ($chat_cnt>0) {
|
||||||
|
$chat_t=~s/ / /g;
|
||||||
|
$gets.= "chat:".($chat_cnt<20?$chat_t:"textField")." ";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $group_t="";
|
||||||
|
my $grcnt_t=0;
|
||||||
|
foreach my $group (keys %{$hash->{helper}{groups}}) {
|
||||||
|
$group_t.="," if $grcnt_t>0;
|
||||||
|
$group_t.=$hash->{helper}{groups}{$group}{name};
|
||||||
|
$grcnt_t++;
|
||||||
|
}
|
||||||
|
if ($grcnt_t>0) {
|
||||||
|
$group_t=~s/ / /g;
|
||||||
|
$gets.= "groupProperties:".($grcnt_t<20?$group_t:"textField")." ";
|
||||||
|
}
|
||||||
|
if ($version>=1200) {
|
||||||
|
my $ident_t="";
|
||||||
|
my $idcnt_t=0;
|
||||||
|
foreach my $number (keys %{$hash->{helper}{identities}}) {
|
||||||
|
$ident_t.="," if $idcnt_t>0;
|
||||||
|
$ident_t.= $number;
|
||||||
|
if (exists $hash->{helper}{contacts}{$number}) {
|
||||||
|
my $cname=$hash->{helper}{contacts}{$number} ne ""?$hash->{helper}{contacts}{$number}:"Unknown";
|
||||||
|
$ident_t.="($cname)";
|
||||||
|
}
|
||||||
|
$idcnt_t++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ident_t=~s/ /_/g;
|
||||||
|
$gets.= "identityDetails:".($idcnt_t<20?$ident_t:"textField")." ";
|
||||||
|
}
|
||||||
return "Signalbot_Get: Unknown argument $cmd, choose one of ".$gets;
|
return "Signalbot_Get: Unknown argument $cmd, choose one of ".$gets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,6 +701,55 @@ sub Signalbot_Get($@) {
|
|||||||
$str.=sprintf("%2i %s\n",$devid,$devname);
|
$str.=sprintf("%2i %s\n",$devid,$devname);
|
||||||
}
|
}
|
||||||
return $str;
|
return $str;
|
||||||
|
} elsif ($cmd eq "identityDetails") {
|
||||||
|
$arg=~/(^.*)(\(.*\)$)/;
|
||||||
|
my $number;
|
||||||
|
if ($1) {
|
||||||
|
$number=$1;
|
||||||
|
} else {
|
||||||
|
$number=$arg;
|
||||||
|
}
|
||||||
|
my $str="Details for $number\n\n";
|
||||||
|
if ($number =~ /^\+[1-9][0-9]{5,}$/) {
|
||||||
|
my $contact=Signalbot_getContactName($hash,$number);
|
||||||
|
my $path=Signalbot_getIdentityPath($hash,$number);
|
||||||
|
return "Unknown identity ".$number if !defined $path;
|
||||||
|
my $ret=Signalbot_getIdentityProperties($hash,$path);
|
||||||
|
if (defined $ret) {
|
||||||
|
my %props=%$ret;
|
||||||
|
$str.="Contact Name :".$contact."\n";
|
||||||
|
$str.="Trust Level :".$props{TrustLevel}."\n";
|
||||||
|
$str.="Safety Number :".$props{SafetyNumber}."\n";
|
||||||
|
#Don't display as it is very long and not sure what it's used for anyway
|
||||||
|
my $fp=$props{Fingerprint};
|
||||||
|
#$str.="Fingerprint :".join(" ",@$fp)."\n";
|
||||||
|
$str.="Added date :". strftime("%d-%m-%Y %H:%M:%S", localtime($props{AddedDate}/1000))."\n";
|
||||||
|
my $sf=$props{ScannableSafetyNumber};
|
||||||
|
my $cstr=pack("C*",@$sf);
|
||||||
|
my $fn=Signalbot_copyToFile($cstr,"dat");
|
||||||
|
unlink "www/signal/qr.png";
|
||||||
|
my $ret=qx(qrencode -r $fn -o www/signal/qr.png);
|
||||||
|
unlink $fn;
|
||||||
|
if (-e "www/signal/qr.png") {
|
||||||
|
$str.="Scannable Safety Number to validate FHEM from Mobile:\n";
|
||||||
|
my $qr_url .= "fhem/signal/qr.png?".gettimeofday(); #adding timestamp to prevent image caching by the browser
|
||||||
|
$str .= "<a href=\"$qr_url\"><img src=\"$qr_url\"><\/a><br>";
|
||||||
|
} else {
|
||||||
|
$str.="Could not generate QR Code. Check if qrencode is installed.\n".$ret."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $str;
|
||||||
|
} elsif ($cmd eq "chat") {
|
||||||
|
my $ret="";
|
||||||
|
my $chat=$hash->{helper}{chat}{$arg};
|
||||||
|
if (defined $chat) {
|
||||||
|
$ret.="Chat history with $arg\n\n";
|
||||||
|
$ret.=$chat;
|
||||||
|
} else {
|
||||||
|
$ret="No chat history with $arg";
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
} elsif ($cmd eq "favorites") {
|
} elsif ($cmd eq "favorites") {
|
||||||
my $favs = AttrVal($name,"favorites","");
|
my $favs = AttrVal($name,"favorites","");
|
||||||
$favs =~ s/[\n\r]//g;
|
$favs =~ s/[\n\r]//g;
|
||||||
@ -712,6 +830,8 @@ sub Signalbot_Get($@) {
|
|||||||
return $ret;
|
return $ret;
|
||||||
} elsif ($cmd eq "groupProperties") {
|
} elsif ($cmd eq "groupProperties") {
|
||||||
return if $version<1000;
|
return if $version<1000;
|
||||||
|
$arg=decode_utf8($arg); #required to fully replace  
|
||||||
|
$arg=~s/$&\x{00a0}/ /g; #Restore normal spaces
|
||||||
my $ret=Signalbot_getGroupProperties($hash,$arg);
|
my $ret=Signalbot_getGroupProperties($hash,$arg);
|
||||||
return "Error:".$hash->{helper}{lasterr} if !defined $ret;
|
return "Error:".$hash->{helper}{lasterr} if !defined $ret;
|
||||||
my %props=%$ret;
|
my %props=%$ret;
|
||||||
@ -754,38 +874,48 @@ sub Signalbot_command($@){
|
|||||||
return $message if $timeout==0;
|
return $message if $timeout==0;
|
||||||
my $cmd=AttrVal($hash->{NAME},"cmdKeyword",undef);
|
my $cmd=AttrVal($hash->{NAME},"cmdKeyword",undef);
|
||||||
return $message unless defined $cmd;
|
return $message unless defined $cmd;
|
||||||
|
my $trust=0;
|
||||||
|
if (exists $hash->{helper}{identities}{$sender} and exists $hash->{helper}{identities}{$sender}{TrustLevel} and
|
||||||
|
$hash->{helper}{identities}{$sender}{TrustLevel} eq "TRUSTED_VERIFIED" and AttrVal($hash->{NAME},"authTrusted","no") eq "yes") {
|
||||||
|
$trust=1;
|
||||||
|
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": $sender is trusted";
|
||||||
|
} else {
|
||||||
|
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": $sender is not trusted";
|
||||||
|
}
|
||||||
my @arr=();
|
my @arr=();
|
||||||
if ($message =~ /^$cmd(.*)/) {
|
if ($message =~ /^$cmd(.*)/) {
|
||||||
$cmd=$1;
|
$cmd=$1;
|
||||||
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Command received:$cmd";
|
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Command received:$cmd";
|
||||||
my $device=AttrVal($hash->{NAME},"authDev",undef);
|
my $device=AttrVal($hash->{NAME},"authDev",undef);
|
||||||
if (!defined $device) {
|
if (!defined $device and $trust==0) {
|
||||||
readingsSingleUpdate($hash, 'lastError', "Missing GoogleAuth device in authDev to execute remote command",1);
|
readingsSingleUpdate($hash, 'lastError', "Missing GoogleAuth device in authDev to execute remote command",1);
|
||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
my @cc=split(" ",$cmd);
|
my @cc=split(" ",$cmd);
|
||||||
if ($cc[0] =~ /^\d+$/) {
|
if ($cc[0] =~ /^\d+$/) {
|
||||||
#This could be a token
|
|
||||||
my $token=shift @cc;
|
|
||||||
my $restcmd=join(" ",@cc);
|
my $restcmd=join(" ",@cc);
|
||||||
my $ret = gAuth($device,$token);
|
if ($trust == 0) {
|
||||||
if ($ret == 1) {
|
#This could be a token
|
||||||
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Token valid for sender $sender for $timeout seconds";
|
my $token=shift @cc;
|
||||||
$hash->{helper}{auth}{$sender}=1;
|
my $ret = gAuth($device,$token);
|
||||||
#Remove potential old timer so countdown start from scratch
|
if ($ret == 1) {
|
||||||
RemoveInternalTimer("$hash->{NAME} $sender");
|
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Token valid for sender $sender for $timeout seconds";
|
||||||
InternalTimer(gettimeofday() + $timeout, 'Signalbot_authTimeout', "$hash->{NAME} $sender", 0);
|
$hash->{helper}{auth}{$sender}=1;
|
||||||
Signalbot_sendMessage($hash,$sender,"","You have control for ".$timeout."s");
|
#Remove potential old timer so countdown start from scratch
|
||||||
$cmd=$restcmd;
|
RemoveInternalTimer("$hash->{NAME} $sender");
|
||||||
} else {
|
InternalTimer(gettimeofday() + $timeout, 'Signalbot_authTimeout', "$hash->{NAME} $sender", 0);
|
||||||
LogUnicode $hash->{NAME}, 3, $hash->{NAME}.": Invalid token sent by $sender";
|
Signalbot_sendMessage($hash,$sender,"","You have control for ".$timeout."s");
|
||||||
$hash->{helper}{auth}{$sender}=0;
|
$cmd=$restcmd;
|
||||||
Signalbot_sendMessage($hash,$sender,"","Invalid token");
|
} else {
|
||||||
LogUnicode $hash->{NAME}, 2, $hash->{NAME}.": Invalid token sent by $sender:$message";
|
LogUnicode $hash->{NAME}, 3, $hash->{NAME}.": Invalid token sent by $sender";
|
||||||
return $cmd;
|
$hash->{helper}{auth}{$sender}=0;
|
||||||
|
Signalbot_sendMessage($hash,$sender,"","Invalid token");
|
||||||
|
LogUnicode $hash->{NAME}, 2, $hash->{NAME}.": Invalid token sent by $sender:$message";
|
||||||
|
return $cmd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my $auth=0;
|
my $auth=$trust;
|
||||||
if (defined $hash->{helper}{auth}{$sender} && $hash->{helper}{auth}{$sender}==1) {
|
if (defined $hash->{helper}{auth}{$sender} && $hash->{helper}{auth}{$sender}==1) {
|
||||||
$auth=1;
|
$auth=1;
|
||||||
}
|
}
|
||||||
@ -992,6 +1122,8 @@ sub Signalbot_MessageReceived ($@) {
|
|||||||
readingsBulkUpdate($hash, "msgText", $message);
|
readingsBulkUpdate($hash, "msgText", $message);
|
||||||
readingsBulkUpdate($hash, "msgSender", $sender);
|
readingsBulkUpdate($hash, "msgSender", $sender);
|
||||||
readingsBulkUpdate($hash, "msgGroupName", $group);
|
readingsBulkUpdate($hash, "msgGroupName", $group);
|
||||||
|
Signalbot_AddToChat($hash,$sender,$sender,$group,$message);
|
||||||
|
|
||||||
#Check if for command execution
|
#Check if for command execution
|
||||||
my $auth=0;
|
my $auth=0;
|
||||||
if (defined $hash->{helper}{auth}{$source}) { $auth=$hash->{helper}{auth}{$source}; }
|
if (defined $hash->{helper}{auth}{$source}) { $auth=$hash->{helper}{auth}{$source}; }
|
||||||
@ -1031,6 +1163,25 @@ sub Signalbot_MessageReceived ($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub Signalbot_AddToChat($$$$$) {
|
||||||
|
my ($hash,$name,$sender,$group,$message) = @_;
|
||||||
|
$group=~s/#//g;
|
||||||
|
$group=~s/ /_/g;
|
||||||
|
$sender=~s/ /_/g;
|
||||||
|
print "$group:$sender:\n";
|
||||||
|
my $index=$sender;
|
||||||
|
$index="+".$group if $group ne "";
|
||||||
|
my $text=$hash->{helper}{chat}{$index};
|
||||||
|
$text.="<b>$name</b> (".strftime("%d-%m-%Y %H:%M", localtime)."): $message\n";
|
||||||
|
my $line_count =()= $text =~ m/<b>/g;
|
||||||
|
while ($line_count>20) {
|
||||||
|
$text=~s/<b>.*?<b>//ms;
|
||||||
|
$text="<b>".$text; #restore <b> that was removed before
|
||||||
|
$line_count =()= $text =~ m/<b>/g;
|
||||||
|
}
|
||||||
|
$hash->{helper}{chat}{$index}=$text;
|
||||||
|
}
|
||||||
|
|
||||||
sub Signalbot_ReceiptReceived {
|
sub Signalbot_ReceiptReceived {
|
||||||
my ($hash, $timestamp, $source) = @_;
|
my ($hash, $timestamp, $source) = @_;
|
||||||
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Signalbot_receive_callback $timestamp $source ";
|
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Signalbot_receive_callback $timestamp $source ";
|
||||||
@ -1099,7 +1250,13 @@ sub Signalbot_setup($@){
|
|||||||
}
|
}
|
||||||
#Clear error on init to avoid confusion with old erros
|
#Clear error on init to avoid confusion with old erros
|
||||||
readingsSingleUpdate($hash, 'lastError', "ok",0);
|
readingsSingleUpdate($hash, 'lastError', "ok",0);
|
||||||
delete $hash->{helper}{contacts};
|
$hash->{helper}{contacts}=undef;
|
||||||
|
$hash->{helper}{qr}=undef;
|
||||||
|
$hash->{helper}{register}=undef;
|
||||||
|
$hash->{helper}{verification}=undef;
|
||||||
|
$hash->{helper}{captcha}=undef;
|
||||||
|
$hash->{helper}{chat}=undef;
|
||||||
|
|
||||||
my $dbus = Protocol::DBus::Client::system();
|
my $dbus = Protocol::DBus::Client::system();
|
||||||
if (!defined $dbus) {
|
if (!defined $dbus) {
|
||||||
Log3 $name, 3, $hash->{NAME}.": Error while initializing Dbus";
|
Log3 $name, 3, $hash->{NAME}.": Error while initializing Dbus";
|
||||||
@ -1141,6 +1298,7 @@ sub Signalbot_setup2($@) {
|
|||||||
}
|
}
|
||||||
if (!$dbus->initialize()) { $dbus->init_pending_send(); return; }
|
if (!$dbus->initialize()) { $dbus->init_pending_send(); return; }
|
||||||
$hash->{helper}{init}=1;
|
$hash->{helper}{init}=1;
|
||||||
|
delete $hash->{helper}{identities};
|
||||||
|
|
||||||
#Restore contactlist into internal hash
|
#Restore contactlist into internal hash
|
||||||
my $clist=ReadingsVal($hash->{NAME}, "contactList",undef);
|
my $clist=ReadingsVal($hash->{NAME}, "contactList",undef);
|
||||||
@ -1214,6 +1372,7 @@ sub Signalbot_setup2($@) {
|
|||||||
#-u Mode or already registered
|
#-u Mode or already registered
|
||||||
if ($num<0 || $account ne "none") {
|
if ($num<0 || $account ne "none") {
|
||||||
Signalbot_CallA($hash,"listNumbers");
|
Signalbot_CallA($hash,"listNumbers");
|
||||||
|
Signalbot_CallA($hash,"listIdentities") if $version>=1200;
|
||||||
#Might make sense to call refreshGroups here, however, that is a sync call and might potentially take longer, so maybe no good idea in startup
|
#Might make sense to call refreshGroups here, however, that is a sync call and might potentially take longer, so maybe no good idea in startup
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
readingsBulkUpdate($hash, 'account', $account) if defined $account;
|
readingsBulkUpdate($hash, 'account', $account) if defined $account;
|
||||||
@ -1247,6 +1406,25 @@ sub Signalbot_ListNumbers_cb($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Async Callback after getting list of Numbers, results will also be filled asynchronous
|
||||||
|
sub Signalbot_ListIdentities_cb($@) {
|
||||||
|
my ($hash,$rec) = @_;
|
||||||
|
return if !defined $rec or $rec ==0;
|
||||||
|
foreach my $ident (@$rec) {
|
||||||
|
my ($idpath,$uuid,$number)=@$ident;
|
||||||
|
#Only for valid numbers - ignore numbers that only have uuids to avoid an error
|
||||||
|
if ($number =~ /^\+[1-9][0-9]{5,}$/) {
|
||||||
|
my $ret=Signalbot_getIdentityProperties($hash,$idpath);
|
||||||
|
if (defined $ret) {
|
||||||
|
my %props=%$ret;
|
||||||
|
my $level=$props{TrustLevel};
|
||||||
|
$hash->{helper}{identities}{$number}{TrustLevel}=$props{TrustLevel};
|
||||||
|
$hash->{helper}{identities}{$number}{SafetyNumber}=$props{SafetyNumber};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#async
|
#async
|
||||||
sub Signalbot_CallA($@) {
|
sub Signalbot_CallA($@) {
|
||||||
my ($hash,$function,@args) = @_;
|
my ($hash,$function,@args) = @_;
|
||||||
@ -1278,6 +1456,17 @@ sub Signalbot_CallSG($@) {
|
|||||||
return Signalbot_CallDbus($hash,1,$path,$function,$prototype,'org.asamk.Signal',@args);
|
return Signalbot_CallDbus($hash,1,$path,$function,$prototype,'org.asamk.Signal',@args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#sync, identity
|
||||||
|
sub Signalbot_CallSI($@) {
|
||||||
|
my ($hash,$function,$identity,@args) = @_;
|
||||||
|
print "Calling $function for $identity with";
|
||||||
|
my $prototype=$identitysignatures{$function};
|
||||||
|
my $path=Signalbot_getIdentityPath($hash,$identity);
|
||||||
|
return if !defined $path;
|
||||||
|
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Calling $function($prototype) $path Args:$args[0]";
|
||||||
|
return Signalbot_CallDbus($hash,1,$path,$function,$prototype,'org.asamk.Signal',@args);
|
||||||
|
}
|
||||||
|
|
||||||
#all group properties
|
#all group properties
|
||||||
sub Signalbot_getGroupProperties($@) {
|
sub Signalbot_getGroupProperties($@) {
|
||||||
my ($hash,$group) = @_;
|
my ($hash,$group) = @_;
|
||||||
@ -1287,6 +1476,14 @@ sub Signalbot_getGroupProperties($@) {
|
|||||||
return Signalbot_CallDbus($hash,1,$path,'GetAll',$prototype,'org.freedesktop.DBus.Properties','org.asamk.Signal.Group');
|
return Signalbot_CallDbus($hash,1,$path,'GetAll',$prototype,'org.freedesktop.DBus.Properties','org.asamk.Signal.Group');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#all identity properties by path
|
||||||
|
sub Signalbot_getIdentityProperties($@) {
|
||||||
|
my ($hash,$path) = @_;
|
||||||
|
my $prototype="s";
|
||||||
|
return if !defined $path;
|
||||||
|
return Signalbot_CallDbus($hash,1,$path,'GetAll',$prototype,'org.freedesktop.DBus.Properties','org.asamk.Signal.Identity');
|
||||||
|
}
|
||||||
|
|
||||||
sub Signalbot_removeDevice($@) {
|
sub Signalbot_removeDevice($@) {
|
||||||
my ($hash,$devid) = @_;
|
my ($hash,$devid) = @_;
|
||||||
return "DeviceID needs to be numeric" if (!looks_like_number($devid));
|
return "DeviceID needs to be numeric" if (!looks_like_number($devid));
|
||||||
@ -1326,9 +1523,9 @@ sub Signalbot_CallDbus($@) {
|
|||||||
) ->then ( sub () {
|
) ->then ( sub () {
|
||||||
$got_response = 1;
|
$got_response = 1;
|
||||||
return if $sync; # Synchronous mode, handling of return data in main loop
|
return if $sync; # Synchronous mode, handling of return data in main loop
|
||||||
|
|
||||||
#Only for asynchronous case:
|
#Only for asynchronous case:
|
||||||
my $msg = shift;
|
my $msg = shift;
|
||||||
|
|
||||||
my $sig = $msg->get_header('SIGNATURE');
|
my $sig = $msg->get_header('SIGNATURE');
|
||||||
if (!defined $sig) {
|
if (!defined $sig) {
|
||||||
#Empty signature is probably a reply from a function without return data, nothing to do
|
#Empty signature is probably a reply from a function without return data, nothing to do
|
||||||
@ -1350,6 +1547,10 @@ sub Signalbot_CallDbus($@) {
|
|||||||
readingsSingleUpdate($hash, 'lastError', $hash->{helper}{lasterr},1);
|
readingsSingleUpdate($hash, 'lastError', $hash->{helper}{lasterr},1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(ref $msg eq ref {})) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
my $sig = $msg->get_header('SIGNATURE');
|
my $sig = $msg->get_header('SIGNATURE');
|
||||||
if (!defined $sig) {
|
if (!defined $sig) {
|
||||||
$hash->{helper}{lasterr}="Error in $function: message without signature";
|
$hash->{helper}{lasterr}="Error in $function: message without signature";
|
||||||
@ -1370,7 +1571,6 @@ sub Signalbot_CallDbus($@) {
|
|||||||
while ($counter>0) {
|
while ($counter>0) {
|
||||||
$dbus->blocking(1);
|
$dbus->blocking(1);
|
||||||
my $msg=$dbus->get_message();
|
my $msg=$dbus->get_message();
|
||||||
#print Dumper($msg);
|
|
||||||
if (defined $msg) {
|
if (defined $msg) {
|
||||||
my $sig = $msg->get_header('SIGNATURE');
|
my $sig = $msg->get_header('SIGNATURE');
|
||||||
if (!defined $sig) {
|
if (!defined $sig) {
|
||||||
@ -1413,6 +1613,18 @@ sub Signalbot_getGroupPath($@) {
|
|||||||
return $path
|
return $path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub Signalbot_getIdentityPath($@) {
|
||||||
|
my ($hash,$identity) = @_;
|
||||||
|
my $path=Signalbot_CallS($hash,"getIdentity",$identity);
|
||||||
|
return if !defined $path;
|
||||||
|
LogUnicode $hash->{NAME}, 5, $hash->{NAME}.": Identity Dbus Path=".$path;
|
||||||
|
if (! ($path =~ /^\//)) {
|
||||||
|
$hash->{helper}{lasterr}=$path;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
return $path
|
||||||
|
}
|
||||||
|
|
||||||
sub Signalbot_Read($@){
|
sub Signalbot_Read($@){
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
if (!defined $hash->{helper}{init}) { Signalbot_setup2($hash); return;};
|
if (!defined $hash->{helper}{init}) { Signalbot_setup2($hash); return;};
|
||||||
@ -2630,6 +2842,15 @@ For German documentation see <a href="https://wiki.fhem.de/wiki/Signalbot">Wiki<
|
|||||||
<li>block/unblock <contact> : block/unblock receiving messages from contact</li>
|
<li>block/unblock <contact> : block/unblock receiving messages from contact</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li><b>set trust <number|all></b><br>
|
||||||
|
<a id="Signalbot-set-trust"></a>
|
||||||
|
Set the unverified trust for a number. Specifying all will set it for all known contacts<br>
|
||||||
|
</li>
|
||||||
|
<li><b>set trustVerified <number> <safetynumber></b><br>
|
||||||
|
<a id="Signalbot-set-trustVerified"></a>
|
||||||
|
Set the verified trust for a number. You can get the safetynumber via "get identityDetails" though the safest way is to ask your contact to send you
|
||||||
|
the number via a safe channel and use that one.<br>
|
||||||
|
</li>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -2663,10 +2884,15 @@ For German documentation see <a href="https://wiki.fhem.de/wiki/Signalbot">Wiki<
|
|||||||
Opens a cheat sheet for all supported replacements to format text or add emoticons using html-like tags or markdown.<br>
|
Opens a cheat sheet for all supported replacements to format text or add emoticons using html-like tags or markdown.<br>
|
||||||
<b>Note:</b> This functionality needs to be enabled using the "formatting" attribute.<br>
|
<b>Note:</b> This functionality needs to be enabled using the "formatting" attribute.<br>
|
||||||
</li>
|
</li>
|
||||||
<li><b>get groupPropertiese <group></b><br>
|
<li><b>get groupProperties <group></b><br>
|
||||||
<a id="Signalbot-get-groupPropertiese"></a>
|
<a id="Signalbot-get-groupProperties"></a>
|
||||||
Shows all known properties of the given group, like members, admins and permissions.
|
Shows all known properties of the given group, like members, admins and permissions.
|
||||||
</li>
|
</li>
|
||||||
|
<li><b>get identityDetails <group></b><br>
|
||||||
|
<a id="Signalbot-get-identityDetails"></a>
|
||||||
|
Shows all known details of a contacts identity.<br>
|
||||||
|
This includes the safetynumber for verification purposes.
|
||||||
|
</li>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -2688,6 +2914,10 @@ For German documentation see <a href="https://wiki.fhem.de/wiki/Signalbot">Wiki<
|
|||||||
<a id="Signalbot-attr-authDev"></a>
|
<a id="Signalbot-attr-authDev"></a>
|
||||||
Name of GoogleAuth device. Will normally be automatically filled when setting an authTimeout or cmdKeyword if a GoogleAuth device is already existing.<br>
|
Name of GoogleAuth device. Will normally be automatically filled when setting an authTimeout or cmdKeyword if a GoogleAuth device is already existing.<br>
|
||||||
</li>
|
</li>
|
||||||
|
<li><b>authTrusted yes|no</b><br>
|
||||||
|
<a id="Signalbot-attr-authTrusted"></a>
|
||||||
|
Do not require GoogleAuth for TRUSTED_VERIFIED contacts (see "set trustedVerified") if set to "yes".<br>
|
||||||
|
</li>
|
||||||
<li><b>autoJoin no|yes</b><br>
|
<li><b>autoJoin no|yes</b><br>
|
||||||
<a id="Signalbot-attr-autoJoin"></a>
|
<a id="Signalbot-attr-autoJoin"></a>
|
||||||
If set to yes, Signalbot will automatically inspect incoming messages for group invite links and join that group.<br>
|
If set to yes, Signalbot will automatically inspect incoming messages for group invite links and join that group.<br>
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#$Id:$
|
#$Id:$
|
||||||
SCRIPTVERSION="3.16"
|
SCRIPTVERSION="3.18"
|
||||||
# Author: Adimarantis
|
# Author: Adimarantis
|
||||||
# License: GPL
|
# License: GPL
|
||||||
#Install script for signal-cli
|
#Install script for signal-cli
|
||||||
SIGNALPATH=/opt
|
SIGNALPATH=/opt
|
||||||
SIGNALUSER=signal-cli
|
SIGNALUSER=signal-cli
|
||||||
LIBPATH=/usr/lib
|
LIBPATH=/usr/lib
|
||||||
SIGNALVERSION="0.11.10"
|
SIGNALVERSION="0.12.0"
|
||||||
LIBRARYVERSION="0.23.1"
|
#Check for latest valid version at https://github.com/AsamK/signal-cli/releases
|
||||||
|
LIBRARYVERSION="0.30.0"
|
||||||
|
#Check for latest valid version at https://github.com/exquo/signal-libs-build/releases
|
||||||
|
#Make sure this matches the required version for signal-cli (see lib/libsignal-client-0.xx.x.jar version in signal-cli)
|
||||||
LIBSIG=libsignal_jni.tgz
|
LIBSIG=libsignal_jni.tgz
|
||||||
SIGNALVAR=/var/lib/$SIGNALUSER
|
SIGNALVAR=/var/lib/$SIGNALUSER
|
||||||
DBSYSTEMD=/etc/dbus-1/system.d
|
DBSYSTEMD=/etc/dbus-1/system.d
|
||||||
@ -245,6 +248,8 @@ install_and_check diff diffutils
|
|||||||
install_and_check dbus-send dbus
|
install_and_check dbus-send dbus
|
||||||
install_and_check cpan cpanminus
|
install_and_check cpan cpanminus
|
||||||
install_and_check zip zip
|
install_and_check zip zip
|
||||||
|
install_and_check qrencode
|
||||||
|
|
||||||
if [ -z "$BASH" ]; then
|
if [ -z "$BASH" ]; then
|
||||||
echo "This script requires bash for some functions. Check if bash is installed."
|
echo "This script requires bash for some functions. Check if bash is installed."
|
||||||
install_and_check bash bash
|
install_and_check bash bash
|
||||||
@ -410,7 +415,7 @@ if [ $NEEDINSTALL = 1 ]; then
|
|||||||
fi
|
fi
|
||||||
echo "done"
|
echo "done"
|
||||||
rm -f /tmp/signal-cli-$SIGNALVERSION.tar.gz
|
rm -f /tmp/signal-cli-$SIGNALVERSION.tar.gz
|
||||||
#rm -f /tmp/$LIBSIG
|
rm -f /tmp/$LIBSIG
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user