Skellington-Closet / skellington

:sparkles::skull::sparkles: The skeleton for your bots
MIT License
64 stars 6 forks source link

Examples with AWS Lambda + API Gateway? #46

Closed zeroasterisk closed 7 years ago

zeroasterisk commented 7 years ago

Hosting bots on AWS Lambda + API Gateway is the current hotness, but I really like a lot of your framework's tooling.

Do you have advice or perhaps examples of configuring the code to work via various AWS Lambda invocations?

Ref: https://aws.amazon.com/blogs/aws/new-slack-integration-blueprints-for-aws-lambda/ https://aws.amazon.com/blogs/compute/create-and-deploy-a-chat-bot-to-aws-lambda-in-five-minutes/

colestrode commented 7 years ago

Hey @zeroasterisk 😄 Thanks for checking out Skellington! Lambda and API Gateway have been interesting to me, but I haven't tried to host a bot there yet. It seems like a really natural fit for a Slack App. I could try to play with it later this weekend and see if I can get anything running. Feel free to use this issue as a running set of notes if you wanna try it out too 😄

You should be able to use a Lambda to receive events from outgoing webhooks, slash commands, and the events API without an issue and you can respond using the Web API. But because of the ephemeral nature of a Lambda, you'll run into two problems: the RTM API and conversations.

I see a few issues with the RTM API. RTM only really works with one long running process (or several behind a websocket load balancer), so isn't suited for Lambda. RTM opens a persistent websocket connection, and I'm not sure how that will interact a Lambda; my guess is it would cause the Lambda process to continue to run after whatever HTTP request woke it up has been responded to. So you'll end up with a long running process defeating the purpose of using Lambda 😄 It may be that the websocket connection won't block the Lambda from tearing down, in which case you'll end up with a non-zero amount of time that your Lambda bot will respond to RTM messages (for all connected teams). If you were to end up with multiple Lambdas running at once, you will get multiple responses for each event.

Either way, You'll want to disable to the RTM API. This is a bit tricky since at the moment Skellington will automatically initiate an RTM connection after the OAuth flow completes (for new teams) or when the app is spun up (for previously authenticated teams).

In the longer term, I should probably add an option to disable RTM connections for cases like this (scaling bots using the RTM API is very difficult relative to the HTTP APIs). In the short term, you can add a plugin with a botConnected callback that calls bot.closeRtm. Make that the first plugin in your plugins array and that should prevent the subsequent listeners you add from picking up RTM events.

The second issue is conversations: because Botkit holds conversation state in memory instead of persisting it like Slapp, you won't be able to write conversation interactions using Skellington in Lambda. I'm thinking of supporting separate bot engines in Skellington 2.0, mostly for this reason, but I have also heard that Botkit is thinking of moving conversations out of memory in the future.

Other than those two things, I believe everything should work in Lambda and API Gateway.

colestrode commented 7 years ago

I filed #47 to make RTM connections optional for Slack Apps.