mos-eisley-lambda
“You will never find a more wretched hive of scum and villainy.” – Obi-Wan Kenobi
Episode 2 of the Ruby based Slack app framework, this time for AWS Lambda. Pure ruby, no external dependency.
Setup
AWS
- Create an SQS queue for MosEisley
- Create an IAM role for MosEisley Lambda function
- Create a Lambda function for MosEisley
- You can install this gem using Lambda Layer or just copy the
libdirectory to your Lambda code.
- You can install this gem using Lambda Layer or just copy the
- Create an HTTP API Gateway
- Create the appropriate routes (or use the OpenAPI spec)
- Create Lambda integration and attach it to all the routes
Configure Lambda environment variable.
SLACK_SIGNING_SECRET: your Slack app credentialsSLACK_BOT_ACCESS_TOKEN: your Slack app OAuth tokenMOSEISLEY_SQS_URL: AWS SQS URL used for the event pipelineMOSEISLEY_LOG_LEVEL– optional, could beDEBUG,INFO,WARN, orERROR
Configure Lambda code in your lambda_function.rb file.
require 'mos-eisley-lambda'
# Or, you can just copy the `lib` directory to your Lambda and...
# require_relative './lib/mos-eisley-lambda'
MosEisley::Handler.import
# Or, if you store your handlers in a non-default location, dictate by...
# MosEisley::Handler.import_from_path('./my-handlers')
def lambda_handler(event:, context:)
MosEisley::lambda_event(event)
end
Slack
Create a Slack app and configure the following.
- Interactivity & Shortcuts – Request URL should be set to the
/actionsendpoint and Options Load URL should be set to the/menusendpoint. - Slash Commands – Request URL should be set to the
/commandsendpoint. - OAuth & Permissions – This is where you get the OAuth Tokens and set Scopes.
- Event Subscriptions – Request URL should be set to the
/eventsendpoint. You'll likely Subscribe to bot eventsapp_mentionat a minimum.
Handlers
Create your own Mos Eisley handlers as blocks and register them. By default, store these Ruby files in the handlers directory.
ME::Handler.command_acks holds [Hash<String, Hash>] which are Slack command keyword and response pair. The response is sent as-is back to Slack as an immediate response.
ME::Handler.command_acks.merge!({
'/command' => {
response_type: 'in_channel',
text: '_Working on it…_',
},
'/secret' => {
response_type: 'ephemeral',
text: '_Just for you…_',
},
})
Add handlers to process the Slack event.
ME::Handler.add(:command, 'A Slack command') do |event, myself|
next unless event[:command] == '/command'
myself.stop
txt = "Your wish is my command."
payload = {
response_type: 'ephemeral',
text: txt,
blocks: [ME::S3PO::BlockKit.sec_text(txt)],
}
ME::SlackWeb.post_response_url(event[:response_url], payload)
end
Protocols
SQS
- Attributes
source:slack,moseisley, or otherendpoint: if source isslack, which endpoint it arrived atdestination:slackormoseisleyapi: if destination isslack
- Message (JSON)
params: object, meant to be passed to Slack APIpayload: the data/payload itself
Helpers
ME::S3PO– collection of helpers to analyze/create Slack messages.ME::SlackWeb– methods for sending payloads to Slack Web API calls.
Event Lifecycle
Inbound
- Slack event is sent to Mos Eisley Lambda function via API Gateway
- Slack event is verified and returned with parsed object
- If it's a slash command, MosEisley::Handler.command_acks is referenced and immediate response is sent
- The original Slack event JSON is sent to SQS with attributes
Event Processing
- Slack event is recieved by SQS trigger
- Handlers are called and processed according to original endpoint the event was sent to; actions, commands, events, menus
- Should send a Slack message to complete the event cycle
Using with Lambda Layers
Used the Makefile to create a zip file which can be uploaded to a Lambda Layer.
make
# Installs the gem to './ruby' then archives it to 'lambda-layers.zip'