Slack Interaction Routing using Django resolvers

Developing a integration for Slack is not easy task. Slack’s API is pretty great and allows a lot of freedom. But when you start adding buttons, integrations and, more recently, interactions with blocks your code will quickly become a never-ending list of if/the/else clauses.

While developing integrations the new slack interactions we were writing were becoming unmangeable. For every new button there would be a new if block_id == "feedback-button" so new solutions needed to be found.

The best one was using Django’s routing mechanism to treat the interactions as urls on a website. Once this mindset was introduced everything became much easier. Let’s start with some examples. First the main methods that make this possible:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def slack_resolver(url: str) -> ResolverMatch:
for urlconf in settings.SLACK_URLCONFS:
# try the various urlconf files we have
try:
resolver = resolve(url, urlconf=urlconf)
return resolver
except Resolver404:
continue
raise Resolver404()

def slack_reverse(viewname, args=None, kwargs=None):
for urlconf in settings.SLACK_URLCONFS:
try:
return reverse(viewname, urlconf=urlconf, args=args, kwargs=kwargs)
except NoReverseMatch:
continue
raise NoReverseMatch(f"Reverse for {viewname} not found: args: {args}, kwargs: {kwargs}")

As the method signatures show the slack_resolver method receives the current url being processed and return the resolver to call the view’s function.

The other method slack_reverse makes sure we can pass a Django url name and get a url back.

The next step is just to defined url using Django’s urlpatterns . An example could be:

block_urls.py

1
2
3
urlpatterns = [
path("actions", onboarding_actions, name="onboarding-actions"),
]

onboarding_actions is a simple function that returns JSON formatted for Slack.

This approach really sped up development on Slack and made our code be much less problematic.

Testing this approach is also much simpler.

There are some other nuances that weren’t mentioned here. If you have any questions at all you can email me.