Slack channel
Allows to create conversational bots for Slack messenger.
Built on top of Slack Bolt SDK library.
How to use
1. Include Slack dependency to your build.gradle
implementation("com.just-ai.jaicf:slack:$jaicfVersion")
Replace $jaicfVersion
with the latest version
2. Use Slack request
and reactions
in your scenarios’ actions
action {
// Slack incoming request types
val command = request.slack?.command // if slash command was received
val event = request.slack?.event // if some event was received
val action = request.slack?.action // if button was clicked
// Use Slack-specified response builders
reactions.slack?.respond(listOf(
ActionsBlock.builder().build(),
ContextBlock.builder().build(),
FileBlock.builder().build(),
ImageBlock.builder().build(),
InputBlock.builder().build(),
RichTextBlock.builder().build(),
SectionBlock.builder().build(),
DividerBlock()
))
// Or use standard response builders
reactions.say("Hello there!")
reactions.image("https://address.com/image.jpg")
reactions.buttons("Hi", "Bye")
}
Learn more about SlackReactions and Slack layout blocks.
Note that this Slack implementation uses Events API meaning that each response builder method actually sends a reply to the user.
3. Create Slack app with Bots feature enabled
Open your Slack apps and create a new one. Enable Bots feature for it. Copy a Bot User OAuth Access Token from OAuth & Permissions page and Signing Secret from Basic Information page of your app.
4. Run Slack channel
Using JAICP
For local development:
fun main() {
JaicpPollingConnector(
botApi = helloWorldBot,
accessToken = "your JAICF project token",
channels = listOf(
ActionsFulfillmentDialogflow
)
).runBlocking()
}
For cloud production:
fun main() {
JaicpServer(
botApi = helloWorldBot,
accessToken = "your JAICF project token",
channels = listOf(
ActionsFulfillmentDialogflow
)
).start(wait = true)
}
Using Ktor
fun main() {
embeddedServer(Netty, 8000) {
routing {
httpBotRouting("/" to SlackChannel(
helloWorldBot,
SlackChannelConfig(
botToken = "Bot User OAuth Access Token",
signingSecret = "Signing Secret"
)
))
}
}.start(wait = true)
}
Using Spring Boot
@WebServlet("/")
class SlackController: HttpBotChannelServlet(
SlackChannel(helloWorldBot, SlackChannelConfig("Bot User OAuth Access Token", "Signing Secret"))
)
5. Setup permissions and callback URLs
Obtain a public URL for your webhook (using ngrok for example) and copy it to clipboard. Go to the Slack app page and setup callback URL on Event Subscriptions, Slash Commands and Interactivity & Shortcuts pages.
Setup all required permission scopes on OAuth & Permissions page:
- app_mentions:read
- chat:write
- commands
- im:history
- users.profile:read
You can also add more scopes you need.
Please learn more about Slack scopes here.
Reinstall the app to your workspace if needed.
Slash commands usage
To react on slash commands from your scenarios, you have to add regex
activator with corresponding slash command pattern:
state("mew") {
activators {
regex("/mew")
}
}
Also add RegexActivator
to the activators list of your agent configuration.
Actions usage
You can respond with buttons on users’ requests. By default the click on the button just sends another request to your scenario with the text of the button. If you need to receive another value, you can create buttons this way:
action {
reactions.slack?.buttons(
"Yes" to "/yes",
"Nope" to "/no"
)
}
Or add ActionsBlock
manually:
action {
reactions.slack?.respond(listOf(
ActionsBlock.builder().elements(
ButtonElement.builder()
.text(PlainTextObject("Button text", false))
.value("button value")
.actionId("action-id")
...
.build()
).build()
))
}
Slack events usage
Slack sends events to your agent each time the user writes a query, uses a slash command or when some non-conversational event happens. Your scenario can react on any of these events via event
activator:
state("state1") {
activators {
event("user_typing")
}
action {
val event = request.slack?.event as UserTypingEvent
}
}
You can subscribe to any event Slack supports marked with Events API label.
Once an event was received, request.slack?.event
with payload
becomes available in the action block. You can use this variables to fetch event’s details. See an example above.
To receive events you have to add BaseEventActivator
to the activators list of your agent configuration.
Native Slack API usage
SlackReactions
object provides a direct access to the native SDK interfaces named context
and client
. Using these interfaces you can perform any operations allowed by Slack:
action {
val ctx = reactions.slack?.context
val client = reactions.slack?.client
// Receive users list
val users = client?.usersList(
UsersListRequest.builder().token(ctx?.botToken).build()
)
}
Learn more about available Slack API methods here.
Fetch user’s profile
The most frequently used feature of Slack API in the context of dialogue scenario is fetching the user’s profile. There is a special function provided by SlackReactions
that can be used for this:
action {
val profile = reactions.slack?.getUserProfile(request.clientId)
}
Learn more about user profile interface here.
Composing responses
You can use both standard response builders and native Slack builder to compose responses in your scenarios.
Native builder usage
SlackReactions
provides a respond
function for native response building:
action {
reactions.slack?.respond(
listOf(
ActionsBlock.builder().build(),
ContextBlock.builder().build(),
FileBlock.builder().build(),
ImageBlock.builder().build(),
InputBlock.builder().build(),
RichTextBlock.builder().build(),
SectionBlock.builder().build(),
DividerBlock()
)
)
}
Learn more about available Slack layout blocks here.