Ok so recently I was chatting on a slack, mostly sharing cat pictures, when I realized the CarGurus slack account did not have a /cat command. I knew immediately, this had to change!

So my vision was simple, write /cat in slack and a random cat appears! Slack has native functionality to extend the slash commands. You can find the custom integrations by clicking on your slack workspace name, and clicking customize slack. Then you can do a search for slash commands.

a screen shot of the slack UI for adding a slash command

So anyway, slash commands will call an http endpoint with either a POST or get. For mine I chose post. They expect a response within 300ms, so not a lot of time! However in the post data slack provides a URL you can post back to with your response. That URL can be used for 3 seconds tons of time for an api.

So I found this api which returns you a url of a random cat photo. Obviously, my first reaction was to just call it and paste the response in slack. Unfortunately slack expects messages to come back in a specific json format.

My first reaction was to make a azure function, when called from http will call the random.cat api, and then shape the data correctly for slack. Even though that is not much code, its certainly more work than I was willing to put in on a lunch break project.

Then I remembered azure logic apps poor choice of name, but the demo I saw a year ago looked interesting. Ok, so this is basically like if-this-then-that but more for developers. You can do all kinds of cool stuff with it, like trigger when a file is written to storage, and call a workflow of other serverless functions.

In my case I started out with the http trigger. I made a parallel branch. The first branch returns an 200 status code back to the caller. This is because slack requires a response within 300ms. The second branch I added a http call to the random cat api, a parse json function to parse the results, and then another http call back to slack with the proper data. The Url to the slack api is a function call to triggerFormDataValue('response_url') which will parse out the response url from the posted data to our function’s trigger. I called the slash command and huzzah! I got an image of a cat!

an image of a cat from the random cat slash command

Here is a quick view of my logic app workflow.

a screen shot of a logic app workflow in azure

The code view of my logic app looks like the following. The whole thing was pretty easy, and I did it over my lunch break!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"HTTP": {
"inputs": {
"method": "GET",
"uri": "http://aws.random.cat/meow"
},
"limit": {
"timeout": "PT1S"
},
"runAfter": {},
"type": "Http"
},
"HTTP_2": {
"inputs": {
"body": {
"parse": "full",
"response_type": "in_channel",
"text": "@body('Parse_JSON')?['file']",
"unfurl_links": true,
"unfurl_media": true
},
"headers": {
"Content-Type": "application/json"
},
"method": "POST",
"uri": "@{triggerFormDataValue('response_url')}"
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Http"
},
"Parse_JSON": {
"inputs": {
"content": "@body('HTTP')",
"schema": {
"properties": {
"file": {
"type": "string"
}
},
"type": "object"
}
},
"runAfter": {
"HTTP": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Response": {
"inputs": {
"statusCode": 200
},
"kind": "Http",
"runAfter": {},
"type": "Response"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
}
}