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 @@
+
+
+