sub HandlePlivoIncoming { my ($c, $req) = @_; my @Cmd = (); my $message_uuid; # my $Signature = $req->header('X-Plivo-Signature'); my $SigMa = $req->header('X-Plivo-Signature-Ma-V2'); my $Nonce = $req->header('X-Plivo-Signature-V2-Nonce'); #print "HandlePlivoIncoming: check header: PeerAddr=".inet_ntoa($c->peeraddr())."\n"; #print $req->as_string."\n"; my $sigStr = $gconstOurBaseURI; # Very weird - plivo will fail verify if you provide port 80 on # the URI, but will require the port number for verification if it # is NOT port 80. Lame! # $sigStr =~ s/:[\d]+\//\//; # NOTE! Plivo documentation is WRONG! Do not add a # trailing slash between URI and nonce as instructed. $sigStr .= $Nonce; my $encStr = encode_base64(hmac_sha256($sigStr, $gAuthToken)); $encStr =~ s/\n//; #print "----HandlePlivoIncoming: Plivo signature confirmation: ".inet_ntoa($c->peeraddr())."\n".$req->as_string."\n"; #print "----\$sigStr=$sigStr\n\$encStr=$encStr\n\$SigMa=$SigMa\n"; if ($encStr eq $SigMa) { my @spl = split(/&/, $req->content); my %rsp; foreach (@spl) { my $Ts = $_; $Ts =~ s/\+/ /g; $Ts = uri_unescape($Ts); my @spe = split(/=/, $Ts); $rsp{@spe[0]} = @spe[1]; } @Cmd[0] = $rsp{'To'}; @Cmd[1] = $rsp{'From'}; @Cmd[2] = $rsp{'Text'}; $message_uuid = $rsp{'MessageUUID'}; # Build return data, Plivo is kinda picky... my $TStr = "ID=$message_uuid"; my $QRsp = HTTP::Response->new(RC_OK, $TStr); $c->send_response($QRsp); } else { $c->send_error(RC_FORBIDDEN); print "****HandlePlivoIncoming: Failed Plivo signature confirmation: ".inet_ntoa($c->peeraddr())."\n".$req->as_string."\n"; print "****\$sigStr=$sigStr\n\$encStr=$encStr\n\$SigMa=$SigMa\n"; } if (@Cmd) { my $SuccessFetch = 0; # Arbitrarily retrying 4 times per minute for 4 mins my $Retry = 0; # 16 while ((!$SuccessFetch) && ($Retry >= 0)) { my $uri = $gBaseURI."Account/$gAuthID/Message/".$message_uuid."/"; my $req = HTTP::Request->new('GET' => $uri); $req->content_type('application/json'); $req->authorization_basic($gAuthID, $gAuthToken); my $ua = LWP::UserAgent->new; my $res = $ua->request($req); if ($res->is_success) { my $TStr = $res->content; #print "\$TStr=$TStr\n"; $TStr =~ s/^.*message_time": "([0-9\-: \t]+).*$/$1/s; $TStr =~ s/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+).*/$2\/$3\/$1 $4:$5:$6/; @Cmd[3] = $TStr; $SuccessFetch = 1; } else { print "HandlePlivoIncoming fetch msg err: ".$res->status_line."\n"; if ($Retry > 0) { sleep(15); } } $Retry--; } #print "\$Retry=$Retry, \$SuccessFetch=$SuccessFetch\n"; HandleIncomingCmds(@Cmd); } } # HandlePlivoIncoming() sub plivo_send_msg { my ($ph, $txt, $srcPh) = @_; my $contentAry = { src => $srcPh, dst => $ph, text => $txt }; my $json = JSON->new(); my $json_args = $json->encode($contentAry); #print "\$json_args=".$json_args."\n"; my $uri = $gBaseURI."Account/$gAuthID/Message/"; #print "\$uri=$uri\n"; my $req = HTTP::Request->new(POST => $uri); $req->content_type('application/json'); $req->authorization_basic($gAuthID, $gAuthToken); $req->content($json_args); my $ua = LWP::UserAgent->new; my $res = $ua->request($req); if ($res->is_success) { if ($gDebug > 7) { print "\$res=".$res->content."\n"; } } else { print "plivo_send_msg err: ".$res->status_line."\n"; if (!$gEmailSentErr) { $gEmailSentErr = 1; my $MsgStr = $res->status_line; $MsgStr .= "\n\$ph=$ph, \$srcPh=$srcPh\n\$txt=$txt"; send_err_email($MsgStr); } } } # plivo_send_msg()