Add your own App to Slack

Overview

So you want to create an App in Slack – meaning that you add new commands in Slack (e.g. “/mynewcommand”) which Slack users of your workspace can use to execute certain functionality. Your App provides this functionality.
This is useful for example, if you run Slack in a company workspace context, and you want to provide a new function, e.g. make certain company data accessible within Slack.

For this, you need the following:

  • An App in Slack (which is published within your workspace)
  • A script/module/… which provides the needed functionality and acts on certain commands in Slack that call this functionality

Let’s go through this one-by-one. Note that a certain knowledge about Slack is needed here; the existing Slack documentation at https://api.slack.com is very good (e.g. here).

Create the App

Go to your Slack Dashboard at https://api.slack.com/apps. Create a new App (by clicking on the respective button). You need to choose your workspace (look it up in your Slack client on your settings; it’s something like ‘companyxyzworkspace.slack.com’).

You may need to speak to your Slack workspace administrator to get the App distributed (i.e. make it visible in your workspace).
Get the AppID (e.g. ‘https://api.slack.com/apps/A…’) and client secret (e.g. ‘5…..’, a very long hex string). This is displayed in the “App Credentials” section of your App (click on your App’s name at https://api.slack.com/apps).

Switch on interactivity: Go to the “Interactive Components” menu (https://api.slack.com/apps/YOUR-APP-ID/interactive-messages?) and switch on interactivity. Set the request URL; this is the URL where your script should sit and listen for incoming HTTP POST requests (e.g. ‘https://my-domain.com/my-script.php’). Note that this has to be a secure server (with TLS), so pure http-requests are not sufficient.

Create your script

You need a script to do the actual work (i.e. contain the desired business logic). I use a php-script, but the programming language doesn’t matter.

Your script has to be publicly reachable (i.e. not reside on some server on your intranet), as it is called from Slack servers.

Identify the user

In order to ensure that your script is only called from Slack servers and empowered users, its first action should be a validation of the calling user. Use the Slack method “users.profile.get” for that (see here). This requires an OAuth-token that has to be passed as parameter.
Create this OAuth token for your App at the “OAuth & Permission” section of your App in Slack (click on your App’s name at https://api.slack.com/apps). The OAuth token is a very long alphanumeric string with some hyphens.

In order to use the users.profile.get function,. your App needs to have the correct scopes applied: team.read and users.profile.read. Assign these permissions in the “Scopes” section of the “OAuth & Permission” section.

Thus the first function of your script could look like this in php:

<?php
$user_id = $_POST['user_id']; // the userid was passed to your script from Slack as POST parameter
$slackoauthtoken= "xoxp-YOUR_OAUTH_TOKEN"; // the slackoauthtoken is the OAuth token generated for your App
$display_name_of_current_user = getDisplayname($user_id,$slackoauthtoken);


function getDisplayname($userid,$slackoauthtoken)
{
$loc = "https://slack.com/api/users.profile.get"; 
$POST['token'] = $slackoauthtoken;
$POST['user'] = $userid;
$ch = curl_init($loc);

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
curl_setopt($ch, CURLOPT_POSTFIELDS, $POST);                                                                  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     

$result = curl_exec($ch);
    if ($error = curl_errno($ch)) { echo $error; }
    //close connection
    curl_close($ch);

$resultarray = json_decode($result, true); #  return JSON as associative array
print_r($resultarray); #for debug purposes only
$display_name = $resultarray["profile"]["display_name"];
return ($display_name);
} # of getDisplayname

?>

You should add some error handling etc; omitted here for clarity. Note also that Slack returns various parameters, e.g. real_name, display_name, first_name and last_name. Not all of these are always filled; this depends on the user’s configuration.

Now do whatever you want to do in this script; e.g. save data for this user, or retrieve data. Obviously you need to set up and access your own database here, e.g. on the webspace where your script resides.

Send commands

The user shall be able to execute an action from within the Slack client. Go to “Slash Commands” in the “Add features and functionality” section (under “Basic information”) of your Slack App and create a new command, e.g. “/mycommand”. Note that these commands typically have the scope of your entire Slack installation (so they are visible and usable in all channels); thus you may want to name them clearly, e.g. “/myappmycommand”.
In the request URL set the URL of your script, e.g. your PHP script (e.g. ‘https://my-domain.com/my-script.php’).
Once your created this command, a user can call it from within the Slack client. The URL will be called (i.e. your script), and the command (together with some payload data) will be added to the POST request, and you can use it within your script:

$user_id = $_POST['user_id']; 
$command = $_POST['command'];
...
if ($command == "/myappmycommand") 
{ ... }

Sending data back to Slack
Obviously your script shall provide some result back to the calling user and his Slack client. Luckily, Slack will provide the response-URL (to which you have to post your results) directly in the request:

$user_id = $_POST['user_id']; 
$command = $_POST['command'];
$response_url = $_POST['response_url'];

Note that this approach is slightly outdated (see https://api.slack.com/interactive-messages), but for the beginner it’s easier to understand.

If you want to generically post messages into a channel, define a webhook (see section ‘Incoming Webhooks’ in your Slack Apps page). You need a channel in your workspace as the target of your automatic posts.
In order to send back data to Slack, build a JSON structure, e.g.:

$url = 'https://hooks.slack.com/services/YOUR_WEEBHOOK_URL'; # to channel xyz

//create a new cURL resource
$ch = curl_init($url);
$message = "Hello $display_name_of_current_user, this is a message from Slack.\n";
$data = array(
	"text" => $message
	   );
$payload = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

Testing the App
Testing your Slack App is not easy, as it is not called interactively – if things go wrong, you don’t really know where things failed (in the Slack client? In the interaction with Slack? Within your script?). I use an “interactive” flag in my script $interactive=0; and put some hard coded settings into the script to generate output even if I call the script directly in the browser:

if ($interactive == 1) 
    {
    $command = "/cancel";
    $display_name_of_current_user = "Frank Dux";
    }

However, this only helps a bit. It can help to build up a string of debug information along the way (inside your script) and push that back to Slack as well:

if ($debug == 1) { $message = $debugstring . " - Message:" . $message;}
$data = array(
	"text" => $message
);

And this is it. You can publish your App to the public Slack directory if needed, but that’s another story. For now it should be sufficient that you enhanced the Slack functionality within your Slack user base.

Leave a Reply

Your email address will not be published. Required fields are marked *