“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 gem/library dependency.
- 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_CREDENTIALS_SSMPS_PATH: hierarchy path to System Managers Parameter Store; e.g.,/slack/credentials/would reference two parameters:/slack/credetials/signing_secret/slack/credetials/bot_access_token
MOSEISLEY_HANDLERS_DIR: optional, if other than./handlersMOSEISLEY_LOG_LEVEL: optional, could beDEBUG,INFO,WARN, orERRORSLACK_LOG_CHANNEL_ID: optional, if you want to useME::SlackWeb.post_log()
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'
def lambda_handler(event:, context:)
MosEisley::lambda_event(event, context)
endCreate 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.
Create your own Mos Eisley handlers as blocks and register them. By default, store these Ruby files in the handlers directory. Add handlers by passing a block to MosEisley::Handler.add() for the types below.
:action
:command_response
:command
:event
:menu
:nonslack:command_response types are Slack command keyword and response pair. The response is sent as-is back to Slack as an immediate response. ME is an alias to MosEisley.
ME::Handler.add(:command_response, '/sample') do |event, myself|
{
response_type: "in_channel",
text: "_Working on `#{event[:command]}`..._",
}
endAdd 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)
endIf your function receives non-Slack events, you can add handlers for that as well.
ME::Handler.add(:nonslack, 'A CloudWatch event') do |event, myself|
next unless event['source'] == 'aws.events'
myself.stop
channel = 'C123SLCK'
txt = 'Shceduled event was received.'
ME::SlackWeb.chat_postmessage(channel: channel, text: txt)
endMosEisley::S3PO– collection of helpers to analyze/create Slack messages.MosEisley::SlackWeb– methods for sending payloads to Slack Web API calls.
To an incoming Slack event, Mos Eisley will quickly respond with a blank HTTP 200. This is to keep Slack's 3-second rule. To do this, handlers are not called yet, but the Slack event is passed on to a recursive asynchronous invoke and then the handlers are called.
The exception is when the incoming Slack event is for a slash command. You can define :command_response handlers for the purpose of generating a simple response message, but nothing more.
sequenceDiagram
participant S as Slack
participant L as Lambda MosEisley
S->>+L: Slack event via API Gateway
alt Slash command
L-->>S: Response message
Note left of L: If a response handler is defined
else All other events
L-->>-S: HTTP 200 (blank)
end
L->>+L: Slack event
Note right of L: Handlers are called
opt
L-->>-S: E.g., chat.postMessage
end
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'