Simple Slack Trait for taking Requests and returning Responses

This is something we have been doing a lot for a team I am on, and I feel that Laravel 5.4 Slack feature might be more than I need in most cases like this one. The Laravel implementation seems more about notifications to users and not so much about just taking and / or sending a message to Slack.

In this example I get a message from Slack (but this can be any message) and then send results back to Slack.

One thing to keep in mind you really want to get your code working out side of Slack since you cannot easily do a push, test, fix, push, test as we normally do when working locally with a browser.

Get your PHPUnit working for a class that will handle the payload, then you know when you plug it in to the Slack Route it will “just work”.

More on that shortly…

Getting a message

Going with the POST settings we will setup Slack to send a POST request to a URL we are building.

So I will show some tests first here and then trait here

We have a few features going on to consider

All of which I use this fixture to replicate the incoming Slack Message

[
{"token": "foo"},
{"team_id": "bar"},
{"team_domain": "baz"},
{"channel_id": "C0JKRSDEV"},
{"channel_name": "test"},
{"user_id": "U02NC4UL2"},
{"user_name": "alfrednutile"},
{"command": "/hp:report"},
{"text": "not really needed yet"},
{"response_url": "https://hooks.slack.com/commands/foo/bar/baz"}
]

see here too.

Is this coming from the right token?

testSuccessVerifiesToken and bad testVerifiesToken

see example here

Is this even coming from Slack?

testSuccessSlackURL and testFailWrongURL

see example here

Is this person even allowed to do this?

testSuccessVerifiesPerson see example here

Is there info/text in the incoming message for me to consider

testKeepSheetsAsTrue shows me looking for text.

Again easy stuff to test outside of Slack. here

Okay Now the message is good how to send one back?

The route has to becomes a non-auth and non-basic auth protected route so Slack can POST to it

Here is my nginx default.confconfig (see docs on how to update this using CloudFormation)

location  /api/v1/slack/ { auth_basic "off"; allow all; satisfy any; try_files $uri $uri/ /index.php?$query_string; }

To allow this to happen see the full file here LINK.

Then the route is simple routes/api.php

Route::group(['prefix' => 'v1'], function(){
Route::post('slack/hp_reports', 'RunReportSlackController@handle');
Route::post('slack/hp_user_reports', 'RunUserLevelReportSlackController@handle');
});

The Controller here does as little work as possible.

Though I would like to move these into a Validation

if(!$this->token) {
$this->setToken(env('SLACK_TOKEN_REPORT_REQUEST'));
}
            if($this->notASlackUrl($request)) {
$message = sprintf("Not a Slack URL");
throw new NotSlackUrlException($message);
}

Again the Controller should not have to do too much.

But the logic is outside the controller and which now is outside the scope of the example since at this point we just have, as seen in the fixture above so do what you want with the incoming JSON.

Once done it sends it back to the Controller here to respond back to Slack using respondToSlack seen in SlackTrait.php here

Which simple breaks it up into an array

public function respondToSlack($message, $attachment, $type = 'in_channel')
{
return ['response_type' => $type, 'text' => $message, 'attachments' => [ ['text' => $attachment ] ] ];
}

Attachments in this case just being more text. For our team you can see it when you type /sd behat in Slack. This request goes to our app, looks for the word(s) behat in the docs and replies back to Slack as such

slash-command APP [11:43 AM] 
Your original search slack total found 4
Title: Holiday and other Team Processes URL: https://foo.com/team-managment
Title: Getting Started New to the Team URL: https://foo.com/new-to-the-team
Title: Onboarding Links URL: https://foo.com/onboarding-links
Title: Contract Testing URL: https://foo.com/contracts

“Your original search slack total found 17” is the text and the rest the “attachments”

ENV

One tricky part here is the .env

I am looking for SLACK_TOKEN but this will get old soon if I do a few of these since they all have different tokens. I would suggest an config/slack.php to then have areas for this.

<?php
return [
'slack_report' => env('SLACK_TOKEN_FEATURE_FOO', '12345'),
];