- Our user ‘Cartman’ types “@pokebot abosol’s abilities” into a group channel on Slack. I chose the name Cartman simply because the user graphic I found online reminded me so much of Cartman from South Park. Abosol is the name of a pokemon and they all have different abilities…didn’t you know that Daddy ???!!!.
- We have to assume this is a busy group channel so we don’t want every comment going to our bot since most will be us humans talking amongst ourselves. The Slack Events API sends a notification to our application only because Cartman mentioned @pokebot. Cartman could also have invited our bot to a Direct Message channel strictly between him & the Pokebot. In this case all messages go to our bot regardless of whether @pokebot is mentioned or not.
- The Slack Events API sends Cartman’s message to an HTTPS endpoint exposed by our application along with other details like Cartman’s user id and the channel the message was created-in. Our Gateway microservice is listening for any POST requests to that endpoint. The Gateway unpacks the HTTPS message and then broadcasts a ‘message.created’ event onto a “Messages” topic. Note that the events API does NOT expect you to send the bot’s response straight back. Our system is asynchronous and we respond to another API — the Slack Web API when our response is ready to send. Decoupling request and response this way gives us and Slack much greater flexibility that means we dont have to deploy super computers capable of handling all that Cartman wants to know in
- Our Controller service is listening for events on the Messages topic. When it receives one it passes Cartman’s message to the Pokebot service using an HTTPS request. For MVP our Pokebot isn’t going to be using any world-beating Machine Learning and I could have easily not created a Pokebot service but coded the logic for the bot directly into the Controller. I’ve architected it this way because I’d like the option of replacing our simple bot some day with a much smarter chatbot. Almost certainly that smarter bot will be written in Python such as RASA and will only be able to respond to HTTPS requests rather than serverless topics. With this architecture I can easily swap out one bot for another. I could have written our simple Pokebot in Ruby but this is (I hope) a fun microservices tutorial so let’s mix-up our tech a bit.
- The Pokebot receives Cartman’s message from the Controller via an HTTPS request. It unpacks the message to determine which Pokemon Cartman wants to know about and what he wants to know. The Pokebot then calls the free Pokeapi to get the information that Cartman wants and returns that to the controller. The controller then emits an “response.created” message onto the responses topic.
- The responder lambda is listening to the responses topic. It picks up our response.created message and writes that back to the channel the message was created in in Slack using the Slack Web API.
- There is also a Recorder lambda also listening for events on the responses topic. This lambda simply saves the event data to amazon S3 as a json object so we have a complete record of our application’s journey.
That’s the app. If you’d like to build it then the next steps are to setup AWS, Slack and the serverless.com tools.
As you’ve probably gathered by now we like building bots. If you get a few minutes you could really help us by answering this short survey about what’s good and bad about being a developer. We’d like to build a bot that helps with the bad.
The Pokebot Tutorial is a work in progress that I hope to complete by end of 2020. Thank you for reading & feel free to reach out, Steve Creedon.
- Building a serverless, event-driven slack pokebot.
- What does a Pokebot look like ?
- Setting up for Slack, AWS and serverless.
- Build the gateway lambda
- About Messaging
- Build the controller and response services then DRY them up.
- Build the Poké-service see the app running
- Add the Responder service.