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.conf
config (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.
<?phpreturn [
'slack_report' => env('SLACK_TOKEN_FEATURE_FOO', '12345'),
];