Before you begin, make sure to setup your LambdaSharp CLI.
An invocations schedule is created by adding a Schedule source to each function. The schedule can either be directly a CloudWatch Events schedule expression or it can provide an expression and a name. The Name attribute is used to distinguish between multiple schedule events when needed.
A Slack command integration is created by adding the SlackCommand source to a function. The LambdaSharp CLI automatically generates the API Gateway scaffolding including resources, methods, stages, and a RestApi deployment. In addition, the Slack command requests are converted into asynchronous invocation to avoid timeout errors for slow functions. Additional details on the Slack Command integration can be found below.
Module: Sample.SlackCommand
Description: A sample module integrating with Slack
Items:
- Parameter: SlackToken
Description: Slack verification token
Scope: MyFunction
Default: ""
- Function: MyFunction
Description: This function is invoked by a Slack command
Memory: 128
Timeout: 30
Sources:
- SlackCommand: /slackThe following AWS Lambda function derives from the ALambdaSlackCommandFunction base class. The base class deserializes the request into a SlackRequest instance. In addition, standard output is captured by the base class and sent in response to the request. In case of an exception, the stack trace is sent back as an ephemeral response, which is only visible to the invoker of the Slack command.
public sealed class Function : ALambdaSlackCommandFunction {
//--- Methods ---
public override async Task InitializeAsync(LambdaConfig config) {
// TO-DO: add function initialization and reading configuration settings
}
protected override async Task ProcessSlackRequestAsync(SlackRequest request) {
// TO-DO: add business logic
Console.WriteLine("Hello world!");
}
}In order to invoke the Sample API, we need to know the URL. The easiest way is to copy the API Gateway base-URL from the LambdaSharp CLI output after the deployment has completed and append the resource URL path.
Copy the complete URL to the API Gateway endpoint and follow these steps:
- Select Customize Slack from your Slack client.
- Click Configure Apps.
- Click Custom Integrations.
- Click Slack Commands.
- Click Add Configuration.
- Enter
SlackCommandSampleas command. - Click Add Slash Command Integration.
- Paste the API Gateway URL into the appropriate box.
- Click Save Integration.
- Go back to your Slack client.
- Click on
slackbot. - Type
/SlackCommandSampleand hit ENTER.
If all went well, you should see Hello World! as response (which may take a few seconds).
The Slack integration converts the Slack form post into a JSON data structure that is deserialized by the ALambdaSlackCommandFunction base class.
public class SlackRequest {
//--- Properties ---
public string Token { get; set; }
public string TeamId { get; set; }
public string TeamDomain { get; set; }
public string EnterpriseId { get; set; }
public string EnterpriseName { get; set; }
public string ChannelId { get; set; }
public string ChannelName { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string Command { get; set; }
public string Text { get; set; }
public string ResponseUrl { get; set; }
}The payload transformation occurs in the API Gateway Method Request. As part of the Slack integration, the API Gateway endpoint must be configured as asynchronous by injecting the X-Amz-Invocation-Type custom HTTP header with the value 'Event'. Making the invocation asynchronous avoids timeout errors in Slack when the Lambda function is slow to respond. The actual payload transformation is done using an Apache Velocity template. The template converts the form URL-encoded payload into a JSON document.
{
#foreach($token in $input.path('$').split('&'))
#set($keyVal = $token.split('='))
#set($keyValSize = $keyVal.size())
#if($keyValSize == 2)
#set($key = $util.escapeJavaScript($util.urlDecode($keyVal[0])))
#set($val = $util.escapeJavaScript($util.urlDecode($keyVal[1])))
"$key": "$val"#if($foreach.hasNext),#end
#end
#end
}
Since the API Gateway endpoint is asynchronous, the API Gateway Method Response must provide a default, valid JSON response. An empty response message is accepted by Slack without any visible output.
{
"response_type": "in_channel",
"text": ""
}