Why I entered the Hackathon
I was recently certified as an Amazon Web Services, Certified Solutions Arthitect (Associate), and began working on the Certified Developer certification. In addition, I began learning AWS Lambda since the certifications do not currently cover AWS Lambda. So, when I saw this hackathon, I thought it was a great way to get "real-life" hands-on practice with AWS Lambda and DynamoDB.
Inspiration for BusyBeeBot
Slack is used by a lot of organizations. Most of these organizations have busy individuals, who we will affectionally call "busy bees". It is easy to be so involved in the work that we sometimes don't take notice of how we feel. If we're feeling good, it's nice to realize that. If we're feeling not-so-good, it's nice to try to fix that. BusyBeeBot asks, inspires, and tracks.
What BusyBeeBot does
BusyBeeBot is a Slack App that asks users how they’re feeling and, if needed, provides motivational quotes based on their responses. BusyBeeBot will remind users daily to check-in, but users may choose to answer the questions at a later time, or multiple times a day if desired. Responses are stored, allowing users to generate a report on demand.
How I built BusyBeeBot
- Code is written in Java 8.
- Code uses Maven for dependencies and building jars.
- Slack commands call endpoints provided by AWS API Gateway which then routes the "Integration Request" to the appropriate AWS Lambda function.
- Code is deployed as AWS Lambda functions. There are 6 functions in total for:
- handling authentication
- handling events sent from the Events API
- handling the /checkin slash command
- handling the /beereport slash command (generates a report)
- handling interactive messages (the actual questions with the "yes/no" buttons)
- checking the users to see who should get a reminder and sending a reminder through Slack (please note that this is a scheduled job and doesn't need to interact with API Gateway)
- AWS DynamoDB is used for all persistence of raw data (e.g. Slack credentials, user responses, tracking of reminders sent, etc.)
- There is a Slack app which includes
- a bot user named BusyBeeBot
- a few relevant slash commands (/checkin and /beereport)
- incoming webhooks
- use of the Events API
- use of the Web API
- AWS S3 is used to store the installation web page, and user reports in CSV format.
- AWS Route53 is used to register a domain name and point to the web page hosted in AWS S3.
- AWS CloudWatch is used heavily indirectly by these services, and was used a lot for checking logs and performance.
Challenges I ran into
I'll preface this by saying that I used to be a strong Java developer but am a little rusty now. So my goals with this project were to (a) refresh my Java skills and use Java 8 (b) do a real-life example using AWS Lambda and DynamoDB as I prepare for the AWS Certified Developer Associate exam (c) develop something fun or useful.
The challenges I ran into were:
- Hands on experience with Java 8 - I haven't coded in Java in years and then it was Java 5. I frequently reverted to Groovy on Grails conventions while coding the Java. Thankfully, the IDE will warn you pretty quickly.
- A lot of the AWS Lambda examples were not in Java. I don't know Node.js or Python. Though I will likely learn them someday, I didn't have enough time right now, plus Java was my goal. There weren't even any AWS Lambda blueprints in Java. So coding this wasn't as fast as I'd hoped. But the next one should be faster. :-)
- API Gateway can be tricky to use. I was pre-warned but I experienced it for myself.
- Slack provides a lot of good documentation, but their API is very inconsistent. Sometimes it's a GET, sometimes it's a POST, sometimes the JSON is in the body, sometimes the JSON is an encoded string sent as one payload string, sometimes you can override the channel but other times you cannot, etc. etc. However, I found the Slack support team to be extremely helpful when I had issues or questions.
- The Slack portions took much longer than I anticipated for the reasons stated above.
- AWS Lambda cold-start issues. This is by far the biggest challenge. I had read about the cold-start issues, and they can be pretty bad. At times I saw executions times of over 12 seconds (but once the code was running, the execution times were typically in the microseconds). The worse part about this is that Slack has a 3-second timeout, and that cannot be changed. While a 3-second timeout is not a bad thing, it led to very confusing/frustrating issues while using the app. Sometimes you'll get a Slack message saying "Darn" (but then the real app message would come shortly thereafter). Sometimes you'd see duplicate posts from the app because Slack retries on failure. Sometimes there were other confusing things that happened. I have tried numerous things to solve this issue, and I'm not sure it wont happen. I considered not submitting due to this issue, but decided to submit anyway. Should you see a timeout issue, please give it a second or two, and the response should still show.
Accomplishments that I'm proud of
- I actually had so many issues at the beginning trying to get an end-to-end example working, but didn't give up.
- I found some showstoppers within the last 3 days of the hackathon, and though I was starting a new job and fighting a cold, I had to rewrite a good portion of the code.
- One of my testers said "BusyBeeBot makes me feel better about not feeling good".
What I learned
- A whole lot about Slack APIs.
- Nitty gritty details of AWS Lambda, API Gateway, DynamoDB, etc.
- That though AWS Lambda seems like it should be about microservices, as long as cold-start issues remain, I'll use as few Lambda functions as possible so that there are fewer functions that can run cold (I'd actually rewrite my code now for that but ran out of time).
What's next for BusyBeeBot
- Once timeout issues are confirmed to be resolved, I will submit this to the Slack app directory.
- I want to integrate Natural Language Processing, for the experience.
- My existing users and I have discussed some enhancements, such as letting the user pick their notification time, using a quotes API to get more quotes, and more.