diff --git a/README.md b/README.md index a1a0f78..1e5c7a6 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,17 @@ To search for ConnectWise configuration records, use cwslack-configs.php. To follow tickets and get updates whenever they're updated, use cwslack-follow.php (requires cwslack-incoming.php). +To modify the MySQL database in Slack, please configure and setup cwslack-dbmanage.php + # Installation Instructions -## cwslack.php, activities, contacts, notes, and configs +This script set and all modules require PHP version 5 and the cURL extension, and many require a MySQL or MariaDB server. + +For non-MySQL installation instructions, please see README_NoMySQL.md + +## cwslack.php, activities, contacts, notes, configs, and dbmanage -1. Download the respective php file, functions.php, and config.php files. +1. Download the respective php file, functions.php, install.php, and config.php files. 2. Place on a compatible web server 3. Create a new slack slash command integration at https://SLACK TEAM.slack.com/apps/A0F82E8CA-slash-commands 4. Set command to reflect the task necessary. E.x. /t for tickets, /act for activities, /note for notes. @@ -30,12 +36,13 @@ To follow tickets and get updates whenever they're updated, use cwslack-follow.p 6. Set Method to GET 7. Copy the token 8. Set a name, icon, and auto complete text if wanted. -9. Modify the config.php file with your companies values and timezone. Full configuration info below. -10. Test it in Slack! +9. Run install.php and proceed through database setup. This will also verify you have the required PHP and cURL versions. +10. Modify the config.php file with your companies values and timezone. Full configuration info below. +11. Test it in Slack! ## cwslack-incoming.php -1. Download the cwslack-incoming.php, functions.php, and config.php files. +1. Download the cwslack-incoming.php, functions.php, install.php, and config.php files. 2. Place on a compatible web server 3. Create a new slack incoming web hook integration at https://my.slack.com/services/new/incoming-webhook/ 4. Set a name, icon, and if wanted. @@ -55,18 +62,19 @@ To follow tickets and get updates whenever they're updated, use cwslack-follow.p **(Requires some variables from cwslack-incoming.php to function if you don't use that)** -1. Download the cwslack-firmalerts.php, functions.php, and config.php files. +1. Download the cwslack-firmalerts.php, functions.php, install.php, and config.php files. 2. Place on a compatible web server. -3. Change $posttousers or $posttochan to 0 in config.php if you don't want it posting to one or the other. -4. Setup a cron job or scheduled task on your server to run this PHP file **every minute.** +3. Run install.php and proceed through database setup. This will also verify you have the required PHP and cURL versions. +4. Change $posttousers or $posttochan to 0 in config.php if you don't want it posting to one or the other. +5. Setup a cron job or scheduled task on your server to run this PHP file **every minute.** ```Cron: * * * * * /usr/bin/php /var/www/cwslack-firmalerts.php >/dev/null 2>&1``` -5. Set a firm appointment and test +6. Set a firm appointment and test ## cwslack-follow.php **(Also requires cwslack-incoming.php to function)** -1. Download the cwslack-follow.php, functions.php, and config.php files. +1. Download the cwslack-follow.php, functions.php, install.php, and config.php files. 2. Place on a compatible web server 3. Create a new slack slash command integration at https://SLACK TEAM.slack.com/apps/A0F82E8CA-slash-commands 4. Set command to /follow (or other if you prefer) @@ -74,8 +82,9 @@ To follow tickets and get updates whenever they're updated, use cwslack-follow.p 6. Set Method to GET 7. Copy the token 8. Set a name, icon, and auto complete text if wanted. -9. Modify the config.php file with your companies values, Full configuration info below. -10. Test it in Slack! +9. Run install.php and proceed through database setup. This will also verify you have the required PHP and cURL versions. +10. Modify the config.php file with your companies values and timezone. Full configuration info below. +11. Test it in Slack! To enable ConnectWise link to follow and unfollow a ticket: @@ -110,7 +119,9 @@ To enable ConnectWise link to follow and unfollow a ticket: \& Ampersand denotes required for cwslack-contacts.php \^ Caret denotes required for cwslack-notes.php \% Percent denotes required for cwslack-notes.php -\= Equals denotes required for cwslack-firmalerts.php +\= Equals denotes required for cwslack-firmalerts.php +\@ At denotes required for cwslack-dbmanage.php + ####All * $connectwise * : This value needs to be set to your main ConnectWise URL. @@ -120,6 +131,11 @@ To enable ConnectWise link to follow and unfollow a ticket: * $apiprivatekey * : Set to your Private Key from API setup * $slacktoken * : Set to the token you got when creating a new slash command integration in Slack. * $timezone * : Set to your timezone according to http://php.net/manual/en/timezones.america.php . +* $usedatabase #,^,=,@ : Automatically configured by install.php +* $dbhost #,^,=,@ : Automatically configured by install.php +* $dbusername #,^,=,@ : Automatically configured by install.php +* $dbpassword #,^,=,@ : Automatically configured by install.php +* $dbdatabase #,^,=,@ : Automatically configured by install.php ####Activities * $slackactivitiestoken + : Set to the token you got when creating a new slash command integration in Slack for /activities. @@ -158,6 +174,11 @@ To enable ConnectWise link to follow and unfollow a ticket: ####Configs * $slackconfigstoken % : Set to the token you got when creating a new slash command integration in Slack for /config. +####DBManage + +* $slackdbmantoken @ : Set your token for the database management slash command +* $adminlist @ : Usernames that are allowed to use this command. Separate by pipe symbol as seen in example if you need multiple people to have access. + ####General * $helpurl : Set to a help document explaining the slash command usage. Feel free to point to this GitHub repo, but ideally you would make it look pretty on your own internal site. @@ -212,6 +233,17 @@ This does allow spaces for the ticket note so do not wrap in quotation marks or ## cwslack-configs.php -/config [company name]*|[config name]* +/config [company name]\*|[config name]* Requires pipe symbol between the two, will return details on config that matches search. + +## cwslack-dbmanage.php + +/dbm [command]* [options] + +Commands available: +* help - Display this help text +* listmap - List all username mappings between CW and Slack +* addmap [slackname]* [cwname]* - Associate the two names +* removemap [slackname]* - Remove a mapping +* clearfollow confirm* - Clears the follow database diff --git a/README_NoMySQL.md b/README_NoMySQL.md new file mode 100644 index 0000000..572f8ba --- /dev/null +++ b/README_NoMySQL.md @@ -0,0 +1,89 @@ +# CWSlack-SlashCommands + +See README.md for full configuration details and other information. + +This file should only be used if you cannot use a MySQL or Maria DB server for this script. Note that future updates past 2.0 may not fully update old modules and may require MySQL for new modules. + + +# Installation Instructions + +## cwslack.php, activities, contacts, notes, and configs + +1. Download the respective php file, functions.php, and config.php files. +2. Place on a compatible web server +3. Create a new slack slash command integration at https://SLACK TEAM.slack.com/apps/A0F82E8CA-slash-commands +4. Set command to reflect the task necessary. E.x. /t for tickets, /act for activities, /note for notes. +5. Set the URL to https://domain.tld/cwslack.php (or other php file) +6. Set Method to GET +7. Copy the token +8. Set a name, icon, and auto complete text if wanted. +9. Modify the config.php file with your companies values and timezone. Full configuration info below. +10. Test it in Slack! + +## cwslack-incoming.php + +1. Download the cwslack-incoming.php, functions.php, and config.php files. +2. Place on a compatible web server +3. Create a new slack incoming web hook integration at https://my.slack.com/services/new/incoming-webhook/ +4. Set a name, icon, and if wanted. +5. Set channel that you want to post to and copy the Web hook URL +6. Create a new integrator login in ConnectWise: + - Go to System > Setup Tables in the client + - Type "int" in the table field and select Integrator Login + - Create a new login with whatever username/password, we don't need this. + - Set Access Level to "All Records" + - Enable "Service Ticket API" and select the board(s) you want this to run on. + - Enter https://domain.tld/cwslack-incoming.php?id= for the callback URL (do not enable legacy format) +7. Modify the config.php file with your companies values and timezone, make sure to set the value for $webhookurl to the value copied in step 5. +8. Change the $postupdated and $postadded to what you prefer. Enabling $postupdated can get spammy. +9. Test it in Slack by creating a new ticket on the board you selected in step 6! + +## cwslack-firmalerts.php + +**(Requires some variables from cwslack-incoming.php to function if you don't use that)** + +1. Download the cwslack-firmalerts.php, functions.php, and config.php files. +2. Place on a compatible web server. +3. Change $posttousers or $posttochan to 0 in config.php if you don't want it posting to one or the other. +4. Setup a cron job or scheduled task on your server to run this PHP file **every minute.** + ```Cron: * * * * * /usr/bin/php /var/www/cwslack-firmalerts.php >/dev/null 2>&1``` +5. Set a firm appointment and test + +## cwslack-follow.php + +**(Also requires cwslack-incoming.php to function)** + +1. Download the cwslack-follow.php, functions.php, and config.php files. +2. Place on a compatible web server +3. Create a new slack slash command integration at https://SLACK TEAM.slack.com/apps/A0F82E8CA-slash-commands +4. Set command to /follow (or other if you prefer) +5. Set the URL to https://domain.tld/cwslack-follow.php +6. Set Method to GET +7. Copy the token +8. Set a name, icon, and auto complete text if wanted. +9. Modify the config.php file with your companies values, Full configuration info below. +10. Test it in Slack! + +To enable ConnectWise link to follow and unfollow a ticket: + +1. Open Setup Tables in ConnectWise. +2. Open the "Links" table. +3. Create a new Link referencing "Service" +4. Set the Link Name to "Slack Follow" +5. Set the Link Definition to https://yourdomain.tld/cwslack-follow.php?memberid=[memberid]&srnumber=[srnumber]&method=follow +6. Create a new Link referencing "Service" +7. Set the Link Name to "Slack Unfollow" +8. Set the Link Definition to https://yourdomain.tld/cwslack-follow.php?memberid=[memberid]&srnumber=[srnumber]&method=unfollow +9. Change the "method" on these links to whatever you set your $followtoken and $unfollowtoken to in config.php. +10. Test the links! + + +# API Key Setup + +1. Login to ConnectWise +2. In the top right, click on your name +3. Go to "My Account" +4. Select the "API Keys" tab +5. Click the Plus icon to create a new key +6. Provide a description and click the Save icon. +7. Save this information, you cannot retrieve the private key ever again so if lost you will need to create new ones. \ No newline at end of file diff --git a/config.php b/config.php index 3e5a708..9a645e8 100644 --- a/config.php +++ b/config.php @@ -26,7 +26,14 @@ $companyname = "MyCompany"; //Set your company name from Connectwise. This is the company name field from login. $apipublickey = "Key"; //Public API key $apiprivatekey = "Key"; //Private API key -$timezone = "America/Chicago"; //Set your timezone here. +$timezone = "America/Chicago"; //Set your timezone here. + +// Database Configuration, required for if you want to use MySQL/Maria DB features. +$usedatabase = 0; // Set to 0 by default, set to 1 if you want to enable MySQL. +$dbhost = "127.0.0.1"; //Your MySQL DB +$dbusername = "username"; //Your MySQL DB Username +$dbpassword = "password"; //Your MySQL DB Password +$dbdatabase = "cwslack"; //Change if you have an existing database you want to use, otherwise leave as default. //cwslack.php $slacktoken = "Slack Token Here"; //Set token from the Slack slash command screen. @@ -39,7 +46,7 @@ //cwlsack-notes.php $slacknotestoken = "Slack Token Here"; //Set your token for the notes slash command -$usecwname = 0; //If set to 1, it will create tickets using the user's slack name. Command will fail if their slack name is not the same as connectwise name. +$usecwname = 1; //If set to 1, it will create tickets using the user's slack name. Command will fail if their slack name is not the same as connectwise name. //cwslack-configs.php $slackconfigstoken = "Slack Token Here"; //Set your token for the configs slash command @@ -67,12 +74,16 @@ $firmalertchan = "#dispatch"; //When you want to split time alerts and firm alerts into their own channels. //cwslack-follow.php +//Requires cwslack-incoming.php to function. $slackfollowtoken = "Slack Token Here"; //Set your token for the follow slash command -$followenabled=0; //When set to 1, follow commands and the follow scripts will be enabled. -$dir="/var/www/storage/"; //Needs to be set to a directory writeable by PHP for storage of the storage.txt file. -$followtoken="follow"; //Change to random text to be used in your CW follow link if you use it. Defaults to follow which is fine for testing. -$unfollowtoken="unfollow"; //Change to random text to be used in your CW unfollow link if you use it. Defaults to unfollow which is fine for testing. +$followenabled = 0; //When set to 1, follow commands and the follow scripts will be enabled. +$dir = "/var/www/storage/"; //Needs to be set to a directory writeable by PHP for storage of the storage.txt file. Not needed if using MySQL. +$followtoken = "follow"; //Change to random text to be used in your CW follow link if you use it. Defaults to follow which is fine for testing. +$unfollowtoken = "unfollow"; //Change to random text to be used in your CW unfollow link if you use it. Defaults to unfollow which is fine for testing. +//cwslack-dbmanage.php +$slackdbmantoken = "Slack Token Here"; //Set your token for the database management slash command +$adminlist = "admin1|admin2"; //Separate by pipe symbol as seen in example if you need multiple people to have access. //Change optional $helpurl = "https://github.com/jundis/CWSlack-SlashCommands"; //Set your help article URL here. @@ -83,9 +94,13 @@ //Timezone Setting to be used for all files. date_default_timezone_set($timezone); -if ( !file_exists($dir) ) { - $oldmask = umask(0); // helpful when used in linux server - mkdir ($dir, 0744); - } + +if ($usedatabase!=1) //Setup directory for Follow module. +{ + if ( !file_exists($dir) ) { + $oldmask = umask(0); // helpful when used in linux server + mkdir ($dir, 0744); + } +} ?> diff --git a/cwslack-activities.php b/cwslack-activities.php index 66f0c04..c052f51 100644 --- a/cwslack-activities.php +++ b/cwslack-activities.php @@ -23,8 +23,8 @@ require_once 'config.php'; require_once 'functions.php'; -$apicompanyname = strtolower($companyname); //Company name all lower case for api auth. -$authorization = base64_encode($apicompanyname . "+" . $apipublickey . ":" . $apiprivatekey); //Encode the API, needed for authorization. +// Authorization array. Auto encodes API key for auhtorization above. +$header_data = postHeader($companyname, $apipublickey, $apiprivatekey); if(empty($_GET['token']) || ($_GET['token'] != $slackactivitiestoken)) die("Slack token invalid."); //If Slack token is not correct, kill the connection. This allows only Slack to access the page for security purposes. if(empty($_GET['text'])) die("No text provided."); //If there is no text added, kill the connection. @@ -32,26 +32,13 @@ //Check to see if the first command in the text array is actually help, if so redirect to help webpage detailing slash command use. if ($exploded[0]=="help") { - $test=json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true)); //Encode a JSON response with a help URL. - echo $test; //Return the JSON - return; //Kill the connection. + die(json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true))); //Encode a JSON response with a help URL. } $urlactivities = $connectwise . "/v4_6_release/apis/3.0/sales/activities/"; -$activityurl = $connectwise . '/v4_6_release/ConnectWise.aspx?fullscreen=false&locale=en_US#startscreen=activity_detail&state={"p":"activity_detail", "s":{"p":{"pid":3, "rd": '; +$activityurl = $connectwise . '/v4_6_release/ConnectWise.aspx?fullscreen=false&locale=en_US#startscreen=activity_detail&state={"p":"activity_detail", "s":{"p":{"pid":3, "rd":'; $activityurl2 = ' ,"compId":0, "contId":0, "oppid":0}}}'; -$utc = time(); //Get the time. -// Authorization array. Auto encodes API key for auhtorization above. -$header_data =array( - "Authorization: Basic ". $authorization, -); -// Authorization array, with extra json content-type used in patch commands to change tickets. -$header_data2 =array( -"Authorization: Basic " . $authorization, - "Content-Type: application/json" -); - $command=NULL; //Create a command variable and set it to Null if (array_key_exists(0,$exploded)) //If a string exists in the slash command array, make it the command. { @@ -64,26 +51,11 @@ if($command=="new") { $dataResponse = cURLPost( $urlactivities, - $header_data2, + $header_data, "POST", array("name"=>$exploded[1],"status"=>array("id"=>1),"assignTo"=>array("identifier"=>$exploded[2]))); } -if(array_key_exists("code",$dataResponse)) { //Check if array contains error code - if($dataResponse->code == "NotFound") { //If error code is NotFound - echo "This should never occur..."; //Report that the ticket was not found. - return; - } - if($dataResponse->code == "Unauthorized") { //If error code is an authorization error - echo "401 Unauthorized, check API key to ensure it is valid."; //Fail case. - return; - } - else { - echo "Unknown Error Occurred, check API key and other API settings. Error: " . $dataResponse->code; //Fail case. - return; - } -} - $return="Unknown command."; if($command == "new") //If command is new. { diff --git a/cwslack-configs.php b/cwslack-configs.php index 2a60040..6414e19 100644 --- a/cwslack-configs.php +++ b/cwslack-configs.php @@ -25,15 +25,11 @@ if(empty($_GET['token']) || ($_GET['token'] != $slackconfigstoken)) die("Slack token invalid."); //If Slack token is not correct, kill the connection. This allows only Slack to access the page for security purposes. if(empty($_GET['text'])) die("No text provided."); //If there is no text added, kill the connection. -$apicompanyname = strtolower($companyname); //Company name all lower case for api auth. -$authorization = base64_encode($apicompanyname . "+" . $apipublickey . ":" . $apiprivatekey); //Encode the API, needed for authorization. $exploded = explode("|",$_GET['text']); //Explode the string attached to the slash command for use in variables. //Check to see if the first command in the text array is actually help, if so redirect to help webpage detailing slash command use. if ($exploded[0]=="help") { - $test=json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true)); //Encode a JSON response with a help URL. - echo $test; //Return the JSON - return; //Kill the connection. + die(json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true))); //Encode a JSON response with a help URL. } $company=NULL; //Just in case @@ -56,11 +52,8 @@ $url = str_replace(' ', '%20', $url); //Encode URL to prevent errors with spaces. -$utc = time(); //Get the time. -// Authorization array. Auto encodes API key for auhtorization above. -$header_data =array( - "Authorization: Basic ". $authorization, -); +// Authorization array. Auto encodes API key for auhtorization. +$header_data = authHeader($companyname, $apipublickey, $apiprivatekey); //Need to create array before hand to ensure no errors occur. $dataTData = array(); @@ -71,12 +64,6 @@ $dataTData = cURL($url, $header_data); // Get the JSON returned by the CW API. //Error handling -if(array_key_exists("errors",$dataTData)) //If connectwise returned an error. -{ - $errors = $dataTData->errors; //Make array easier to access. - - die("ConnectWise Error: " . $errors[0]->message); //Return CW error -} if($dataTData==NULL) //If no contact is returned or your API URL is incorrect. { die("No configuration found."); //Return error. diff --git a/cwslack-contacts.php b/cwslack-contacts.php index 8fbed92..818a1ef 100644 --- a/cwslack-contacts.php +++ b/cwslack-contacts.php @@ -26,15 +26,11 @@ if(empty($_GET['token']) || ($_GET['token'] != $slackcontactstoken)) die("Slack token invalid."); //If Slack token is not correct, kill the connection. This allows only Slack to access the page for security purposes. if(empty($_GET['text'])) die("No text provided."); //If there is no text added, kill the connection. -$apicompanyname = strtolower($companyname); //Company name all lower case for api auth. -$authorization = base64_encode($apicompanyname . "+" . $apipublickey . ":" . $apiprivatekey); //Encode the API, needed for authorization. $exploded = explode(" ",$_GET['text']); //Explode the string attached to the slash command for use in variables. //Check to see if the first command in the text array is actually help, if so redirect to help webpage detailing slash command use. if ($exploded[0]=="help") { - $test=json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true)); //Encode a JSON response with a help URL. - echo $test; //Return the JSON - return; //Kill the connection. + die(json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true))); //Encode a JSON response with a help URL. } $firstname=NULL; //Create a first name variable and set it to Null @@ -56,9 +52,8 @@ $utc = time(); //Get the time. // Authorization array. Auto encodes API key for auhtorization above. -$header_data =array( - "Authorization: Basic ". $authorization, -); +$header_data = authHeader($companyname, $apipublickey, $apiprivatekey); + //Need to create array before hand to ensure no errors occur. $dataTData = array(); diff --git a/cwslack-dbmanage.php b/cwslack-dbmanage.php new file mode 100644 index 0000000..b951758 --- /dev/null +++ b/cwslack-dbmanage.php @@ -0,0 +1,118 @@ +. +*/ + +ini_set('display_errors', 1); //Display errors in case something occurs +header('Content-Type: application/json'); //Set the header to return JSON, required by Slack +require_once 'config.php'; +require_once 'functions.php'; + +if(empty($_GET['token']) || ($_GET['token'] != $slackdbmantoken)) die("Slack token invalid."); //If Slack token is not correct, kill the connection. This allows only Slack to access the page for security purposes. +if(empty($_GET['text'])) die("No text provided."); //If there is no text added, kill the connection. +$exploded = explode(" ",$_GET['text']); //Explode the string attached to the slash command for use in variables. + +$explodeadmins = explode("|", $adminlist); //Explode list of acceptable admins. +if(!in_array($_GET["user_name"],$explodeadmins)) +{ + die("You are not authorized to access this command. Only the following users can: " . implode(", ",$explodeadmins)); +} + +//Check to see if the first command in the text array is actually help, if so redirect to help webpage detailing slash command use. +if ($exploded[0]=="help") { + die("The following commands are available:\nlistmap - List all username mappings between CW and Slack\naddmap (slackname) (cwname) - Associate the two names\nremovemap (slackname) - Remove a mapping\nclearfollow confirm - Clears the follow database"); +} + +$mysql = mysqli_connect($dbhost, $dbusername, $dbpassword, $dbdatabase); //Connect MySQL + +if (!$mysql) //Check for errors +{ + die("Connection Error: " . mysqli_connect_error()); +} + +if ($exploded[0]=="listmap") +{ + $sql = "SELECT * FROM `usermap`"; //SQL Query to select all users + + $result = mysqli_query($mysql, $sql); //Run result + $output = "List of username mappings:\n"; + if(mysqli_num_rows($result) > 0) //If there were too many rows matching query + { + while($row = mysqli_fetch_assoc($result)) + { + $output = $output . "Slack: " . $row["slackuser"] . " | ConnectWise: " . $row["cwname"] . "\n"; + } + die($output); + } + else + { + die("No user mappings found in database."); + } +} +else if ($exploded[0]=="addmap") +{ + if (!array_key_exists(2,$exploded)) + { + die("Error: Please ensure you're entering the following: addmap (slack name) (connectwise username)"); + } + $sql = "INSERT INTO `usermap` (`slackuser`, `cwname`) VALUES ('" . $exploded[1] . "', '" . $exploded[2] . "');"; //SQL Query to insert new map + + if(mysqli_query($mysql,$sql)) + { + die("Successfully added mapping for Slack User " . $exploded[1] . " to ConnectWise User " . $exploded[2]); + } + else + { + die("MySQL Error: " . mysqli_error($mysql)); + } +} +else if ($exploded[0]=="removemap") +{ + if (!array_key_exists(1,$exploded)) + { + die("Error: Please ensure you're entering the following: removemap (slack name)"); + } + $sql = "DELETE FROM .`usermap` WHERE `usermap`.`slackuser` = '" . $exploded[1] . "';"; //SQL Query to remove map + + if(mysqli_query($mysql,$sql)) + { + die("Successfully removed mapping for Slack User " . $exploded[1]); + } + else + { + die("MySQL Error: " . mysqli_error($mysql)); + } +} +else if ($exploded[0]=="clearfollow") +{ + if (!array_key_exists(1,$exploded) || $exploded[1]!="confirm") + { + die("Error: Please ensure you're confirming the command by entering: clearfollow confirm"); + } + $sql = "TRUNCATE follow"; //SQL Query to remove map + + if(mysqli_query($mysql,$sql)) + { + die("Successfully cleared follow table."); + } + else + { + die("MySQL Error: " . mysqli_error($mysql)); + } +} + +?> \ No newline at end of file diff --git a/cwslack-firmalerts.php b/cwslack-firmalerts.php index ae45f1c..d141f0e 100644 --- a/cwslack-firmalerts.php +++ b/cwslack-firmalerts.php @@ -1,5 +1,5 @@ . + along with this program. If not, see . */ //Receive connector for Connectwise Callbacks @@ -23,9 +23,6 @@ require_once 'config.php'; //Require the config file. require_once 'functions.php'; -$apicompanyname = strtolower($companyname); //Company name all lower case for api auth. -$authorization = base64_encode($apicompanyname . "+" . $apipublickey . ":" . $apiprivatekey); //Encode the API, needed for authorization. - //Dates required for URL to function $datenow = gmdate("Y-m-d\TH:i", strtotime("-10 minutes")); //Date set to 10 minutes prior to now, to catch for tickets happening right now. $date2hours = gmdate("Y-m-d\TH:i", strtotime("+2 hours")); //Date set to 2 hours out so reminders up to 2 hours function. @@ -35,9 +32,8 @@ //Set headers for cURL requests. $header_data covers API authentication while $header_data2 covers the Slack output. -$header_data =array( - "Authorization: Basic ". $authorization, -); +$header_data = authHeader($companyname, $apipublickey, $apiprivatekey); + $header_data2 =array( "Content-Type: application/json" ); @@ -54,12 +50,39 @@ $company = $companyarray[0]; //Set company to first part of second explode. $summary = $namearray[1]; //Set the ticket summary to second part of first explode. $datenow = date("Y-m-d\TH:i"); //Reusing datenow as non-GMT based time. - $datestart = date("Y-m-d\TH:i",strtotime($entry->dateStart)); //Start time of the tickte. - + $datestart = date("Y-m-d\TH:i",strtotime($entry->dateStart)); //Start time of the ticket. + + //Username mapping code + if($usedatabase==1) + { + $mysql = mysqli_connect($dbhost, $dbusername, $dbpassword, $dbdatabase); //Connect MySQL + + if (!$mysql) //Check for errors + { + die("Connection Error: " . mysqli_connect_error()); //Return error + } + + $sql = "SELECT * FROM `usermap` WHERE `cwname`=\"" . $user . "\""; //SQL Query to select all ticket number entries + + $result = mysqli_query($mysql, $sql); //Run result + $rowcount = mysqli_num_rows($result); + if($rowcount > 1) //If there were too many rows matching query + { + die("Error: too many users somehow?"); //This should NEVER happen. + } + else if ($rowcount == 1) //If exactly 1 row was found. + { + $row = mysqli_fetch_assoc($result); //Row association. + + $user = $row["slackuser"]; //Return the slack username portion of the found row as the $user variable to be used as part of the notification. + } + //If no rows are found here, then it just uses whatever if found as $user previously from the ticket. + } + if($reminder != "0 minutes" && $posttousers == 1) //If reminder is not 0 minutes, proceed. Pointless to have 0 minute reminder as that is handled below. { $datereminder = date("Y-m-d\TH:i",strtotime($entry->dateStart . " -" . $reminder)); //Set the reminder date to a readable comparable format. - + if($datenow==$datereminder) //If datenow and datereminder are the same.. { //Setup the slack return text @@ -80,7 +103,7 @@ cURLPost($webhookurl, $header_data2, "POST", $postfieldspre); } } - + if($datenow == $datestart) //If the start of the ticket is right now.. { if($posttousers==1) //And user post is on. diff --git a/cwslack-follow.php b/cwslack-follow.php index 87d83aa..2e98131 100644 --- a/cwslack-follow.php +++ b/cwslack-follow.php @@ -33,17 +33,7 @@ $link=1; } -//File Handling block -if(file_exists($dir."storage.txt")) //Check if storage file exists. -{ - $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //If so, open it. -} -else -{ - $f = fopen($dir."storage.txt", 'w') or die("can't open file"); //If not, create it. - fclose($f); //Close newly created file. - $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //Open it again for reading. -} +$command=NULL; //Set a null command variable, so it has something set no matter what. //Check for command errors. if($link==0 && !is_numeric($exploded[0])) { @@ -57,10 +47,9 @@ { echo "Unknown entry for ticket number."; return; - }; + } } -$command=NULL; //Set a null command variable, so it has something set no matter what. if($link==0){ $ticketnumber = $exploded[0]; //Read ticket number to variable for convenience. @@ -70,15 +59,15 @@ { $command = $exploded[1]; } -} -else +} +else { $ticketnumber = $_GET['srnumber']; $username = $_GET['memberid']; if($_GET['method']==$followtoken) { //For future use. - } + } else if ($_GET['method']==$unfollowtoken) { $command="unfollow"; //Set command to unfollow if it matches the CW unfollowtoken @@ -89,39 +78,90 @@ } } -if($command=="unfollow") //If unfollow is set in the text received from Slack. +if($usedatabase==1) { - $lines = explode("\n",$file); //Explode the file into each line + $mysql = mysqli_connect($dbhost, $dbusername, $dbpassword, $dbdatabase); + if (!$mysql) + { + die("Connection Error: " . mysqli_connect_error()); + } - foreach($lines as $line) //For each line in the file... + if ($command == "unfollow") { - $tempex = explode("^",$line); //Explode the line into parts based on character set by this file's output. + $sql = "DELETE FROM `follow` WHERE `ticketnumber`=\"" . $ticketnumber . "\" AND `slackuser`=\"" . $username . "\""; - if($tempex[0]!=$ticketnumber) //If the first part of the line is not the ticket number + if(mysqli_query($mysql,$sql)) + { + die("Successfully unfollowed ticket #".$ticketnumber); + } + else + { + die("MySQL Error: " . mysqli_error($mysql)); + } + } + else + { + $sql = "INSERT INTO `follow` (`id`, `ticketnumber`, `slackuser`) VALUES (NULL, '" . $ticketnumber . "', '" . $username . "');"; + if(mysqli_query($mysql,$sql)) { - $output[] = $line; //Output the line to the file again. + die("Successfully followed ticket #".$ticketnumber); } - else //If it is not + else { - if($tempex[1]!=$username) //If the second part is not the username of sender. + die("MySQL Error: " . mysqli_error($mysql)); + } + } +} +else +{ + //File Handling block + if(file_exists($dir."storage.txt")) //Check if storage file exists. + { + $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //If so, open it. + } + else + { + $f = fopen($dir."storage.txt", 'w') or die("can't open file"); //If not, create it. + fclose($f); //Close newly created file. + $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //Open it again for reading. + } + + + if($command=="unfollow") //If unfollow is set in the text received from Slack. + { + $lines = explode("\n",$file); //Explode the file into each line + + foreach($lines as $line) //For each line in the file... + { + $tempex = explode("^",$line); //Explode the line into parts based on character set by this file's output. + + if($tempex[0]!=$ticketnumber) //If the first part of the line is not the ticket number { - $output[]=$line; //Output the line to the file again. + $output[] = $line; //Output the line to the file again. } - else //If the ticket number and username match. + else //If it is the ticket number. { - //Do not output this line. + if($tempex[1]!=$username) //If the second part is not the username of sender. + { + $output[]=$line; //Output the line to the file again. + } + else //If the ticket number and username match. + { + //Do not output this line. + } } } + echo "Unfollowed ticket #" .$ticketnumber; //Return text to Slack + $out = implode("\n",$output); //Implode all lines. + file_put_contents($dir."/storage.txt",$out); //Output to file again, excluding the line unfollowed. + } + else //If no command. + { + file_put_contents($dir."/storage.txt","\n".$ticketnumber."^".$username,FILE_APPEND); //Take the ticket number and the username of the person who submitted it and output to storage file, seperated by ^ sign. + echo "Now following ticket #" . $ticketnumber; //Return text to Slack notifying of follow. } - echo "Unfollowed ticket #" .$ticketnumber; //Return text to Slack - $out = implode("\n",$output); //Implode all lines. - file_put_contents($dir."/storage.txt",$out); //Output to file again, excluding the line unfollowed. -} -else //If no command. -{ - file_put_contents($dir."/storage.txt","\n".$ticketnumber."^".$username,FILE_APPEND); //Take the ticket number and the username of the person who submitted it and output to storage file, seperated by ^ sign. - echo "Now following ticket #" . $ticketnumber; //Return text to Slack notifying of follow. } + ?> diff --git a/cwslack-incoming.php b/cwslack-incoming.php index 15d3cdc..888009e 100644 --- a/cwslack-incoming.php +++ b/cwslack-incoming.php @@ -23,9 +23,6 @@ require_once 'config.php'; //Require the config file. require_once 'functions.php'; -$apicompanyname = strtolower($companyname); //Company name all lower case for api auth. -$authorization = base64_encode($apicompanyname . "+" . $apipublickey . ":" . $apiprivatekey); //Encode the API, needed for authorization. - $data = json_decode(file_get_contents('php://input')); //Decode incoming body from connectwise callback. $info = json_decode(stripslashes($data->Entity)); //Decode the entity field which contains the JSON data we want. @@ -51,9 +48,7 @@ $dataTimeData = array(); //Blank array. //Set headers for cURL requests. $header_data covers API authentication while $header_data2 covers the Slack output. -$header_data =array( - "Authorization: Basic ". $authorization, -); +$header_data = authHeader($companyname, $apipublickey, $apiprivatekey); // Authorization array. Auto encodes API key for auhtorization. $header_data2 =array( "Content-Type: application/json" ); @@ -221,27 +216,53 @@ if($followenabled==1) { - if(file_exists($dir."storage.txt")) //Check if storage file exists. + $alerts = array(); //Create a blank array. + + if($usedatabase==1) { - $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //If so, open it. + $mysql = mysqli_connect($dbhost, $dbusername, $dbpassword, $dbdatabase); //Connect MySQL + if (!$mysql) //Check for errors + { + die("Connection Error: " . mysqli_connect_error()); //Die with error if error found + } + + $sql = "SELECT * FROM `follow` WHERE `ticketnumber`=\"" . $ticket . "\""; //SQL Query to select all ticket number entries + + $result = mysqli_query($mysql, $sql); //Run result + + if(mysqli_num_rows($result) > 0) //If there were rows matching query + { + while($row = mysqli_fetch_assoc($result)) //While we still have rows to work with + { + $alerts[]=$row["slackuser"]; //Add user to alerts array. + } + } } else { - $f = fopen($dir."storage.txt", 'w') or die("can't open file"); //If not, create it. - fclose($f); //Close newly created file. - $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //Open it again for reading. - } - $lines = explode("\n",$file); //Create array with each line being it's own part of the array. - $alerts = array(); //Create a blank array. - foreach($lines as $line) //Read through each line in the file. - { - $tempex = explode("^",$line); //Explode line based on seperator from cwslack-follow.php + if(file_exists($dir."storage.txt")) //Check if storage file exists. + { + $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //If so, open it. + } + else + { + $f = fopen($dir."storage.txt", 'w') or die("can't open file"); //If not, create it. + fclose($f); //Close newly created file. + $file = file_get_contents($dir."/storage.txt",FILE_SKIP_EMPTY_LINES); //Open it again for reading. + } + $lines = explode("\n",$file); //Create array with each line being it's own part of the array. - if($tempex[0]==$ticket) //If the first part of the line is the ticket number.. + foreach($lines as $line) //Read through each line in the file. { - $alerts[]=$tempex[1]; //Then add the username to the alerts array. + $tempex = explode("^",$line); //Explode line based on seperator from cwslack-follow.php + + if($tempex[0]==$ticket) //If the first part of the line is the ticket number.. + { + $alerts[]=$tempex[1]; //Then add the username to the alerts array. + } } } + if(!empty($alerts)) { foreach ($alerts as $username) //For each user in alerts array, set $postfieldspre to the follow message. { diff --git a/cwslack-notes.php b/cwslack-notes.php index 86b3fb9..8664a5c 100644 --- a/cwslack-notes.php +++ b/cwslack-notes.php @@ -26,23 +26,19 @@ if(empty($_GET['token']) || ($_GET['token'] != $slacknotestoken)) die("Slack token invalid."); //If Slack token is not correct, kill the connection. This allows only Slack to access the page for security purposes. if(empty($_GET['text'])) die("No text provided."); //If there is no text added, kill the connection. -$apicompanyname = strtolower($companyname); //Company name all lower case for api auth. -$authorization = base64_encode($apicompanyname . "+" . $apipublickey . ":" . $apiprivatekey); //Encode the API, needed for authorization. $exploded = explode(" ",$_GET['text']); //Explode the string attached to the slash command for use in variables. //This section checks if the ticket number is not equal to 6 digits (our tickets are in the hundreds of thousands but not near a million yet) and kills the connection if it's not. if(!is_numeric($exploded[0])) { //Check to see if the first command in the text array is actually help, if so redirect to help webpage detailing slash command use. if ($exploded[0]=="help") { - $test=json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true)); - echo $test; - return; + die(json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true))); //Encode a JSON response with a help URL. } else //Else close the connection. { echo "Unknown entry for ticket number."; return; - }; + } } $ticketnumber = $exploded[0]; //Set the ticket number to the first string $command=NULL; //Create a command variable and set it to Null @@ -65,10 +61,7 @@ } // Authorization array, with extra json content-type used in patch commands to change tickets. -$header_data =array( - "Authorization: Basic " . $authorization, - "Content-Type: application/json" -); +$header_data = postHeader($companyname, $apipublickey, $apiprivatekey); //Need to create array before hand to ensure no errors occur. $dataTNotes = array(); @@ -77,40 +70,59 @@ $postfieldspre = NULL; //avoid errors. if($command == "internal") //If second part of text is internal { - if($usecwname==1) //If usecwname variable is set. - { - $postfieldspre = array("internalAnalysisFlag" => "True", "member"=>array("identifier"=>$_GET['user_name']), "text" => $sentence); //Post ticket as slack user. - } - else //If not - { - $postfieldspre = array("internalAnalysisFlag" => "True", "text" => $sentence); //Post ticket as API user - } + $postfieldspre = array("internalAnalysisFlag" => "True", "text" => $sentence); //Post ticket as API user } else if ($command == "external")//If second part of text is external { - if($usecwname==1) + $postfieldspre = array("detailDescriptionFlag" => "True", "text" => $sentence); +} +else if ($command == "externalemail" || $command == "emailexternal")//If second part of text is external +{ + $postfieldspre = array("detailDescriptionFlag" => "True", "processNotifications" => "True", "text" => $sentence); +} +else //If second part of text is neither external or internal +{ + die("Second part of text must be either internal or external."); //Return error text. +} + +//Username mapping code +if($usedatabase==1) +{ + $mysql = mysqli_connect($dbhost, $dbusername, $dbpassword, $dbdatabase); //Connect MySQL + + if (!$mysql) //Check for errors { - $postfieldspre = array("detailDescriptionFlag" => "True", "member"=>array("identifier"=>$_GET['user_name']), "text" => $sentence); + die("Connection Error: " . mysqli_connect_error()); } - else + + $sql = "SELECT * FROM `usermap` WHERE `slackuser`=\"" . $_GET["user_name"] . "\""; //SQL Query to select all ticket number entries + + $result = mysqli_query($mysql, $sql); //Run result + $rowcount = mysqli_num_rows($result); + if($rowcount > 1) //If there were too many rows matching query { - $postfieldspre = array("detailDescriptionFlag" => "True", "text" => $sentence); + die("Error: too many users somehow?"); //This should NEVER happen. } -} -else if ($command == "externalemail" || $command == "emailexternal")//If second part of text is external -{ - if($usecwname==1) + else if ($rowcount == 1) //If exactly 1 row is found. { - $postfieldspre = array("detailDescriptionFlag" => "True", "processNotifications" => "True", "member"=>array("identifier"=>$_GET['user_name']), "text" => $sentence); + $row = mysqli_fetch_assoc($result); //Row association. + + $postfieldspre["member"] = array("identifier"=>$row["cwname"]); //Return the connectwise name of the row found as the CW member name. } - else + else //If no rows are found { - $postfieldspre = array("detailDescriptionFlag" => "True", "processNotifications" => "True", "text" => $sentence); + if($usecwname==1) //If variable enabled + { + $postfieldspre["member"] = array("identifier"=>$_GET['user_name']); //Return the slack username as the user for the ticket note. If the user does not exist in CW, it will use the API username. + } } } -else //If second part of text is neither external or internal +else { - die("Second part of text must be either internal or external."); //Return error text. + if($usecwname==1) + { + $postfieldspre["member"] = array("identifier"=>$_GET['user_name']); + } } $dataTNotes = cURLPost($noteurl, $header_data, "POST", $postfieldspre); diff --git a/cwslack.php b/cwslack.php index e79be8a..1261adf 100644 --- a/cwslack.php +++ b/cwslack.php @@ -17,14 +17,17 @@ along with this program. If not, see . */ +// This is a development branch, please use with caution as things will frequently be changing. ini_set('display_errors', 1); //Display errors in case something occurs header('Content-Type: application/json'); //Set the header to return JSON, required by Slack require_once 'config.php'; require_once 'functions.php'; -$apicompanyname = strtolower($companyname); //Company name all lower case for api auth. -$authorization = base64_encode($apicompanyname . "+" . $apipublickey . ":" . $apiprivatekey); //Encode the API, needed for authorization. +// Authorization array. Auto encodes API key for auhtorization above. +$header_data = authHeader($companyname, $apipublickey, $apiprivatekey); +// Authorization array, with extra json content-type used in patch commands to change tickets. +$header_data2 = postHeader($companyname, $apipublickey, $apiprivatekey); if(empty($_GET['token']) || ($_GET['token'] != $slacktoken)) die("Slack token invalid."); //If Slack token is not correct, kill the connection. This allows only Slack to access the page for security purposes. if(empty($_GET['text'])) die("No text provided."); //If there is no text added, kill the connection. @@ -34,15 +37,12 @@ if(!is_numeric($exploded[0])) { //Check to see if the first command in the text array is actually help, if so redirect to help webpage detailing slash command use. if ($exploded[0]=="help") { - $test=json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true)); - echo $test; - return; + die(json_encode(array("parse" => "full", "response_type" => "in_channel","text" => "Please visit " . $helpurl . " for more help information","mrkdwn"=>true))); } else //Else close the connection. { - echo "Unknown entry for ticket number."; - return; - }; + die("Unknown entry for ticket number."); + } } $ticketnumber = $exploded[0]; //Set the ticket number to the first string $command=NULL; //Create a command variable and set it to Null @@ -57,27 +57,16 @@ } //Set URLs $urlticketdata = $connectwise . "/v4_6_release/apis/3.0/service/tickets/" . $ticketnumber; //Set ticket API url -$noteurl = $connectwise . "/v4_6_release/apis/3.0/service/tickets/" . $ticketnumber . "/notes?orderBy=id%20desc"; $ticketurl = $connectwise . "/v4_6_release/services/system_io/Service/fv_sr100_request.rails?service_recid="; //Ticket URL for connectwise. $timeurl = $connectwise . "/v4_6_release/apis/3.0/time/entries?conditions=chargeToId=" . $ticketnumber . "&chargeToType=%27ServiceTicket%27&orderBy=dateEntered%20desc"; //Set the URL required for cURL requests to the time entry API. - - -//Set noteurl to use ascending if an initial note command is passed. -if($command == "initial" || $command == "first" || $command == "note") +if($command == "initial" || $command == "first" || $command == "note") //Set noteurl to use ascending if an initial note command is passed, else use descending. { $noteurl = $connectwise . "/v4_6_release/apis/3.0/service/tickets/" . $ticketnumber . "/notes?orderBy=id%20asc"; } - -$utc = time(); //Get the time. -// Authorization array. Auto encodes API key for auhtorization above. -$header_data =array( - "Authorization: Basic ". $authorization, -); -// Authorization array, with extra json content-type used in patch commands to change tickets. -$header_data2 =array( -"Authorization: Basic " . $authorization, - "Content-Type: application/json" -); +else +{ + $noteurl = $connectwise . "/v4_6_release/apis/3.0/service/tickets/" . $ticketnumber . "/notes?orderBy=id%20desc"; +} //Need to create 3 arrays before hand to ensure no errors occur. $dataTNotes = array(); @@ -93,52 +82,7 @@ { die("Array not returned in line 195. Please check your connectwise URL variable in config.php and ensure it is accessible via the web at " . $urlticketdata); } -if(array_key_exists("code",$dataTData)) { //Check if array contains error code - if($dataTData->code == "NotFound") { //If error code is NotFound - echo "Connectwise ticket " . $ticketnumber . " was not found."; //Report that the ticket was not found. - return; - } - if($dataTData->code == "Unauthorized") { //If error code is an authorization error - echo "401 Unauthorized, check API key to ensure it is valid."; //Fail case. - return; - } - else { - echo "Unknown Error Occurred, check API key and other API settings." . $dataTData->code; //Fail case. - return; - } -} - -if($posttext==1) //Block for curl to get latest note -{ - $createdby = "Error"; //Create with error just in case. - $notetext = "Error"; //Create with error just in case. - - $dataTNotes = cURL($noteurl, $header_data); // Get the JSON returned by the CW API for $noteurl. - - $dataTimeData = cURL($timeurl, $header_data); // Get the JSON returned by the CW API for $timeurl. - - if($command == "full" || $command == "notes" || $command == "all") - { - $dataTNotes2 = cURL($connectwise . "/v4_6_release/apis/3.0/service/tickets/" . $ticketnumber . "/notes?orderBy=id%20asc", $header_data); // Get the JSON returned by the CW API for ticket notes. - } - $createdby = $dataTNotes[0]->createdBy; //Set $createdby to the ticket note creator. - $notetime = new DateTime($dataTNotes[0]->dateCreated); //Create new datetime object based on ticketnote note. - $notedate = $dataTNotes[0]->dateCreated; - - $text = $dataTNotes[0]->text; //Set $text to the ticket text. - if(array_key_exists(0,$dataTNotes) && array_key_exists(0,$dataTimeData) && $command != "initial" && $command != "first" && $command != "note") //Check if arrays exist properly. - { - $timetime = new DateTime($dataTimeData[0]->dateEntered); //Create new time object based on time entry note. - - if($timetime>$notetime) //If the time entry is newer than latest ticket note. - { - $createdby = $dataTimeData[0]->enteredBy; //Set $createdby to the time entry creator. - $text = $dataTimeData[0]->notes; //Set $text to the time entry text. - $notedate = $dataTimeData[0]->dateEntered; - } - } -} //- //Priority command //- @@ -159,16 +103,32 @@ } else //If unknown { - echo "Failed to get priority code"; //Send error message. Anything not Slack JSON formatted will return just to the user who submitted the slash command. Don't need to spam errors. - return; + die("Failed to get priority code: " . $option3); //Send error message. Anything not Slack JSON formatted will return just to the user who submitted the slash command. Don't need to spam errors. } - $dataTCmd = cURLPost( - $urlticketdata, - $header_data2, - "PATCH", - array(array("op" => "replace", "path" => "/priority/id", "value" => $priority)) + $dataTCmd = cURLPost( //Function for POST requests in cURL + $urlticketdata, //URL + $header_data2, //Header + "PATCH", //Request type + array(array("op" => "replace", "path" => "/priority/id", "value" => $priority)) //POST Body ); + + $return =array( + "parse" => "full", //Parse all text. + "response_type" => "in_channel", //Send the response in the channel + "attachments"=>array(array( + "fallback" => "Info on Ticket #" . $dataTData->id, //Fallback for notifications + "title" => "Ticket Summary: " . $dataTData->summary, //Set bolded title text + "pretext" => "Ticket #" . $dataTData->id . "'s priority has been set to " . $option3, //Set pretext + "text" => "Click <" . $ticketurl . $dataTData -> id . "&companyName" . $companyname . "|here> to open the ticket.", //Set text to be returned + "mrkdwn_in" => array( //Set markdown values + "text", + "pretext" + ) + )) + ); + + die(json_encode($return, JSON_PRETTY_PRINT)); //Return properly encoded arrays in JSON for Slack parsing. } //- @@ -188,8 +148,7 @@ } else { - echo "Failed to get status code"; - return; + die("Failed to get status code: " . $option3); } $dataTCmd = cURLPost( $urlticketdata, @@ -197,22 +156,59 @@ "PATCH", array(array("op" => "replace", "path" => "/status/id", "value" => $status)) ); + + $return =array( + "parse" => "full", + "response_type" => "in_channel", + "attachments"=>array(array( + "fallback" => "Info on Ticket #" . $dataTData->id, //Fallback for notifications + "title" => "Ticket Summary: " . $dataTData->summary, + "pretext" => "Ticket #" . $dataTData->id . "'s status has been set to " . $option3, + "text" => "Click <" . $ticketurl . $dataTData -> id . "&companyName" . $companyname . "|here> to open the ticket.", + "mrkdwn_in" => array( + "text", + "pretext" + ) + )) + ); + + die(json_encode($return, JSON_PRETTY_PRINT)); //Return properly encoded arrays in JSON for Slack parsing. } +if($posttext==1) //Block for curl to get latest note +{ + $createdby = "Error"; //Create with error just in case. + $notetext = "Error"; //Create with error just in case. + + $dataTNotes = cURL($noteurl, $header_data); // Get the JSON returned by the CW API for $noteurl. -if(array_key_exists("code",$dataTCmd)) { //Check if array contains error code - if($dataTCmd->code == "NotFound") { //If error code is NotFound - echo "Connectwise ticket " . $ticketnumber . " was not found."; //Report that the ticket was not found. - return; - } - if($dataTCmd->code == "Unauthorized") { //If error code is an authorization error - echo "401 Unauthorized, check API key to ensure it is valid."; //Fail case. - return; + $dataTimeData = cURL($timeurl, $header_data); // Get the JSON returned by the CW API for $timeurl. + + if($command == "full" || $command == "notes" || $command == "all") + { + $dataTNotes2 = cURL($connectwise . "/v4_6_release/apis/3.0/service/tickets/" . $ticketnumber . "/notes?orderBy=id%20asc", $header_data); // Get the JSON returned by the CW API for ticket notes. } - else { - echo "Unknown Error Occurred, check API key and other API settings. Error: " . $dataTCmd->code; //Fail case. - return; + + $createdby = $dataTNotes[0]->createdBy; //Set $createdby to the ticket note creator. + $notetime = new DateTime($dataTNotes[0]->dateCreated); //Create new datetime object based on ticketnote note. + $notedate = $dataTNotes[0]->dateCreated; + + $text = $dataTNotes[0]->text; //Set $text to the ticket text. + if(array_key_exists(0,$dataTNotes) && array_key_exists(0,$dataTimeData) && $command != "initial" && $command != "first" && $command != "note") //Check if arrays exist properly. + { + $timetime = new DateTime($dataTimeData[0]->dateEntered); //Create new time object based on time entry note. + + + if ($timetime > $notetime) //If the time entry is newer than latest ticket note. + { + $createdby = $dataTimeData[0]->enteredBy; //Set $createdby to the time entry creator. + $text = $dataTimeData[0]->notes; //Set $text to the time entry text. + $notedate = $dataTimeData[0]->dateEntered; + } } + + $date2=strtotime($notedate); + $date2format=date('m-d-Y g:i:sa',$date2); } $date=strtotime($dataTData->dateEntered); //Convert date entered JSON result to time. @@ -231,53 +227,12 @@ { $resources=$dataTData->resources; } -if($posttext==1) -{ - $date2=strtotime($notedate); - $date2format=date('m-d-Y g:i:sa',$date2); -} - if(!$dataTData->contact==NULL) { //Check if contact name exists in array. $contact = $dataTData->contact->name; //Set contact variable to contact name. } - -if($command == "priority") //If command is priority. -{ - $return =array( - "parse" => "full", //Parse all text. - "response_type" => "in_channel", //Send the response in the channel - "attachments"=>array(array( - "fallback" => "Info on Ticket #" . $dataTData->id, //Fallback for notifications - "title" => "Ticket Summary: " . $dataTData->summary, //Set bolded title text - "pretext" => "Ticket #" . $dataTData->id . "'s priority has been set to " . $option3, //Set pretext - "text" => "Click <" . $ticketurl . $dataTData -> id . "&companyName" . $companyname . "|here> to open the ticket.", //Set text to be returned - "mrkdwn_in" => array( //Set markdown values - "text", - "pretext" - ) - )) - ); -} -else if($command == "status") //If command is status. -{ - $return =array( - "parse" => "full", - "response_type" => "in_channel", - "attachments"=>array(array( - "fallback" => "Info on Ticket #" . $dataTData->id, //Fallback for notifications - "title" => "Ticket Summary: " . $dataTData->summary, - "pretext" => "Ticket #" . $dataTData->id . "'s status has been set to " . $option3, - "text" => "Click <" . $ticketurl . $dataTData -> id . "&companyName" . $companyname . "|here> to open the ticket.", - "mrkdwn_in" => array( - "text", - "pretext" - ) - )) - ); -} -else if($command == "initial" || $command == "first" || $command == "note") +if($command == "initial" || $command == "first" || $command == "note") { if($posttext==0) { diff --git a/functions.php b/functions.php index 19cd975..6b58760 100644 --- a/functions.php +++ b/functions.php @@ -49,7 +49,27 @@ function cURL($url, $header) } curl_close($ch); - return json_decode($curlBodyTData); //Decode the JSON returned by the CW API. + $jsonDecode = json_decode($curlBodyTData); //Decode the JSON returned by the CW API. + + if(array_key_exists("code",$jsonDecode)) { //Check if array contains error code + if($jsonDecode->code == "NotFound") { //If error code is NotFound + die("Connectwise record was not found."); //Report that the ticket was not found. + } + if($jsonDecode->code == "Unauthorized") { //If error code is an authorization error + die("401 Unauthorized, check API key to ensure it is valid."); //Fail case. + } + else { + die("Unknown Error Occurred, check API key and other API settings. Error: " . $jsonDecode->code); //Fail case. + } + } + if(array_key_exists("errors",$jsonDecode)) //If connectwise returned an error. + { + $errors = $dataTData->errors; //Make array easier to access. + + die("ConnectWise Error: " . $errors[0]->message); //Return CW error + } + + return $jsonDecode; } /** @@ -85,9 +105,50 @@ function cURLPost($url, $header, $request, $postfieldspre) die(curl_error($ch)); } curl_close($ch); + if($curlBodyTCmd == "ok") //Slack catch + { + return null; + } + $jsonDecode = json_decode($curlBodyTCmd); //Decode the JSON returned by the CW API. + + if(array_key_exists("code",$jsonDecode)) { //Check if array contains error code + if($jsonDecode->code == "NotFound") { //If error code is NotFound + die("Connectwise record was not found."); //Report that the ticket was not found. + } + if($jsonDecode->code == "Unauthorized") { //If error code is an authorization error + die("401 Unauthorized, check API key to ensure it is valid."); //Fail case. + } + else { + die("Unknown Error Occurred, check API key and other API settings. Error: " . $jsonDecode->code); //Fail case. + } + } + if(array_key_exists("errors",$jsonDecode)) //If connectwise returned an error. + { + $errors = $jsonDecode->errors; //Make array easier to access. + + die("ConnectWise Error: " . $errors[0]->message); //Return CW error + } - return json_decode($curlBodyTCmd); + return $jsonDecode; } +function authHeader($company, $publickey, $privatekey) +{ + $apicompanyname = strtolower($company); //Company name all lower case for api auth. + $authorization = base64_encode($apicompanyname . "+" . $publickey . ":" . $privatekey); //Encode the API, needed for authorization. + + return array("Authorization: Basic ". $authorization); +} + +function postHeader($company, $publickey, $privatekey) +{ + $apicompanyname = strtolower($company); //Company name all lower case for api auth. + $authorization = base64_encode($apicompanyname . "+" . $publickey . ":" . $privatekey); //Encode the API, needed for authorization. + + return array( + "Authorization: Basic " . $authorization, + "Content-Type: application/json" + ); +} ?> \ No newline at end of file diff --git a/install.php b/install.php new file mode 100644 index 0000000..6a25373 --- /dev/null +++ b/install.php @@ -0,0 +1,477 @@ + + + + + + + + + + + + CWSlack Installer + + +
+
+

CWSlack-SlashCommands Installer

+ MySQL Configuration

"; + + echo "
+

+

+

+


+ "; + echo "
"; + die(); + } + if ($_GET["page"] == "Setup Settings" || $_GET["page"] == "Skip to Config.php Settings") { + echo "

Settings Configuration

"; + echo "
Any field left blank will not change the setting, however yes/no questions must be updated any time you save this.
"; + echo "
+

General

+
Ensure that your URL is set to https://cw.domain.tld OR if you're hosted, use https://api-country.myconnectwise.net.
+

+
Set company name to the one you use when logging into ConnectWise
+

+
Set API keys according to the README.md API instructions.
+

+

+
Set time zone to PHP supported format such as America/Chicago. Full list here.
+

+

+
+

Tokens

+
Set each of these to the respective Slack Token that you've setup. Leave blank if you do not need them.
+

+

+

+

+

+

+
The one below is for the use of the DBManage module, not needed if you plan to do all MySQL work in a different way.
+

+

Incoming Module

+
+
Yes No
+
Yes No
+
Yes No
+
Yes No
+
Yes No
+
Yes No
+
+
+
Set these to any \"bad\" things you don't want posting updates. Use the pipe symbol | to separate multiple items.
+
+
+
+

FirmAlerts Module

+
Yes No
+
Yes No
+
Yes No
+
+

Follow Module

+
Yes No
+
+
+

DBManage Module

+
List of Slack usernames that can access the /dbm commands. Seperate them by a pipe symbol, |
+
+ +

"; + echo ""; + //Template for future use + //
Yes No
+ //
+ die(); + } + if ($_GET["page"] == "Test MySQL") { + $dbhost = $_POST["dbhost"]; + $dbusername = $_POST["dbusername"]; + $dbpassword = $_POST["dbpassword"]; + $dbdatabase = $_POST["dbname"]; + + $mysql = mysqli_connect($dbhost, $dbusername, $dbpassword); + + if (!$mysql) { + echo "
"; + echo "Connection Error: " . mysqli_connect_error(); + echo "
"; + echo "
+ +
"; + die(); + } + + $dbselect = mysqli_select_db($mysql, $dbdatabase); + if (!$dbselect) { + //Select database failed + $sql = "CREATE DATABASE " . $dbdatabase; + if (mysqli_query($mysql, $sql)) { + //Database created successfully + $dbselect = mysqli_select_db($mysql, $dbdatabase); + } else { + echo "
"; + echo "Database Creation Error: " . mysqli_error($mysql); + echo "
"; + echo "
+ +
"; + die(); + } + } + + $sql = "CREATE TABLE IF NOT EXISTS follow (id INT(7) UNSIGNED AUTO_INCREMENT PRIMARY KEY, ticketnumber INT(10) NOT NULL, slackuser VARCHAR(25) NOT NULL)"; + if (mysqli_query($mysql, $sql)) { + //Table created successfully + } else { + echo "
"; + echo "follow Table Creation Error: " . mysqli_error($mysql); + echo "
"; + echo "
+ +
"; + die(); + } + + $sql = "CREATE TABLE IF NOT EXISTS usermap (slackuser VARCHAR(25) PRIMARY KEY, cwname VARCHAR(25) NOT NULL)"; + if (mysqli_query($mysql, $sql)) { + //Table created successfully + } else { + echo "
"; + echo "usermap Table Creation Error: " . mysqli_error($mysql); + echo "
"; + echo "
+ +
"; + die(); + } + + $sql = "CREATE TABLE IF NOT EXISTS usermap (slackuser VARCHAR(25) PRIMARY KEY, cwname VARCHAR(25) NOT NULL)"; + if (mysqli_query($mysql, $sql)) { + //Table created successfully + } else { + echo "
"; + echo "usermap Table Creation Error: " . mysqli_error($mysql); + echo "
"; + echo "
+ +
"; + die(); + } + + echo "
"; + echo "Successfully connected and setup MySQL Database!

You can now finish configuring the options in config.php and then test it out! You can also click the button below to configure the config.php file with this script."; + echo "
Please remove install.php to avoid people accessing it externally if you manually configure settings.
"; + echo "
+ +
"; + + mysqli_close($mysql); + + $filedata = file('config.php'); + $newdata = array(); + + foreach ($filedata as $data) { + if (stristr($data, '$dbhost')) { + $newdata[] = '$dbhost = "' . $dbhost . '"; //Your MySQL DB' . PHP_EOL; + } else if (stristr($data, '$dbusername')) { + $newdata[] = '$dbusername = "' . $dbusername . '"; //Your MySQL DB Username' . PHP_EOL; + } else if (stristr($data, '$dbpassword')) { + $newdata[] = '$dbpassword = "' . $dbpassword . '"; //Your MySQL DB Password' . PHP_EOL; + } else if (stristr($data, '$dbdatabase')) { + $newdata[] = '$dbdatabase = "' . $dbdatabase . '"; //Change if you have an existing database you want to use, otherwise leave as default.' . PHP_EOL; + } else if (stristr($data, '$usedatabase')) { + $newdata[] = '$usedatabase = 1; // Set to 0 by default, set to 1 if you want to enable MySQL.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } + + file_put_contents('config.php', implode('', $newdata)); + + die(); + } + if ($_GET["page"] == "Save Settings") { + $filedata = file('config.php'); + $newdata = array(); + + foreach ($filedata as $data) { + if (stristr($data, '$connectwise =')) { + if (!empty($_POST["connectwise"])) { + $newdata[] = '$connectwise = "' . $_POST["connectwise"] . '"; //Set your Connectwise URL' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$companyname =')) { + if (!empty($_POST["companyname"])) { + $newdata[] = '$companyname = "' . $_POST["companyname"] . '"; //Set your company name from Connectwise. This is the company name field from login.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$apipublickey =')) { + if (!empty($_POST["apipublickey"])) { + $newdata[] = '$apipublickey = "' . $_POST["apipublickey"] . '"; //Public API key' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$apiprivatekey =')) { + if (!empty($_POST["apiprivatekey"])) { + $newdata[] = '$apiprivatekey = "' . $_POST["apiprivatekey"] . '"; //Private API key' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$timezone =')) { + if (!empty($_POST["timezone"])) { + $newdata[] = '$timezone = "' . $_POST["timezone"] . '"; //Set your timezone here.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$helpurl =')) { + if (!empty($_POST["helpurl"])) { + $newdata[] = '$helpurl = "' . $_POST["helpurl"] . '"; //Set your help article URL here.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$slacktoken =')) { + if (!empty($_POST["slacktoken"])) { + $newdata[] = '$slacktoken = "' . $_POST["slacktoken"] . '"; //Set token from the Slack slash command screen.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$slackactivitiestoken =')) { + if (!empty($_POST["slackactivitiestoken"])) { + $newdata[] = '$slackactivitiestoken = "' . $_POST["slackactivitiestoken"] . '"; //Set your token for the activities slash command' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$slackcontactstoken =')) { + if (!empty($_POST["slackcontactstoken"])) { + $newdata[] = '$slackcontactstoken = "' . $_POST["slackcontactstoken"] . '"; //Set your token for the contacts slash command' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$slacknotestoken =')) { + if (!empty($_POST["slacknotestoken"])) { + $newdata[] = '$slacknotestoken = "' . $_POST["slacknotestoken"] . '"; //Set your token for the notes slash command' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$slackconfigstoken =')) { + if (!empty($_POST["slackconfigstoken"])) { + $newdata[] = '$slackconfigstoken = "' . $_POST["slackconfigstoken"] . '"; //Set your token for the configs slash command' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$slackfollowtoken =')) { + if (!empty($_POST["slackfollowtoken"])) { + $newdata[] = '$slackfollowtoken = "' . $_POST["slackfollowtoken"] . '"; //Set your token for the follow slash command' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$slackdbmantoken =')) { + if (!empty($_POST["slackdbmantoken"])) { + $newdata[] = '$slackdbmantoken = "' . $_POST["slackdbmantoken"] . '"; //Set your token for the database management slash command' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$webhookurl =')) { + if (!empty($_POST["webhookurl"])) { + $newdata[] = '$webhookurl = "' . $_POST["webhookurl"] . '"; //Change this to the URL retrieved from incoming webhook setup for Slack.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$postadded =')) { + if ($_POST["postadded"] == "yes") { + $newdata[] = '$postadded = 1; //Set this to post new tickets to slack.' . PHP_EOL; + } else { + $newdata[] = '$postadded = 0; //Set this to post new tickets to slack.' . PHP_EOL; + } + } else if (stristr($data, '$postupdated =')) { + if ($_POST["postupdated"] == "yes") { + $newdata[] = '$postupdated = 1; //Set this to post updated tickets to slack. Defaults to off to avoid spam' . PHP_EOL; + } else { + $newdata[] = '$postupdated = 0; //Set this to post updated tickets to slack. Defaults to off to avoid spam' . PHP_EOL; + } + } else if (stristr($data, '$allowzadmin =')) { + if ($_POST["allowzadmin"] == "yes") { + $newdata[] = '$allowzadmin = 1; //Set this to allow posts from zAdmin, warning as zAdmin does workflow rules so update spam is countered, however new client tickets are through zAdmin. To avoid insane spam, do not have this turned on while $postupdated is turned on.' . PHP_EOL; + } else { + $newdata[] = '$allowzadmin = 0; //Set this to allow posts from zAdmin, warning as zAdmin does workflow rules so update spam is countered, however new client tickets are through zAdmin. To avoid insane spam, do not have this turned on while $postupdated is turned on.' . PHP_EOL; + } + } else if (stristr($data, '$posttext =')) { + if ($_POST["posttext"] == "yes") { + $newdata[] = '$posttext = 1; //Set to 1 if you want it to post the latest note from the ticket into chat whenever a ticket is created or updated.' . PHP_EOL; + } else { + $newdata[] = '$posttext = 0; //Set to 1 if you want it to post the latest note from the ticket into chat whenever a ticket is created or updated.' . PHP_EOL; + } + } else if (stristr($data, '$postcompany =')) { + if ($_POST["postcompany"] == "yes") { + $newdata[] = '$postcompany = 1; //Set to 1 if you want the Company to be posted in the clear text of the post (general what will be seen on IRC/XMPP)' . PHP_EOL; + } else { + $newdata[] = '$postcompany = 0; //Set to 1 if you want the Company to be posted in the clear text of the post (general what will be seen on IRC/XMPP)' . PHP_EOL; + } + } else if (stristr($data, '$timeenabled =')) { + if ($_POST["timeenabled"] == "yes") { + $newdata[] = '$timeenabled = 1; //Set to 1 if you want to post all tickets past $timepast to a specific channel, $timechan' . PHP_EOL; + } else { + $newdata[] = '$timeenabled = 0; //Set to 1 if you want to post all tickets past $timepast to a specific channel, $timechan' . PHP_EOL; + } + } else if (stristr($data, '$timepast =')) { + if (!empty($_POST["timepast"])) { + $newdata[] = '$timepast = ' . $_POST["timepast"] . '; //Set to a time in hours where once reached all updates will post to #dispatch.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$timechan =')) { + if (!empty($_POST["timechan"])) { + $newdata[] = '$timechan = "' . $_POST["timechan"] . '"; //Set to a channel to post to for $timeenabled' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$badboard =')) { + if (!empty($_POST["badboard"])) { + $newdata[] = '$badboard = "' . $_POST["badboard"] . '"; //Set to any board name you want to fail, to avoid ticket creation/updates from this board posting to Slack.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$badstatus =')) { + if (!empty($_POST["badstatus"])) { + $newdata[] = '$badstatus = "' . $_POST["badstatus"] . '"; //Set to any status name you want to fail, to avoid ticket creation/updates with this status from posting to Slack.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$badcompany =')) { + if (!empty($_POST["badcompany"])) { + $newdata[] = '$badcompany = "' . $_POST["badcompany"] . '"; //Set to any company name you want to fail, to avoid ticket creation for catchall from posting to Slack.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$posttousers =')) { + if ($_POST["posttousers"] == "yes") { + $newdata[] = '$posttousers = 1; //When set, will post to the user whenever the appointment reminder is reached.' . PHP_EOL; + } else { + $newdata[] = '$posttousers = 0; //When set, will post to the user whenever the appointment reminder is reached.' . PHP_EOL; + } + } else if (stristr($data, '$posttochan =')) { + if ($_POST["posttochan"] == "yes") { + $newdata[] = '$posttochan = 1; //When set, will post to $timechan whenever the firm appointment starts.' . PHP_EOL; + } else { + $newdata[] = '$posttochan = 0; //When set, will post to $timechan whenever the firm appointment starts.' . PHP_EOL; + } + } else if (stristr($data, '$usetimechan =')) { + if ($_POST["usetimechan"] == "yes") { + $newdata[] = '$usetimechan = 1; //When set, this will use the $timechan variable instead of the one below.' . PHP_EOL; + } else { + $newdata[] = '$usetimechan = 0; //When set, this will use the $timechan variable instead of the one below.' . PHP_EOL; + } + } else if (stristr($data, '$firmalertchan =')) { + if (!empty($_POST["firmalertchan"])) { + $newdata[] = '$firmalertchan = "' . $_POST["firmalertchan"] . '"; //When you want to split time alerts and firm alerts into their own channels.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$followenabled =')) { + if ($_POST["postadded"] == "yes") { + $newdata[] = '$followenabled = 1; //When set to 1, follow commands and the follow scripts will be enabled.' . PHP_EOL; + } else { + $newdata[] = '$followenabled = 0; //When set to 1, follow commands and the follow scripts will be enabled.' . PHP_EOL; + } + } else if (stristr($data, '$followtoken =')) { + if (!empty($_POST["followtoken"])) { + $newdata[] = '$followtoken = "' . $_POST["followtoken"] . '"; //Change to random text to be used in your CW follow link if you use it. Defaults to follow which is fine for testing.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$unfollowtoken =')) { + if (!empty($_POST["unfollowtoken"])) { + $newdata[] = '$unfollowtoken = "' . $_POST["unfollowtoken"] . '"; //Change to random text to be used in your CW unfollow link if you use it. Defaults to unfollow which is fine for testing.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else if (stristr($data, '$adminlist =')) { + if (!empty($_POST["adminlist"])) { + $newdata[] = '$adminlist = "' . $_POST["adminlist"] . '"; //Separate by pipe symbol as seen in example if you need multiple people to have access.' . PHP_EOL; + } else { + $newdata[] = $data; + } + } else { + $newdata[] = $data; + } + } + + file_put_contents('config.php', implode('', $newdata)); + echo "
"; + echo "Successfully configured the config.php file! Please test out your commands in Slack and submit any issues you have to GitHub!"; + echo "
Please remove install.php to avoid people accessing it externally. You can re-add it anytime to configure database or settings again, or just manually edit config.php.
"; + echo ""; + die(); + } + } + + $php_version=phpversion(); + preg_match("#^\d.\d#", phpversion(), $match); + if($match[0]<5) + { + $php_error="Error: PHP version is ".phpversion().", Version 5 or newer is required."; + } + if($match[0]>6) + { + $php_warning="Warning: PHP version is ".phpversion().", Script tested only on Version 5."; + } + + // declare function + function find_SQL_Version() { + $output = shell_exec('mysql -V'); + preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version); + return @$version[0]?$version[0]:-1; + } + + $mysql_version=find_SQL_Version(); + if($mysql_version<5) + { + $mysql_error="Error: MySQL version is $mysql_version. Version 5 or newer is required."; + } + + if(!function_exists('curl_exec')) + { + $curl_error="Error: PHP CURL function is not enabled!"; + } + ?> + + +

Checking versions...

+ + Success: PHP Version $php_version - OK!

"; + else if (empty($php_error)) echo "$php_warning

"; + else echo "$php_error

"; + + if(empty($mysql_error)) echo "Success: MySQL Version $mysql_version - OK!

"; + else echo "$mysql_error

"; + + if(empty($curl_error)) echo "Success: cURL Enabled - OK!

"; + else echo "$curl_error

"; + + if(empty($curl_error) && empty($mysql_error) && empty($php_error)) + { + echo "
+ +
"; + echo "
+ +
"; + } + else + { + echo ""; + } + ?> + + + + \ No newline at end of file