You have access to a webserver but need someone to slack? Maybe this is your chance: Build your own Slack-Bot!
Structure
Beneath the webserver hosting 3 php-scripts there’s not much you need:
- For an AI to respond to your chat-messages: Create an OpenAI API Key
- For structured communication, write 3 php-scripts (or just clone my repo):
– The 1st one, secrets.php, stores all IDs and API-Keys you need,
– the 2nd, response.php, is for installing the new App into your Slack workspace only and
– the 3rd, slackChat.php, does all the work receiving an writing chat messages. - For the communication from and to your Slack-Workspace: Your Slack-App
OpenAI API-Key
Starting with the easy part getting into flow, you only need to set up a new OpenAI-Account, if you don’t already have one, and create a new API-Key (left side menu: API keys > “+ Create new secret key”). Don’t forget setting “Usage limits” at Settings > Limits, avoiding surprises on your bank account when someone finds and uses your API key.
PHP scripts: secrets.php
Just a few lines of code you should write via editor, maybe Visual Studio Code or just Notepad, into a file called “secrets.php” and store it in a safe path on your webserver.
At this moment you can only fill in the OpenAI API-Key. The values for the other variables will be generated creating and configuring your Slack-App.
<?php
$api_key = "sk- ..."; // Your OpenAI API key
$clientId = '...'; //In your App: Settings > Basic Information > App Credentials
$clientSecret = '...'; //Your App: Settings > Basic Information > App Credentials
$slackToken = 'xoxb-...'; //Your App: Features > Basic Information > App Credentials
$verificationToken = '...'; //Your App: Settings > Basic Information > App Credentials
?>
Please take care about the security especially of this one: None of this infos should be known by anyone else but you.
PHP scripts: response.php
This one is only for adding your new Slack-App to your Workspace(s), so in best case you can delete it after one use having added your app to your Workspace successfully.
<?php
require_once '\SECRET PATH\secrets.php';
$code = $_GET['code']; // The authorization code Slack sends as query parameter
// Exchange the authorization code for an access token
$url = 'https://slack.com/api/oauth.v2.access';
$data = http_build_query([
'client_id' => $clientId, #Your Apps Client ID
'client_secret' => $clientSecret, #Your Apps Client Secret
'code' => $code
]);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => $data
]
]);
$response = file_get_contents($url, false, $context);
if ($response === false) {
echo "Error during the OAuth process";
} else {
$responseArray = json_decode($response, true);
if (isset($responseArray['access_token'])) {
echo "Authorization successful";
} else {
echo "Authorization failed";
}
}
?>
PHP scripts: slackChat.php
Now the most important piece of code. There are many things to change and configure here but first start with this and place this code within slackChat.php on the webserver.
<?php
require_once '\SECRET PATH\secrets.php';
// Function to send a message to ChatGPT and get a response
function chatGptResponse($messageText) {
global $api_key;
$curl = curl_init('https://api.openai.com/v1/chat/completions');
$postData = json_encode([
'model' => 'gpt-4-turbo-preview', // Choose the model you'd like to use
'messages' => [
["role" => "system", "content" => "You are a helpful assistant."],
["role" => "user", "content" => $messageText]
],
'temperature' => 1.0,
]);
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $api_key,
],
]);
$response = curl_exec($curl);
curl_close($curl);
$decodedResponse = json_decode($response, true);
// Extracting the text from the ChatGPT response
return $decodedResponse['choices'][0]['message']['content'] ?? 'Sorry, I could not process that.';
}
// Function to post a message back to Slack
function postToSlack($channelId, $messageText) {
global $slackToken;
$curl = curl_init('https://slack.com/api/chat.postMessage');
$postData = http_build_query([
'channel' => $channelId,
'text' => $messageText,
]);
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $slackToken,
'Content-Type: application/x-www-form-urlencoded',
],
]);
$response = curl_exec($curl);
curl_close($curl);
}
// Main logic to handle Slack events
$content = file_get_contents("php://input");
$event = json_decode($content, true);
// Token verification
if (isset($event['token']) && $event['token'] !== $verificationToken) {
http_response_code(403); // Forbidden
echo 'Invalid verification token.';
exit;
}
if ($event['type'] === 'url_verification') {
echo $event['challenge'];
exit;
} elseif ($event['type'] === 'event_callback') {
// Check for the specific channel ID before proceeding
//if ($event['event']['channel'] !== 'CHANNEL ID') { // Activate this, if you want only to react on events of the specified channel
//exit;
//}
// Ignore messages from bots, including your own bot's messages
if (isset($event['event']['subtype']) && $event['event']['subtype'] === 'bot_message' || isset($event['event']['bot_id'])) {
return; // Ignore bot messages entirely
}
$channelId = $event['event']['channel'];
$userMessage = $event['event']['text'];
// Avoid responding to messages not containing text or other bot messages
if (empty($userMessage) || isset($event['event']['bot_id'])) {
return;
}
// Get response from ChatGPT
$chatGptResponse = chatGptResponse($userMessage);
// Post response back to Slack
postToSlack($channelId, $chatGptResponse);
}
?>
Slack App
Now we can put it all together. But first: Let’s create a Slack App!
Just open https://api.slack.com/apps, click “Create New App” and give it a name like “ChatBot” for example.
Now we have to do some configuration: But first: Don’t opt in for token rotation!
- token rotation is not revertable when set for this app and this example won’t work with token rotation.
- At Features > OAuth & Permissions > Redirect URLs we have to Add New Redirect URL and paste the path to our response.php, e.g. https://www.scrummastersmind.com/php/response.php, saving the added redirect URL.
- At Features > OAuth & Permissions > Scopes you should add “channels:history” and “chat:write” as Bot Token Scopes as well as User Token Scopes via button “Add an OAuth Scope”.
- At Features > Event Subscriptions we will “Enable Events” first. Then
- at Features > Event Subscriptions > Enable Events we can now add the path to our slackChat.php as Request URL, e.g. https://www.scrummastersmind.com/php/slackChat.php. Next
- at Features > Event Subscriptions > Subscribe to events on behalf of users we can configure an event in our Slack Workspace to react on calling our php:
Clicking “Add Workspace Event” we can add “message.channels”, so every time a user posts a message in one of our workspaces channels our app will react calling our slackChat.php. - At Settings > Manage Distribution click on the “Add to Slack” button adding you new app to your Slack workspace. Clicking the “Verify”-button Slack will call our response.php showing “Authorization successful” in best case.
- Now you can delete response.php from the webserver. It’s purpose was to add the App to your Slack workspace.
- Last but not least we can fill in the remaining variables in our secrets.php:
$clientId, $clientSecret and $verificationToken can be found at Setting > Basic Information > App Credentials and $slackToken at Features > OAuth & Permissions > Bot OAuth Token, all within your new Slack App.
If you choose the User OAuth Token instead your Slack-Bot will answer as user instead of answering as bot.
Slack Time
Now the work is done and you can have fun using your new Slack-Bot!
Especially you could try restricting your bot to just one channel, see the comment in the code of slackChat.php. You will find the Channel ID in the Channel-Details of each of your Slack workspaces channels.
You could also re-define the bots initial instruction “You are a helpful assistant.” making it more specified on your purposes.
There are thousands of more things to find out!
Feedback
If you have any comments, ideas, suggestions or other feedback about this article, feel free to send me an email at Feedback[at]scrummastersmind.com.