<?php
/**
 * @copyright 2021 Double Bastion LLC <www.doublebastion.com>
 *
 * @author Double Bastion LLC
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

declare(strict_types=1);

namespace OCA\SMSRelentless\Controller;

use OCP\AppFramework\ApiController;
use OCP\IRequest;
use OCA\SMSRelentless\Service\SmsrelentlessService;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IUserSession;
use OCP\IConfig;
use \DateTime;
use OCP\AppFramework\Controller;
use OCP\Files\IAppData;
use OCP\AppFramework\App;
use OCP\Files\NotPermittedException;
use \ReflectionClass;
use OCP\Notification\INotification;
use OCP\Notification\IManager;
use OCP\IDBConnection;
use OCP\IUserManager;
use Plivo\RestClient;
use Plivo\Util\signatureValidation;


class AuthorApiController extends ApiController {

    private $service;
    private $userId;
    private $config;
    private $connection;
    private $userManager;
    private $manager;

    public function __construct($appName, IRequest $request, SmsrelentlessService $service, $userId, IConfig $config, IDBConnection $connection, IUserManager $userManager, IManager $manager) {
        parent::__construct(
            $appName,
            $request,
            'PUT, POST, GET, DELETE, PATCH',
            'Authorization, Content-Type, Accept',
            1728000);

        $this->service = $service;
        $this->userId = $userId;
        $this->config = $config;
        $this->connection = $connection;
        $this->userManager = $userManager;
	$this->manager = $manager;
    }


    /**
     * @NoAdminRequired
     */
    public function object_to_array($obj) {
       if(is_object($obj)) $obj = (array)$this->dismount($obj);
       if(is_array($obj)) {
          $new = array();
          foreach($obj as $key => $val) {
              $new[$key] = $this->object_to_array($val);
          }
       }
       else $new = $obj;
       return $new;
    }


    /**
     * @NoAdminRequired
     */
    public function dismount($object) {
       $reflectionClass = new ReflectionClass(get_class($object));
       $array = array();
       foreach ($reflectionClass->getProperties() as $property) {
          $property->setAccessible(true);
          $array[$property->getName()] = $property->getValue($object);
          $property->setAccessible(false);
       }
       return $array;
    }


    /**
     * @NoAdminRequired
     */
    public function createMessageId() {

             // Create a random string to use as message id for messages that don't have it
	     $keypassin = substr(sha1((string) mt_rand()), 0, 32);
	     $keysaltin = openssl_random_pseudo_bytes(24);
	     $keyLengthin = 32;
	     $iterationin = 50;
	     $generated_keyin = openssl_pbkdf2($keypassin, $keysaltin, $keyLengthin, $iterationin, 'sha256');
	     $ctdMessageId = "generated-id-" . bin2hex($generated_keyin);
             return $ctdMessageId;
    }


    /**
     * @NoAdminRequired
     */
    public function verifyHeader($receiveddata, $signature_header, $timestamp, $public_key = '', $tolerance = null ) {
        // Typecast timestamp to int for comparisons
        $timestamp = (int)$timestamp;

        // Check if timestamp is within tolerance
        if (($tolerance > 0) && (\abs(\time() - $timestamp) > $tolerance)) {
             return false;
        } else {

            // Convert base64 string to bytes for sodium crypto functions
            $public_key_bytes = base64_decode($public_key);
            $signature_header_bytes = base64_decode($signature_header);

            // Construct a message to test against the signature header using the timestamp and payload
            $constructed_string = $timestamp . '|' . $receiveddata;

            if (!\sodium_crypto_sign_verify_detached($signature_header_bytes, $constructed_string, $public_key_bytes)) {
                return false;
            } else {
                return true;
            }
        }
    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function recdeliveryreptel() {

       $request = file_get_contents("php://input");
       $recdata = json_decode($request, TRUE);

       $delsmswebhookurl = $recdata["data"]["payload"]["webhook_url"];
       $ncuserfortelnyxdel = $this->service->getuserbyteldelrwhurl($delsmswebhookurl);

       if ($ncuserfortelnyxdel) {

	       $messageid = $recdata["data"]["payload"]["id"];

	       $network = $recdata["data"]["payload"]["to"][0]["carrier"];
	       $messageprice = $recdata["data"]["payload"]["cost"]["amount"];
	       $deliverystatus = $recdata["data"]["payload"]["to"][0]["status"];

	       $goterrorinit = $recdata["data"]["payload"]["errors"];

	       if (!empty($goterrorinit)) {
		   $retrievedtitle = $recdata["data"]["payload"]["errors"][0]["title"];
		   $retrievedcode = $recdata["data"]["payload"]["errors"][0]["code"];
		   $messagestatus = "(Error " . $retrievedcode . ") " . $retrievedtitle;
	       } else {
		   $messagestatus = "Success ! The message has been successfully accepted for delivery.";
	       }

	       return $this->service->updatedeliverystatustel($ncuserfortelnyxdel, $messageid, $network, $messageprice, $messagestatus, $deliverystatus); 

       } else { return "access denied"; }

    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function recdeliveryrepnex() {

       $plivodrurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

       $ncuserforplivodel = $this->service->getuserbyplivodelrwhurl($plivodrurl);

       if ($ncuserforplivodel) {

	       $networkcode = "";
	       $mStatus = ""; 

	       if (isset($_REQUEST["MessageUUID"])) { $messageid = $_REQUEST["MessageUUID"]; } else { $messageid = ''; }
	       if (isset($_REQUEST["MCC"]) && isset($_REQUEST["MNC"])) { $networkcode = $_REQUEST["MCC"] . " " . $_REQUEST["MNC"]; } else { $networkcode = ''; }
	       if (isset($_REQUEST["TotalAmount"])) { $messageprice = $_REQUEST["TotalAmount"]; } else { $messageprice = ''; }
	       if (isset($_REQUEST["ErrorCode"]) && $_REQUEST["ErrorCode"] == "") {
                   $mStatus = "Success ! The message has been successfully accepted for delivery.";
               } elseif (isset($_REQUEST["ErrorCode"]) && $_REQUEST["ErrorCode"] != "") {
                   $mStatus = "Error " . $_REQUEST["ErrorCode"]; 
               } else { $mStatus = ''; }

	       if (isset($_REQUEST["Status"])) { $deliverystatus = $_REQUEST["Status"]; }

	       return $this->service->updatedeliverystatusnex($ncuserforplivodel, $messageid, $networkcode, $messageprice, $mStatus, $deliverystatus);

       } else { return "access denied"; }

    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function recdeliveryreptwil() {

       $twildrurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

       $ncuserfortwildel = $this->service->getuserbytwildelrwhurl($twildrurl);

       if ($ncuserfortwildel) {

           $messageid = $_REQUEST["SmsSid"];

           if ($messageid != null) {

               $credentialstw = $this->service->getapicredentials($ncuserfortwildel, 'twilio');
               $sidtw = $credentialstw[15];
               $tokentw = $credentialstw[16];
               $msdetails = json_decode(file_get_contents("https://".$sidtw.":".$tokentw."@api.twilio.com/2010-04-01/Accounts/".$sidtw."/Messages/".$messageid.".json"));
               $errorMessage = $msdetails->error_message;
               $errorCode = $msdetails->error_code;
               $deliverystatus = $msdetails->status;

               if ($errorCode == null) { 
                   $mStatus = 'Success ! The message has been successfully accepted for delivery.'; 
               } else { $mStatus = 'Error ' . $errorCode . '. '. ($errorMessage != '') ? 'Message: '. $errorMessage : ''; }

               $messagepricepre = $msdetails->price;

               if ($messagepricepre) {
                   $messageprice = str_replace("-", "", $messagepricepre);
               } else { $messageprice = ""; }

               $networkcode = '';

	       return $this->service->updatedeliverystatustwil($ncuserfortwildel, $messageid, $networkcode, $messageprice, $mStatus, $deliverystatus);

           } else { exit(); }

       } else { exit(); }

    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function recdeliveryrepflow() {

       $flowdrurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

       $ncuserforflowdel = $this->service->getuserbyflowdelrwhurl($flowdrurl);

       if ($ncuserforflowdel) {

           $receivereq = file_get_contents('php://input');
           $recmdec = json_decode($receivereq, true);
           $recmsid = $recmdec['data']['id'];

           $smsapicredfl = $this->service->getapicredentials($ncuserforflowdel, 'flowroute');
           $flowapikey = $smsapicredfl[20];
           $flowapisecret = $smsapicredfl[21];

           $getmsdetails = json_decode(file_get_contents("https://".$flowapikey.":".$flowapisecret."@api.flowroute.com/v2.1/messages/".$recmsid.""), true);
           $messagepriceflinit = $getmsdetails['data']['attributes']['amount_display'];
           $messagepricefl = str_replace("$", "", $messagepriceflinit);

           $mdeliveryflinit = $getmsdetails['data']['attributes']['delivery_receipts'][0]['status'];

           if ($mdeliveryflinit != 'message buffered') {
               if ($mdeliveryflinit == 'Ok') {
                   $messagedeliveryfl = "Issues";
               } else { $messagedeliveryfl = $mdeliveryflinit; }
           } else { $messagedeliveryfl = 'delivered'; }

           $messagestatuscode = $getmsdetails['data']['attributes']['delivery_receipts'][0]['status_code'];
           $messagestatusdescr = $getmsdetails['data']['attributes']['delivery_receipts'][0]['status_code_description'];

           if ($messagestatuscode != '') { 
               $messagestatusfl = (($messagestatusdescr != '') ? $messagestatusdescr . ". " : "") . "Status code: " . $messagestatuscode; 
           } else { $messagestatusfl = "There were issues with message delivery."; }

           $networkcodefl = '';

           return $this->service->updatedeliverystatusflow($ncuserforflowdel, $recmsid, $networkcodefl, $messagepricefl,  $messagestatusfl, $messagedeliveryfl);

       } else { return "access denied"; }

    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function receivesmstel() {

       $signature = $_SERVER['HTTP_TELNYX_SIGNATURE_ED25519'];
       $timestamp = $_SERVER['HTTP_TELNYX_TIMESTAMP'];

       $receivereq = file_get_contents('php://input');

       $recmesdata = json_decode($receivereq, TRUE);

       $recsmswebhookurl = $recmesdata["data"]["payload"]["webhook_url"];

       $ncuserfortelnyx = $this->service->getuserbytelrecwhurl($recsmswebhookurl);

       $txcredentials = $this->service->getapicredentials($ncuserfortelnyx, 'telnyx');

       $telpubkey = $txcredentials[1];
       $telnyxkey = $txcredentials[0];
       $teldelrecurl = $txcredentials[3];
       $messagingprofid = $txcredentials[4];

       // Verify message signature
       $signatureverify = $this->verifyHeader($receivereq, $signature, $timestamp, $telpubkey, $tolerance = 30);

       if ($signatureverify) {

          if ($ncuserfortelnyx) {

               if ($recmesdata) {
                   if (isset($recmesdata["data"]["payload"]["id"])) {
                       $messageid = $recmesdata["data"]["payload"]["id"];
                   } else { $messageid = $this->createMessageId(); }
               } else { $messageid = $this->createMessageId(); }

	       $messagedate = date("Y-m-d H:i:s");

	       $messagefrom = $recmesdata["data"]["payload"]["from"]["phone_number"];

	       $messageto = "Telnyx: " . $recmesdata["data"]["payload"]["to"][0]["phone_number"];

               $messagetopr = $recmesdata["data"]["payload"]["to"][0]["phone_number"];

               $messagetoprtx = "Tx: " . $messagetopr;

               // Check if the message is a MMS
               if ($recmesdata["data"]["payload"]['type'] == 'MMS') {

                   $includedFilestx = '';

                   foreach ($recmesdata["data"]["payload"]['media'] as $telkey => $telvalue) {
                        if (is_array($telvalue)) {
                            foreach ($telvalue as $telkeysec => $telvaluesec) {
                                if ($telkeysec == "url") {
                                    $includedFilestx .= $telvaluesec . "<br><br>";
                                }
                            }
                        }
                   }

                   $messagetexttel = $recmesdata["data"]["payload"]["text"] . "<br><br><br></b>--- The files included in the MMS follow. Download them only if you trust the sender and the domains of the URLs ---<br><br><br>" . $includedFilestx;
                   $ismmstel = 1;
               } else {
                   $messagetexttel = $recmesdata["data"]["payload"]["text"];
                   $ismmstel = 0;
               }

	       $recmessagearr = [$messageid, $messagedate, $messagefrom, $messageto, $messagetexttel];

	       $this->service->insertrecsms($ncuserfortelnyx, $recmessagearr);


               // Check if there is any auto-reply configured for the receiving number
	       $telgetarpl = $this->connection->prepare('SELECT `phone_number`, `days_of_week`, `daily_start`, `daily_end`, `vacation_start`, `vacation_end`, `message_text` FROM 
                                                        `*PREFIX*sms_relent_autorply` WHERE `phone_number` = ?');
	       $telgetarplres = $telgetarpl->execute([$messagetoprtx]);
	       $telarpldata = $telgetarplres->fetch();
	       $telgetarplres->closeCursor();

               if ($telarpldata) {

                   $autoreplytext = $telarpldata['message_text'];

                   // Get the Display Name of the current user
                   $crtuser = $this->userManager->get($ncuserfortelnyx);
                   $displaynm = $crtuser->getDisplayName();

                   // Check if the auto-reply is in 'daily mode'
                   if ($telarpldata['days_of_week']) {

                       // Check if the auto-reply should be sent 
                       $daysofweekarrinit = explode(",", $telarpldata['days_of_week']);

                       $daysofweekarr = [];
                       $fulldays = [];
                       foreach ($daysofweekarrinit as $crtday) {
                           if (strpos($crtday, "full") !== false) {
                               $fulldays[] = $crtday;
                           } else {
                               $daysofweekarr[] = $crtday;
                           }
                       }

                       $dailystart = $telarpldata['daily_start'];
                       $dailyend = $telarpldata['daily_end'];

                       $crntdate = date("Y-m-d");
                       $crntDayNumber = date('N', strtotime($crntdate));

                       if (in_array($crntDayNumber, $daysofweekarr)) {

                           $crntimehrmin = date("H:i");
                           $crntdatefmt = new DateTime($crntimehrmin);
                           $startdatefmt = new DateTime($dailystart);
                           $enddatefmt = new DateTime($dailyend);

                           if ($crntdatefmt >= $startdatefmt && $enddatefmt > $crntdatefmt) {
                               // OK
                           } else {

	                       // Send the auto-reply
		               \Telnyx\Telnyx::setApiKey($telnyxkey);
		               $messagedate = date("Y-m-d H:i:s");
		               $message = \Telnyx\Message::Create(["from" => $messagetopr, "to" => $messagefrom, "text" => $autoreplytext, "webhook_url" => $teldelrecurl]);

		               // Insert the sent SMS in the 'sms_relent_sent' table
			       if ($message) {
				   if (isset($message['id'])) {
				       $messageid = $message['id'];
				   } else { $messageid = $this->createMessageId(); }
			       } else { $messageid = $this->createMessageId(); }

		               $messagefromtx = "Telnyx: " . $messagetopr;
		               $messagetotx = $messagefrom;
		               $messagenetwork = null;
		               $messageprice = null;
		               $messagestatus = $message['to'][0]['status'];
		               $messagedelivery = null;

		               $sentmessagearr = [$messageid, $messagedate, $messagefromtx, $messagetotx, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $autoreplytext];

		               $this->service->insertsentsms($ncuserfortelnyx, $displaynm, $sentmessagearr);
                           }
                       }

                       if (in_array($crntDayNumber . "(full)", $fulldays)) {

	                       // Send the auto-reply
		               \Telnyx\Telnyx::setApiKey($telnyxkey);
		               $messagedate = date("Y-m-d H:i:s");
		               $message = \Telnyx\Message::Create(["from" => $messagetopr, "to" => $messagefrom, "text" => $autoreplytext, "webhook_url" => $teldelrecurl]);

		               // Insert the sent SMS in the 'sms_relent_sent' table
			       if ($message) {
				   if (isset($message['id'])) {
				       $messageid = $message['id'];
				   } else { $messageid = $this->createMessageId(); }
			       } else { $messageid = $this->createMessageId(); }
		               $messagefromtx = "Telnyx: " . $messagetopr;
		               $messagetotx = $messagefrom;
		               $messagenetwork = null;
		               $messageprice = null;
		               $messagestatus = $message['to'][0]['status'];
		               $messagedelivery = null;

		               $sentmessagearr = [$messageid, $messagedate, $messagefromtx, $messagetotx, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $autoreplytext];

		               $this->service->insertsentsms($ncuserfortelnyx, $displaynm, $sentmessagearr);
                       }

                   } elseif ($telarpldata['vacation_start'] && $telarpldata['vacation_end']) {

                             $vacationstart = $telarpldata['vacation_start'];
                             $vacationend = $telarpldata['vacation_end'];

                             $crntimeymd = date("Y-m-d H:i:s");
                             $crntdatevcfmt = new DateTime($crntimeymd);
                             $startdatevcfmt = new DateTime($vacationstart);
                             $enddatefvcmt = new DateTime($vacationend);

                             if ($startdatevcfmt <= $crntdatevcfmt && $crntdatevcfmt <= $enddatefvcmt) {

			         // Send the auto-reply
			         \Telnyx\Telnyx::setApiKey($telnyxkey);
			         $messagedate = date("Y-m-d H:i:s");
			         $message = \Telnyx\Message::Create(["from" => $messagetopr, "to" => $messagefrom, "text" => $autoreplytext, "webhook_url" => $teldelrecurl]);

			         // Insert the sent SMS in the 'sms_relent_sent' table
			         if ($message) {
				     if (isset($message['id'])) {
				         $messageid = $message['id'];
				     } else { $messageid = $this->createMessageId(); }
			         } else { $messageid = $this->createMessageId(); }
			         $messagefromtx = "Telnyx: " . $messagetopr;
			         $messagetotx = $messagefrom;
			         $messagenetwork = null;
			         $messageprice = null;
			         $messagestatus = $message['to'][0]['status'];
			         $messagedelivery = null;

			         $sentmessagearr = [$messageid, $messagedate, $messagefromtx, $messagetotx, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $autoreplytext];

			         $this->service->insertsentsms($ncuserfortelnyx, $displaynm, $sentmessagearr);
                           }

                   }
               }


	       // Send notifications
               $nameofhost = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];

	       $telsmsapicred = $this->service->getapicredentials($ncuserfortelnyx, 'telnyx');
	       $telnotify = $telsmsapicred[12];
	       $emailaddress = $telsmsapicred[13];
	       $includemessageinemail = $telsmsapicred[14];

               if ($ismmstel == 0) { $smsormmstel = "SMS"; } else { $smsormmstel = "MMS"; }

               // Send the Nextcloud notification(s)
	       if ($telnotify != 0 ) {

                   $allalloweduserstx = $this->service->getallowedusers($ncuserfortelnyx);

                   foreach ($allalloweduserstx as $alusrkeytx => $specusrnametx) {

		            $notificationtx = $this->manager->createNotification();
		            $notificationtx->setApp('sms_relentless')
			          ->setUser($specusrnametx)
			          ->setDateTime(new \DateTime())
			          ->setObject('sms_relentless', '11')
			          ->setSubject('New SMS Message');
		            $this->manager->notify($notificationtx);
                   }
	       }

               // Send the email notification
	       if ($emailaddress != '') {

		   $gmtind = "UTC " . date('P');
		   $smsdateinit = date("Y-m-d  H:i:s");
		   $smsdate = $smsdateinit . " " . $gmtind;

		   $subject = "New ". $smsormmstel ." message received";

                   $messagetextnltel = str_replace("\n", "<br>", $messagetexttel);

		   if ($includemessageinemail == 0) {
		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." .<br> You can check the new message by going to 'SMS Relentless' > 'Received SMS Messages'. <br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '" . $nameofhost . "' <br>";
		   } else {
		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." :<br><br><br> Message ID: ".$messageid." <br> Message Date: ".$messagedate." <br> From: ".$messagefrom." <br> To: ".$messageto."<br> Message Text: <br><br><b>".$messagetextnltel."</b><br><br>____________<br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
		   }

                   $messagefin = chunk_split(base64_encode($message));

		   $headers = "MIME-Version: 1.0" . "\r\n";
		   $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
                   $headers .= "Content-Transfer-Encoding: base64" . "\r\n";

		   // Set the email sender
		   $headers .= "From: " . $emailaddress . "\r\n";
		   $headers .= "Reply-To: " . $emailaddress . "\r\n";

		   mail($emailaddress, $subject, $messagefin, $headers);
	       }

	       return http_response_code(200);

          } else { return "access denied"; }

       } else { return "access denied"; }

    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function receivesmsnex() {

       $plivosignature = $_SERVER['HTTP_X_PLIVO_SIGNATURE_V2'];
       $plivononce = $_SERVER["HTTP_X_PLIVO_SIGNATURE_V2_NONCE"];

       $plivorecurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

       $ncuserforplivo = $this->service->getuserbyplivorecwhurl($plivorecurl);

       $smsapicred = $this->service->getapicredentials($ncuserforplivo, 'plivo');

       $plivoapikey = $smsapicred[5];
       $plivoauthtoken = $smsapicred[6];
       $plivowhdelrcpt = $smsapicred[8];

       $baseplivourlinit = explode("?", $plivorecurl);  
       $baseplivoURI = $baseplivourlinit[0];

       // Verify message signature
       $SigValidation = new signatureValidation();
       $signverify = $SigValidation->validateSignature($baseplivoURI, $plivononce, $plivosignature, $plivoauthtoken);

       if ($signverify) {

              if ($ncuserforplivo) {

	          if ($_REQUEST) {
		      if (isset($_REQUEST["MessageUUID"])) {
		          $messageid = $_REQUEST["MessageUUID"];
		      } else { $messageid = $this->createMessageId(); }
	          } else { $messageid = $this->createMessageId(); }

	          $messagedate = date("Y-m-d H:i:s");

	          $messagefrom = "+" . $_REQUEST['From'];
	          $messageto = "Plivo: +" . $_REQUEST['To'];
	          $messagetoprpl = "Pl: +" . $_REQUEST['To'];
                  $messagetoplsp = "+" . $_REQUEST['To'];

                  // Check if the message is a MMS
                  if ($_REQUEST['Type'] == 'mms') {

                      $includedFilespl = '';
                      foreach ($_REQUEST as $plkey => $plvalue) {

			   if (strpos($plkey, "Media") !== false && $plkey != "MediaCount") {
                               $includedFilespl .= $plvalue . "<br><br>";
			   }
                      }

                      $messagetextpl = $_REQUEST['Body'] . "<br><br><br></b>--- The files included in the MMS follow. Download them only if you trust the sender and the domains of the URLs ---<br><br><br>" . $includedFilespl;
                      $ismmspl = 1;
                  } else {
                      $messagetextpl = $_REQUEST['Text'];
                      $ismmspl = 0;
                  }

	          $recmessagearr = [$messageid, $messagedate, $messagefrom, $messageto, $messagetextpl];

                  $this->service->insertrecsms($ncuserforplivo, $recmessagearr);


                  // Check if there is any auto-reply configured for the receiving number
	          $plgetarpl = $this->connection->prepare('SELECT `phone_number`, `days_of_week`, `daily_start`, `daily_end`, `vacation_start`, `vacation_end`, `message_text` FROM 
                                                          `*PREFIX*sms_relent_autorply` WHERE `phone_number` = ?');
	          $plgetarplres = $plgetarpl->execute([$messagetoprpl]);
	          $plarpldata = $plgetarplres->fetch();
	          $plgetarplres->closeCursor();

                  if ($plarpldata) {

                      $autoreplytext = $plarpldata['message_text'];

                      // Get the Display Name of the current user
                      $crtuser = $this->userManager->get($ncuserforplivo);
                      $displaynm = $crtuser->getDisplayName();

                      // Check if the auto-reply is in 'daily mode'
                      if ($plarpldata['days_of_week']) {

                          // Check if the auto-reply should be sent 
                          $daysofweekarrinit = explode(",", $plarpldata['days_of_week']);

                          $daysofweekarr = [];
                          $fulldays = [];
                          foreach ($daysofweekarrinit as $crtday) {
                              if (strpos($crtday, "full") !== false) {
                                  $fulldays[] = $crtday;
                              } else {
                                  $daysofweekarr[] = $crtday;
                              }
                          }

                          $dailystart = $plarpldata['daily_start'];
                          $dailyend = $plarpldata['daily_end'];

                          $crntdate = date("Y-m-d");
                          $crntDayNumber = date('N', strtotime($crntdate));

                          if (in_array($crntDayNumber, $daysofweekarr)) {

                              $crntimehrmin = date("H:i");
                              $crntdatefmt = new DateTime($crntimehrmin);
                              $startdatefmt = new DateTime($dailystart);
                              $enddatefmt = new DateTime($dailyend);

                              if ($crntdatefmt >= $startdatefmt && $enddatefmt > $crntdatefmt) {
                                  // OK
                              } else {

                                  // Send the auto-reply
		                  $client = new RestClient($plivoapikey, $plivoauthtoken);
                                  $messagedatepl = date("Y-m-d H:i:s");
		                  $response = $client->messages->create($messagetoplsp,[$messagefrom],$autoreplytext,["url" => $plivowhdelrcpt]);
			          $messageidinit = $response->getmessageUuid(0);

				  if ($messageidinit) {
				      if (isset($messageidinit[0])) {
					  $messageid = $messageidinit[0];
				      } else { $messageid = $this->createMessageId(); }
				  } else { $messageid = $this->createMessageId(); }

		                  if (property_exists($response, 'error')) { 
		                      $messagestatus = "Error: " . $response->error;
		                  } else { $messagestatus = 'The message has been accepted for delivery.'; }

                                  $messagefrompl = $messageto;
			          $messagetopl = $messagefrom;
			          $messagenetwork = '';
			          $messageprice = '';

			          $messagedelivery = '';

			          $sentmessagearr = [$messageid, $messagedatepl, $messagefrompl, $messagetopl, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $autoreplytext];

			          $this->service->insertsentsms($ncuserforplivo, $displaynm, $sentmessagearr);
                              }
                          }

                          if (in_array($crntDayNumber, $fulldays)) {

                                  // Send the auto-reply
		                  $client = new RestClient($plivoapikey, $plivoauthtoken);
                                  $messagedatepl = date("Y-m-d H:i:s");
		                  $response = $client->messages->create($messagetoplsp,[$messagefrom],$autoreplytext,["url" => $plivowhdelrcpt]);
			          $messageidinit = $response->getmessageUuid(0);

				  if ($messageidinit) {
				      if (isset($messageidinit[0])) {
					  $messageid = $messageidinit[0];
				      } else { $messageid = $this->createMessageId(); }
				  } else { $messageid = $this->createMessageId(); }

		                  if (property_exists($response, 'error')) { 
		                      $messagestatus = "Error: " . $response->error;
		                  } else { $messagestatus = 'The message has been accepted for delivery.'; }

                                  $messagefrompl = $messageto;
			          $messagetopl = $messagefrom;
			          $messagenetwork = '';
			          $messageprice = '';

			          $messagedelivery = '';

			          $sentmessagearr = [$messageid, $messagedatepl, $messagefrompl, $messagetopl, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $autoreplytext];

			          $this->service->insertsentsms($ncuserforplivo, $displaynm, $sentmessagearr);
                          }

                      } elseif ($plarpldata['vacation_start'] && $plarpldata['vacation_end']) {

                             $vacationstart = $plarpldata['vacation_start'];
                             $vacationend = $plarpldata['vacation_end'];

                             $crntimeymd = date("Y-m-d H:i:s");
                             $crntdatevcfmt = new DateTime($crntimeymd);
                             $startdatevcfmt = new DateTime($vacationstart);
                             $enddatefvcmt = new DateTime($vacationend);

                             if ($startdatevcfmt <= $crntdatevcfmt && $crntdatevcfmt <= $enddatefvcmt) {

		                 $client = new RestClient($plivoapikey, $plivoauthtoken);
                                 $messagedatepl = date("Y-m-d H:i:s");
		                 $response = $client->messages->create($messagetoplsp,[$messagefrom],$autoreplytext,["url" => $plivowhdelrcpt]);

			         $messageidinit = $response->getmessageUuid(0);

				  if ($messageidinit) {
				      if (isset($messageidinit[0])) {
					  $messageid = $messageidinit[0];
				      } else { $messageid = $this->createMessageId(); }
				  } else { $messageid = $this->createMessageId(); }

		                 if (property_exists($response, 'error')) { 
		                     $messagestatus = "Error: " . $response->error;
		                 } else { $messagestatus = 'The message has been accepted for delivery.'; }

                                 $messagefrompl = $messageto;
			         $messagetopl = $messagefrom;
			         $messagenetwork = '';
			         $messageprice = '';

			         $messagedelivery = '';

			         $sentmessagearr = [$messageid, $messagedatepl, $messagefrompl, $messagetopl, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $autoreplytext];

			         $this->service->insertsentsms($ncuserforplivo, $displaynm, $sentmessagearr);
                             }

                      }
                  }


	          // Send notifications
                  $nameofhost = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];

	          $nextnotify = $smsapicred[12];
	          $emailaddress = $smsapicred[13];
	          $includemessageinemail = $smsapicred[14];

                  if ($ismmspl == 0) { $smsormmspl = "SMS"; } else { $smsormmspl = "MMS"; }

                  // Send the Nextcloud notification(s)
	          if ($nextnotify != 0 ) {

                      $allalloweduserspl = $this->service->getallowedusers($ncuserforplivo);

                      foreach ($allalloweduserspl as $alusrkeypl => $specusrnamepl) {

		               $notificationpl = $this->manager->createNotification();
		               $notificationpl->setApp('sms_relentless')
			                      ->setUser($specusrnamepl)
			                      ->setDateTime(new \DateTime())
			                      ->setObject('sms_relentless', '11')
			                      ->setSubject('New SMS Message');
		               $this->manager->notify($notificationpl);
                      }
	          }

                  // Send the email notification
	          if ($emailaddress != '') {

		      $gmtind = "UTC " . date('P');
		      $smsdateinit = date("Y-m-d  H:i:s");
		      $smsdate = $smsdateinit . " " . $gmtind;

		      $subject = "New ". $smsormmspl ." message received";

                      $messagetextnlpl = str_replace("\n", "<br>", $messagetextpl);

		      if ($includemessageinemail == 0) {
		          $message = "Hello, <br><br> You have received a new message on ".$smsdate." .<br> You can check the new message by going to 'SMS Relentless' > 'Received SMS Messages'. <br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
		      } else {
		          $message = "Hello, <br><br> You have received a new message on ".$smsdate." :<br><br><br> Message ID: ".$messageid." <br> Message Date: ".$messagedate." <br> From: ".$messagefrom." <br> To: ".$messageto."<br> Message Text: <br><br><b>".$messagetextnlpl."</b><br><br>____________<br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
		      }

                      $messagefin = chunk_split(base64_encode($message));

		      $headers = "MIME-Version: 1.0" . "\r\n";
		      $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
                      $headers .= "Content-Transfer-Encoding: base64" . "\r\n";

		      // Set the email sender
		      $headers .= "From: " . $emailaddress . "\r\n";
		      $headers .= "Reply-To: " . $emailaddress . "\r\n";

		      mail($emailaddress, $subject, $messagefin, $headers);
	          }

	          return http_response_code(200);

              } else { return "access denied"; }

       } else { return "access denied"; }
    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function receivesmstwil() {

       $twilsig = $_SERVER['HTTP_X_TWILIO_SIGNATURE'];

       $basepath = rtrim($this->config->getSystemValue('overwrite.cli.url'), '/');
       $twilrecprm = $_GET["twilrecparam"] ?? '';
       if (is_array($twilrecprm)) {
           $twilrecprm = end($twilrecprm);
       }
       $twilrecprm = (string) $twilrecprm;

       $twilrecurl = $basepath . "/apps/sms_relentless/api/recsmstwil?twilrecparam=" . $twilrecprm;

       $ncuserfortwil = $this->service->getuserbytwilrecwhurl($twilrecurl);

       $smsapicred = $this->service->getapicredentials($ncuserfortwil, 'twilio');
       $apikeyTw = $smsapicred[15];
       $authTokenTw = $smsapicred[16];
       $apidelrecurltw = $smsapicred[18];

       $postVars = $_POST;
       ksort($postVars);

       $compurlpart = '';

       foreach ($postVars as $twilkey => $twilvalue) {
                $compurlpart .= $twilkey . $twilvalue;
       }

       $compURL1 = $basepath . "/apps/sms_relentless/api/recsmstwil?twilrecparam=" . $twilrecprm . $compurlpart;
       $compURL2 = $basepath . "/apps/sms_relentless/api/recsmstwil?twilrecparam=" . $twilrecprm . "&twilrecparam=" . $twilrecprm . $compurlpart;
       $computedsig1 = base64_encode(hash_hmac('sha1', $compURL1, $authTokenTw, true));
       $computedsig2 = base64_encode(hash_hmac('sha1', $compURL2, $authTokenTw, true));

       // Verify message signature
       if (strcmp($computedsig1, $twilsig) == 0 || strcmp($computedsig2, $twilsig) == 0) {

           if ($ncuserfortwil) {

	       if ($_POST) {
	           if (isset($_POST['MessageSid'])) {
		       $messageid = $_POST['MessageSid'];
	           } else { $messageid = $this->createMessageId(); }
	       } else { $messageid = $this->createMessageId(); }

	       $messagedate = date("Y-m-d H:i:s");

	       $messagefrom = $_POST['From'];

	       $messageto = "Twilio: " . $_POST['To'];

	       $messagetoprtw = $_POST['To'];

	       $messagetotwls = "Tw: " . $_POST['To'];

               // Check if the new message is a MMS
               if ($_POST['NumMedia'] != 0) {

                   $includedFilestw = '';
                   foreach ($_POST as $twkey => $twvalue) {

			if (strpos($twkey, "MediaUrl") !== false) {
                            $includedFilestw .= $twvalue . "<br><br>";
			}
                   }
                   $messagetexttw = $_POST['Body'] . "<br><br><br></b>--- The files included in the MMS follow. Download them only if you trust the sender and the domains of the URLs ---<br><br><br>" . $includedFilestw;
                   $ismmstw = 1;

               } else {
                   $messagetexttw = $_POST['Body'];
                   $ismmstw = 0;
               }

	       $recmessagearr = [$messageid, $messagedate, $messagefrom, $messageto, $messagetexttw];

	       $this->service->insertrecsms($ncuserfortwil, $recmessagearr);


               // Check if there is any auto-reply configured for the receiving number
	       $twilgetarpl = $this->connection->prepare('SELECT `phone_number`, `days_of_week`, `daily_start`, `daily_end`, `vacation_start`, `vacation_end`, `message_text` FROM 
                                                         `*PREFIX*sms_relent_autorply` WHERE `phone_number` = ?');
	       $twilgetarplres = $twilgetarpl->execute([$messagetotwls]);
	       $twilarpldata = $twilgetarplres->fetch();
	       $twilgetarplres->closeCursor();

               if ($twilarpldata) {

                   $autoreplytext = $twilarpldata['message_text'];

                   // Get the Display Name of the current user
                   $crtuser = $this->userManager->get($ncuserfortwil);
                   $displaynm = $crtuser->getDisplayName();

                   // Check if the auto-reply is in 'daily mode'
                   if ($twilarpldata['days_of_week']) {

                       // Check if the auto-reply should be sent 
                       $daysofweekarrinit = explode(",", $twilarpldata['days_of_week']);

                       $daysofweekarr = [];
                       $fulldays = [];
                       foreach ($daysofweekarrinit as $crtday) {
                           if (strpos($crtday, "full") !== false) {
                               $fulldays[] = str_replace("(full)", "", $crtday);
                           } else {
                               $daysofweekarr[] = $crtday;
                           }
                       }

                       $dailystart = $twilarpldata['daily_start'];
                       $dailyend = $twilarpldata['daily_end'];

                       $crntdate = date("Y-m-d");
                       $crntDayNumber = date('N', strtotime($crntdate));

                       if (in_array($crntDayNumber, $daysofweekarr)) {

                           $crntimehrmin = date("H:i");
                           $crntdatefmt = new DateTime($crntimehrmin);
                           $startdatefmt = new DateTime($dailystart);
                           $enddatefmt = new DateTime($dailyend);

                           if ($crntdatefmt >= $startdatefmt && $enddatefmt > $crntdatefmt) {
                               // OK
                           } else {

			       $datatoposttw = [["To" => $messagefrom, "From" => $messagetoprtw, "Body" => $autoreplytext, "StatusCallback" => $apidelrecurltw]];

			       $postedsendingfl = implode('&', array_map('http_build_query', $datatoposttw));
			       $messagedatetw = date("Y-m-d H:i:s");

			       $chtw = curl_init();
			       curl_setopt($chtw, CURLOPT_URL, 'https://api.twilio.com/2010-04-01/Accounts/' . $apikeyTw . '/Messages.json');
			       curl_setopt($chtw, CURLOPT_TIMEOUT, 300);
			       curl_setopt($chtw, CURLOPT_RETURNTRANSFER, 1);
			       curl_setopt($chtw, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
			       curl_setopt($chtw, CURLOPT_USERPWD, "$apikeyTw:$authTokenTw");
			       curl_setopt($chtw, CURLOPT_POST, 1);
			       curl_setopt($chtw, CURLOPT_POSTFIELDS, $postedsendingfl);

			       $resulttw = curl_exec ($chtw);
			       $statusCodetw = curl_getinfo($chtw, CURLINFO_HTTP_CODE);
			       curl_close ($chtw);

			       $decresulttw = json_decode($resulttw);

			       if ($resulttw) {
				   if (property_exists($decresulttw, 'sid')) {
				       $messageidtw = $decresulttw->sid;
				   } else { $messageidtw = $this->createMessageId(); }
			       } else { $messageidtw = $this->createMessageId(); }

			       if (in_array($statusCodetw, [200, 201, 202, 203, 204, 205, 206])) {
				   $messagestatustw = 'The message has been accepted for delivery.';
			       } else {
				   $messagestatustw = 'An error occurred while trying to send the message.';
			       }

			       $messagenetworktw = '';
			       $messagepricetw = '';
			       $messagedeliverytw = '';

			       $sentmessagearr = [$messageidtw, $messagedatetw, $messageto, $messagefrom, $messagenetworktw, $messagepricetw, $messagestatustw, $messagedeliverytw, $autoreplytext];

			       $this->service->insertsentsms($ncuserfortwil, $displaynm, $sentmessagearr);
                           }
                       }

                       if (in_array($crntDayNumber, $fulldays)) {

			       $datatoposttw = [["To" => $messagefrom, "From" => $messagetoprtw, "Body" => $autoreplytext, "StatusCallback" => $apidelrecurltw]];

			       $postedsendingfl = implode('&', array_map('http_build_query', $datatoposttw));
			       $messagedatetw = date("Y-m-d H:i:s");

			       $chtw = curl_init();
			       curl_setopt($chtw, CURLOPT_URL, 'https://api.twilio.com/2010-04-01/Accounts/' . $apikeyTw . '/Messages.json');
			       curl_setopt($chtw, CURLOPT_TIMEOUT, 300);
			       curl_setopt($chtw, CURLOPT_RETURNTRANSFER, 1);
			       curl_setopt($chtw, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
			       curl_setopt($chtw, CURLOPT_USERPWD, "$apikeyTw:$authTokenTw");
			       curl_setopt($chtw, CURLOPT_POST, 1);
			       curl_setopt($chtw, CURLOPT_POSTFIELDS, $postedsendingfl);

			       $resulttw = curl_exec ($chtw);
			       $statusCodetw = curl_getinfo($chtw, CURLINFO_HTTP_CODE);
			       curl_close ($chtw);

			       $decresulttw = json_decode($resulttw);

			       if ($resulttw) {
				   if (property_exists($decresulttw, 'sid')) {
				       $messageidtw = $decresulttw->sid;
				   } else { $messageidtw = $this->createMessageId(); }
			       } else { $messageidtw = $this->createMessageId(); }

			       if (in_array($statusCodetw, [200, 201, 202, 203, 204, 205, 206])) {
				   $messagestatustw = 'The message has been accepted for delivery.';
			       } else {
				   $messagestatustw = 'An error occurred while trying to send the message.';
			       }

			       $messagenetworktw = '';
			       $messagepricetw = '';
			       $messagedeliverytw = '';

			       $sentmessagearr = [$messageidtw, $messagedatetw, $messageto, $messagefrom, $messagenetworktw, $messagepricetw, $messagestatustw, $messagedeliverytw, $autoreplytext];

			       $this->service->insertsentsms($ncuserfortwil, $displaynm, $sentmessagearr);
                       }

                   } elseif ($twilarpldata['vacation_start'] && $twilarpldata['vacation_end']) {

                             $vacationstart = $twilarpldata['vacation_start'];
                             $vacationend = $twilarpldata['vacation_end'];

                             $crntimeymd = date("Y-m-d H:i:s");
                             $crntdatevcfmt = new DateTime($crntimeymd);
                             $startdatevcfmt = new DateTime($vacationstart);
                             $enddatefvcmt = new DateTime($vacationend);

                             if ($startdatevcfmt <= $crntdatevcfmt && $crntdatevcfmt <= $enddatefvcmt) {

			         $datatoposttw = [["To" => $messagefrom, "From" => $messagetoprtw, "Body" => $autoreplytext, "StatusCallback" => $apidelrecurltw]];

			         $postedsendingfl = implode('&', array_map('http_build_query', $datatoposttw));
			         $messagedatetw = date("Y-m-d H:i:s");

			         $chtw = curl_init();
			         curl_setopt($chtw, CURLOPT_URL, 'https://api.twilio.com/2010-04-01/Accounts/' . $apikeyTw . '/Messages.json');
			         curl_setopt($chtw, CURLOPT_TIMEOUT, 300);
			         curl_setopt($chtw, CURLOPT_RETURNTRANSFER, 1);
			         curl_setopt($chtw, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
			         curl_setopt($chtw, CURLOPT_USERPWD, "$apikeyTw:$authTokenTw");
			         curl_setopt($chtw, CURLOPT_POST, 1);
			         curl_setopt($chtw, CURLOPT_POSTFIELDS, $postedsendingfl);

			         $resulttw = curl_exec ($chtw);
			         $statusCodetw = curl_getinfo($chtw, CURLINFO_HTTP_CODE);
			         curl_close ($chtw);

			         $decresulttw = json_decode($resulttw);

			         if ($resulttw) {
				     if (property_exists($decresulttw, 'sid')) {
				         $messageidtw = $decresulttw->sid;
				     } else { $messageidtw = $this->createMessageId(); }
			         } else { $messageidtw = $this->createMessageId(); }

			         if (in_array($statusCodetw, [200, 201, 202, 203, 204, 205, 206])) {
				     $messagestatustw = 'The message has been accepted for delivery.';
			         } else {
				     $messagestatustw = 'An error occurred while trying to send the message.';
			         }

			         $messagenetworktw = '';
			         $messagepricetw = '';
			         $messagedeliverytw = '';

			         $sentmessagearr = [$messageidtw, $messagedatetw, $messageto, $messagefrom, $messagenetworktw, $messagepricetw, $messagestatustw, $messagedeliverytw, $autoreplytext];

			         $this->service->insertsentsms($ncuserfortwil, $displaynm, $sentmessagearr);
                             }

                   }
               }


	       // Send notifications
               $nameofhost = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];

	       $twilnotify = $smsapicred[12];
	       $emailaddress = $smsapicred[13];
	       $includemessageinemail = $smsapicred[14];

               if ($ismmstw == 0) { $smsormmstw = "SMS"; } else { $smsormmstw = "MMS"; }

               // Send the Nextcloud notification(s)
	       if ($twilnotify != 0 ) {

                   $allalloweduserstw = $this->service->getallowedusers($ncuserfortwil);

                   foreach ($allalloweduserstw as $alusrkeytw => $specusrnametw) {

	                    $notificationtw = $this->manager->createNotification();
		            $notificationtw->setApp('sms_relentless')
			                   ->setUser($specusrnametw)
			                   ->setDateTime(new \DateTime())
			                   ->setObject('sms_relentless', '11')
			                   ->setSubject('New SMS Message');
		            $this->manager->notify($notificationtw);
                   }
	       }

               // Send the email notification
	       if ($emailaddress != '') {

		   $gmtind = "UTC " . date('P');
		   $smsdateinit = date("Y-m-d  H:i:s");
		   $smsdate = $smsdateinit . " " . $gmtind;

		   $subject = "New ". $smsormmstw ." message received";

                   $messagetextnltw = str_replace("\n", "<br>", $messagetexttw);

		   if ($includemessageinemail == 0) {
		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." .<br> You can check the new message by going to 'SMS Relentless' > 'Received SMS Messages'. <br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
		   } else {
		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." :<br><br><br> Message ID: ".$messageid." <br> Message Date: ".$messagedate." <br> From: ".$messagefrom." <br> To: ".$messageto."<br> Message Text: <br><br><b>".$messagetextnltw."</b><br><br>____________<br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
		   }

                   $messagefin = chunk_split(base64_encode($message));

		   $headers = "MIME-Version: 1.0" . "\r\n";
		   $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
                   $headers .= "Content-Transfer-Encoding: base64" . "\r\n";

		   // Set the email sender
		   $headers .= "From: " . $emailaddress . "\r\n";
		   $headers .= "Reply-To: " . $emailaddress . "\r\n";

		   mail($emailaddress, $subject, $messagefin, $headers);
	       }

               exit();

           } else { exit(); }

       } else { exit(); }

    }


    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @PublicPage
     */
    public function receivesmsflow() {

       $flowdrurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

       $receivesms = file_get_contents('php://input');
       $recsmsarr = json_decode($receivesms, true);

       $ncuserforflowrec = $this->service->getuserbyflowrecwhurl($flowdrurl);

       if ($ncuserforflowrec) {

           if ($recsmsarr) {
	       if (isset($recsmsarr['data']['id'])) {
	           $messageidfl = $recsmsarr['data']['id'];
	       } else { $messageidfl = $this->createMessageId(); }
           } else { $messageidfl = $this->createMessageId(); }

           $messagedatefl = date("Y-m-d H:i:s");

           $messagefromflpre = $recsmsarr['data']['attributes']['from'];
           if (substr($messagefromflpre, 0, 1) == '+') { $messagefromfl = $messagefromflpre; } else { $messagefromfl = '+' . $messagefromflpre; }

           $messagetofl = "Flowroute: +" . $recsmsarr['data']['attributes']['to'];
           $messagetoprsl = "+" . $recsmsarr['data']['attributes']['to'];
           $messagetoprfl = "Fl: +" . $recsmsarr['data']['attributes']['to'];

           // Check if the message is a MMS
           if ($recsmsarr['data']['attributes']['is_mms'] == true) {

               $includedFilesfl = '';
               for ($k = 0; $k < count($recsmsarr['included']); $k++) {
                    $includedFilesfl .= $recsmsarr['included'][$k]['attributes']['url'] . "<br><br>";
               }
               $messagetextfl = $recsmsarr['data']['attributes']['body'] . "<br><br><br></b>--- The files included in the MMS follow. Download them only if you trust the sender and the domains of the URLs ---<br><br><br>" . $includedFilesfl;
               $ismmsfl = 1;
           } else {
               $messagetextfl = $recsmsarr['data']['attributes']['body'];
               $ismmsfl = 0;
           }

           $recmessagearr = [$messageidfl, $messagedatefl, $messagefromfl, $messagetofl, $messagetextfl];

           $this->service->insertrecsms($ncuserforflowrec, $recmessagearr);

           $flsmsapicred = $this->service->getapicredentials($ncuserforflowrec, 'flowroute');
	   $flownotify = $flsmsapicred[12];
	   $emailaddress = $flsmsapicred[13];
	   $includemessageinemail = $flsmsapicred[14];
           $flowapikey = $flsmsapicred[20];
           $flowapisecret = $flsmsapicred[21];
           $flowdelrecurl = $flsmsapicred[23];


           // Check if there is any auto-reply configured for the receiving number
	   $flgetarpl = $this->connection->prepare('SELECT `phone_number`, `days_of_week`, `daily_start`, `daily_end`, `vacation_start`, `vacation_end`, `message_text` FROM 
                                                   `*PREFIX*sms_relent_autorply` WHERE `phone_number` = ?');
	   $flgetarplres = $flgetarpl->execute([$messagetoprfl]);
	   $flarpldata = $flgetarplres->fetch();
	   $flgetarplres->closeCursor();

           if ($flarpldata) {

               $autoreplytext = $flarpldata['message_text'];

               // Get the Display Name of the current user
               $crtuser = $this->userManager->get($ncuserforflowrec);
               $displaynm = $crtuser->getDisplayName();

               // Check if the auto-reply is in 'daily mode'
               if ($flarpldata['days_of_week']) {

                   // Check if the auto-reply should be sent 
                   $daysofweekarrinit = explode(",", $flarpldata['days_of_week']);

                   $daysofweekarr = [];
                   $fulldays = [];
                   foreach ($daysofweekarrinit as $crtday) {
                       if (strpos($crtday, "full") !== false) {
                           $fulldays[] = str_replace("(full)", "", $crtday);
                       } else {
                           $daysofweekarr[] = $crtday;
                       }
                   }

                   $dailystart = $flarpldata['daily_start'];
                   $dailyend = $flarpldata['daily_end'];

                   $crntdate = date("Y-m-d");
                   $crntDayNumber = date('N', strtotime($crntdate));

                   if (in_array($crntDayNumber, $daysofweekarr)) {

                       $crntimehrmin = date("H:i");
                       $crntdatefmt = new DateTime($crntimehrmin);
                       $startdatefmt = new DateTime($dailystart);
                       $enddatefmt = new DateTime($dailyend);

                       if ($crntdatefmt >= $startdatefmt && $enddatefmt > $crntdatefmt) {
                           // OK
                       } else {

                           // Send the auto-reply
		           $postedparamsfl = json_encode(["to" => $messagefromfl, "from" => $messagetoprsl, "body" => $autoreplytext, "dlr_callback" => $flowdelrecurl]);
		           $messagedatefl = date("Y-m-d H:i:s");

		           $chfl = curl_init();
		           curl_setopt($chfl, CURLOPT_URL, 'https://' . $flowapikey . ':' . $flowapisecret . '@api.flowroute.com/v2.1/messages');
		           curl_setopt($chfl, CURLOPT_HTTPHEADER, array("Content-Type: application/vnd.api+json"));
		           curl_setopt($chfl, CURLOPT_TIMEOUT, 300);
		           curl_setopt($chfl, CURLOPT_RETURNTRANSFER, 1);
		           curl_setopt($chfl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
		           curl_setopt($chfl, CURLOPT_POST, 1);
		           curl_setopt($chfl, CURLOPT_POSTFIELDS, $postedparamsfl);
		           $resultfl = curl_exec ($chfl);
		           $statusCode = curl_getinfo($chfl, CURLINFO_HTTP_CODE);
		           curl_close ($chfl);

		           $decresultfl = json_decode($resultfl);

		           if ($resultfl) {
			       if (isset($decresultfl->data->id)) {
			           $messageidfl = $decresultfl->data->id;
			       } else { $messageidfl = $this->createMessageId(); }
		           } else { $messageidfl = $this->createMessageId(); }

		           if (in_array($statusCode, [200, 201, 202, 203, 204, 205, 206])) {
		               $messagestatusfl = 'The message has been accepted for delivery.'; 
		           } else { 
		               $messagestatusfl = 'An error occurred while trying to send the message.'; 
		           }

		           $messagefromflow = "Flowroute: " . $messagetoprsl;
                           $messagetoflow = $messagefromfl;
		           $messagenetworkfl = '';
		           $messagepricefl = '';
		           $messagedeliveryfl = '';

		           $sentmessagearr = [$messageidfl, $messagedatefl, $messagefromflow, $messagetoflow, $messagenetworkfl, $messagepricefl, $messagestatusfl, $messagedeliveryfl, $autoreplytext];

		           $this->service->insertsentsms($ncuserforflowrec, $displaynm, $sentmessagearr);
                       }
                   }

                   if (in_array($crntDayNumber, $fulldays)) {

                           // Send the auto-reply
		           $postedparamsfl = json_encode(["to" => $messagefromfl, "from" => $messagetoprsl, "body" => $autoreplytext, "dlr_callback" => $flowdelrecurl]);
		           $messagedatefl = date("Y-m-d H:i:s");

		           $chfl = curl_init();
		           curl_setopt($chfl, CURLOPT_URL, 'https://' . $flowapikey . ':' . $flowapisecret . '@api.flowroute.com/v2.1/messages');
		           curl_setopt($chfl, CURLOPT_HTTPHEADER, array("Content-Type: application/vnd.api+json"));
		           curl_setopt($chfl, CURLOPT_TIMEOUT, 300);
		           curl_setopt($chfl, CURLOPT_RETURNTRANSFER, 1);
		           curl_setopt($chfl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
		           curl_setopt($chfl, CURLOPT_POST, 1);
		           curl_setopt($chfl, CURLOPT_POSTFIELDS, $postedparamsfl);
		           $resultfl = curl_exec ($chfl);
		           $statusCode = curl_getinfo($chfl, CURLINFO_HTTP_CODE);
		           curl_close ($chfl);

		           $decresultfl = json_decode($resultfl);

		           if ($resultfl) {
			       if (isset($decresultfl->data->id)) {
			           $messageidfl = $decresultfl->data->id;
			       } else { $messageidfl = $this->createMessageId(); }
		           } else { $messageidfl = $this->createMessageId(); }

		           if (in_array($statusCode, [200, 201, 202, 203, 204, 205, 206])) {
		               $messagestatusfl = 'The message has been accepted for delivery.'; 
		           } else { 
		               $messagestatusfl = 'An error occurred while trying to send the message.'; 
		           }

		           $messagefromflow = "Flowroute: " . $messagetoprsl;
                           $messagetoflow = $messagefromfl;
		           $messagenetworkfl = '';
		           $messagepricefl = '';
		           $messagedeliveryfl = '';

		           $sentmessagearr = [$messageidfl, $messagedatefl, $messagefromflow, $messagetoflow, $messagenetworkfl, $messagepricefl, $messagestatusfl, $messagedeliveryfl, $autoreplytext];

		           $this->service->insertsentsms($ncuserforflowrec, $displaynm, $sentmessagearr);
                   }

               } elseif ($flarpldata['vacation_start'] && $flarpldata['vacation_end']) {

                         $vacationstart = $flarpldata['vacation_start'];
                         $vacationend = $flarpldata['vacation_end'];

                         $crntimeymd = date("Y-m-d H:i:s");
                         $crntdatevcfmt = new DateTime($crntimeymd);
                         $startdatevcfmt = new DateTime($vacationstart);
                         $enddatefvcmt = new DateTime($vacationend);

                         if ($startdatevcfmt <= $crntdatevcfmt && $crntdatevcfmt <= $enddatefvcmt) {

		             $postedparamsfl = json_encode(["to" => $messagefromfl, "from" => $messagetoprsl, "body" => $autoreplytext, "dlr_callback" => $flowdelrecurl]);
		             $messagedatefl = date("Y-m-d H:i:s");

		             $chfl = curl_init();
		             curl_setopt($chfl, CURLOPT_URL, 'https://' . $flowapikey . ':' . $flowapisecret . '@api.flowroute.com/v2.1/messages');
		             curl_setopt($chfl, CURLOPT_HTTPHEADER, array("Content-Type: application/vnd.api+json"));
		             curl_setopt($chfl, CURLOPT_TIMEOUT, 300);
		             curl_setopt($chfl, CURLOPT_RETURNTRANSFER, 1);
		             curl_setopt($chfl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
		             curl_setopt($chfl, CURLOPT_POST, 1);
		             curl_setopt($chfl, CURLOPT_POSTFIELDS, $postedparamsfl);
		             $resultfl = curl_exec ($chfl);
		             $statusCode = curl_getinfo($chfl, CURLINFO_HTTP_CODE);
		             curl_close ($chfl);

		             $decresultfl = json_decode($resultfl);

		             if ($resultfl) {
			         if (isset($decresultfl->data->id)) {
			             $messageidfl = $decresultfl->data->id;
			         } else { $messageidfl = $this->createMessageId(); }
		             } else { $messageidfl = $this->createMessageId(); }

		             if (in_array($statusCode, [200, 201, 202, 203, 204, 205, 206])) {
		                 $messagestatusfl = 'The message has been accepted for delivery.'; 
		             } else { 
		                 $messagestatusfl = 'An error occurred while trying to send the message.'; 
		             }

		             $messagefromflow = "Flowroute: " . $messagetoprsl;
                             $messagetoflow = $messagefromfl;
		             $messagenetworkfl = '';
		             $messagepricefl = '';
		             $messagedeliveryfl = '';

		             $sentmessagearr = [$messageidfl, $messagedatefl, $messagefromflow, $messagetoflow, $messagenetworkfl, $messagepricefl, $messagestatusfl, $messagedeliveryfl, $autoreplytext];

		             $this->service->insertsentsms($ncuserforflowrec, $displaynm, $sentmessagearr);
                         }

               }
           }


	   // Send notifications
           $nameofhost = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];

           if ($ismmsfl == 0) { $smsormmsfl = "SMS"; } else { $smsormmsfl = "MMS"; }

           // Send the Nextcloud notification(s)
	   if ($flownotify != 0 ) {

               $allallowedusersfl = $this->service->getallowedusers($ncuserforflowrec);

               foreach ($allallowedusersfl as $alusrkeyfl => $specusrnamefl) {

	                $notificationfl = $this->manager->createNotification();
	                $notificationfl->setApp('sms_relentless')
		                       ->setUser($specusrnamefl)
			               ->setDateTime(new \DateTime())
			               ->setObject('sms_relentless', '11')
			               ->setSubject('New SMS Message');
	                $this->manager->notify($notificationfl);
               }
	   }

           // Send the email notification
	   if ($emailaddress != '') {

	       $gmtind = "UTC " . date('P');
	       $smsdateinit = date("Y-m-d  H:i:s");
	       $smsdate = $smsdateinit . " " . $gmtind;

	       $subject = "New ". $smsormmsfl ." message received";

               $messagetextnlfl = str_replace("\n", "<br>", $messagetextfl);

	       if ($includemessageinemail == 0) {
	           $message = "Hello, <br><br> You have received a new message on ".$smsdate." .<br> You can check the new message by going to 'SMS Relentless' > 'Received SMS Messages'. <br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
	       } else {
	           $message = "Hello, <br><br> You have received a new message on ".$smsdate." :<br><br><br> Message ID: ".$messageidfl." <br> Message Date: ".$messagedatefl." <br> From: ".$messagefromfl." <br> To: ".$messagetofl."<br> Message Text: <br><br><b>".$messagetextnlfl."</b><br><br>____________<br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
	       }

               $messagefin = chunk_split(base64_encode($message));

	       $headers = "MIME-Version: 1.0" . "\r\n";
	       $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
               $headers .= "Content-Transfer-Encoding: base64" . "\r\n";

	       // Set the email sender
	       $headers .= "From: " . $emailaddress . "\r\n";
	       $headers .= "Reply-To: " . $emailaddress . "\r\n";

	       mail($emailaddress, $subject, $messagefin, $headers);
	   }

           return http_response_code(200);

       } else { return "access denied"; }

    }
}
