Dialog is a Dialogflow v2 API implementation written in Kotlin. With some great optional extensions you can use to write your own voice application fast.
- Dialogflow V2 API reference implementation written in Kotlin
- Multiplatform support, one service for Alexa and Google Assistant
- Intercepter API for adding e.g. tracking
- Spring reference implementation
- SSML builder for creating rich responses
- Plugin for Konversation to distinct the dialogs from code
A response with a simple response and a basic card would look like this:
return handler.responseBuilder
.expectUserResponse(true)
.withGoogleSimpleResponse(speech)
.withGoogleBasicCard(
title = "CardTitle",
subtitle = "CardSubTitle",
formattedText = "CardFormattedText",
buttons = mutableListOf(
GoogleButton(
title = "ButtonText",
openUrlAction = OpenUrlAction(url = "https://rewe-digital.com/")
)
)
)
.withGoogleSimpleResponse(question)
.withGoogleSuggestions(*suggestions.orEmpty())
Example taken from UiElementsIntentHandler
Here is a list of some selected methods you can use to create the response of your voice application:
askGoogleForCoarseLocation(...)
askGoogleForLocation(...)
askGoogleForPreciseLocation(...)
askGoogleForSignIn(...)
expectUserResponse(...)
withCard(...)
withGoogleBasicCard(...)
withGoogleCarouselSelect(...)
withGoogleLinkOutSuggestion(...)
withGoogleListSelect(...)
withGoogleReprompts(...)
withGoogleSimpleResponse(...)
withGoogleSimpleResponses(...)
withGoogleSuggestions(...)
withImage(...)
withQuickReplies(...)
withText(...)
You can use the core library for you own implementation, where you can choose your own application server or your own server less hosting. In the end you need to setup your rest endpoints yourself and manage the conversion of the POKOs (plain old Kotlin objects).
When you have your request converted to WebhookRequest Dialog can handle the request by using the RequestResolver.
The constructor expects 4 arguments: intentHandlers
, requestInterceptors
, responseInterceptors
and
fallbackAction
. The first three options are lists each of them are explained in more details in the following sections.
The DialogflowIntentHandler is the core where you handle the intents. Each handler can choose independent if it feels responsible for the intent. This is very helpful if you have some intents which depends on the current context.
RequestResolver will call the function canHandleDialogflowIntent(...)
. When your intent feels
responsible return true
then the handleDialogflowIntent(...)
will be called. Please note that
you define the order of the calls with the order of of the RequestResolver
's intentHandlers
. First come first serve,
you should avoid that multiple handlers return true
of the same intent, based your the list implementation the result
could be random.
As said above the RequestResolver will call the handleDialogflowIntent(...)
method if you return
true
in the canHandleDialogflowIntent
method. The logic for handling the Intent goes here. To
create a response use input.responseBuilder
.
You can use the RequestInterceptor for tracking. In onDialogflowRequest()
will get the input where you can grep the
data you need for analytics.
This is a special DialogflowIntentHandler which will be invoked when no intent handler will feel responsible for your
request. Please note that the result of the canHandle
method will be ignored for the fallback usage.
class WelcomeIntentHandler : DialogflowIntentHandler {
override fun canHandleDialogflowIntent(handler: DialogflowHandler): Boolean {
return handler.action?.equals("input.welcome") ?: false
}
override fun handleDialogflowIntent(handler: DialogflowHandler): DialogflowResponseBuilder {
return handler.responseBuilder.withText("Welcome to Dialog!")
}
}
We have a special plugin for Spring which should make it very easy to implement your own webservice with it. You can use
the spring-sample project as template for your own project. When you use our plugin you should annotate each intent with
@IntentHandler
to make that intent handler to a component which provides you all the advantages of dependency
injection. The best it that we use it also for discovering your intent handler automatically. For the fallback intent
you should use the annotation @FallbackIntentHandler
, if it is missing you service won't start up.
You can add the Alexa plugin to build a service which can serve Alexa and the Google Assistant at once. You just have to change your IntentHandler to implement the MultiplatformIntentHandler.
class WelcomeIntentHandler : MultiPlatformIntentHandler {
override fun canHandleAlexa(input: HandlerInput) =
input.matches(Predicates.requestType(LaunchRequest::class.java))
override fun handleAlexa(input: HandlerInput): Optional<Response> {
return input.responseBuilder
.withSpeech("Welcome to Dialog!")
.build()
}
override fun canHandleDialogflowIntent(handler: DialogflowHandler): Boolean {
return handler.action?.equals("input.welcome") ?: false
}
override fun handleDialogflowIntent(handler: DialogflowHandler): DialogflowResponseBuilder {
return handler.responseBuilder.withText("Welcome to Dialog!")
}
}
If you're using Dialog with Spring you can add the alexa-spring-plugin
which will automatically provide a Bean of
IntentHandlerHolder
. This call contains the list of all Alexa RequestHandler
which can be added to the
CustomSkillBuilder
like in the following example.
@Configuration
class AlexaConfig {
@Bean
fun provideSkill(
intentHandlerHolder: IntentHandlerConfig.IntentHandlerHolder,
interceptorHolder: InterceptorConfig.InterceptorHolder
): Skill =
CustomSkillBuilder()
.addRequestHandlers(intentHandlerHolder.intentHandlers)
.apply {
interceptorHolder.requestInterceptors.forEach {
addRequestInterceptor(it)
}
interceptorHolder.responseInterceptors.forEach {
addResponseInterceptor(it)
}
}
.withApiClient(ApacheHttpApiClient.standard())
.build()
}
The MIT license (MIT)
Copyright (c) 2018 REWE Digital GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.