From 30aac0ecdc9739c39c9059c3a4dfdd06334aa548 Mon Sep 17 00:00:00 2001 From: Denire Date: Sat, 20 Feb 2021 14:50:40 +0300 Subject: [PATCH] PR fixes: naming, javadocs --- .../jaicf/channel/facebook/FacebookChannel.kt | 2 +- .../justai/jaicf/channel/jaicp/JaicpEvents.kt | 12 +++--- .../execution/ThreadPoolRequestExecutor.kt | 2 +- .../jaicp/http/ChatAdapterConnector.kt | 18 ++++----- .../jaicp/reactions/JaicpAsyncReactions.kt | 35 +----------------- .../reactions/reaction/SwitchReaction.kt | 37 +++++++++++++++++++ .../jaicf/channel/slack/SlackChannel.kt | 5 ++- .../jaicf/channel/telegram/TelegramChannel.kt | 8 +++- .../invocationapi/InvocableBotChannel.kt | 12 +++--- .../invocationapi/InvocationQueryParams.kt | 2 +- .../invocationapi/InvocationRequest.kt | 2 +- .../invocationapi/InvocationRouting.kt | 8 ++-- .../invocationapi/InvocationServlet.kt | 8 ++-- 13 files changed, 79 insertions(+), 72 deletions(-) create mode 100644 channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/reaction/SwitchReaction.kt diff --git a/channels/facebook/src/main/kotlin/com/justai/jaicf/channel/facebook/FacebookChannel.kt b/channels/facebook/src/main/kotlin/com/justai/jaicf/channel/facebook/FacebookChannel.kt index b0d04bc8..bb352a4f 100644 --- a/channels/facebook/src/main/kotlin/com/justai/jaicf/channel/facebook/FacebookChannel.kt +++ b/channels/facebook/src/main/kotlin/com/justai/jaicf/channel/facebook/FacebookChannel.kt @@ -59,7 +59,7 @@ class FacebookChannel private constructor( internal const val REQUEST_TEMPLATE_PATH = "/FacebookRequestTemplate.json" } - override fun processExternalInvocation(request: InvocationRequest, requestContext: RequestContext) { + override fun processInvocation(request: InvocationRequest, requestContext: RequestContext) { val template = getRequestTemplateFromResources(request, REQUEST_TEMPLATE_PATH) messenger.onReceiveEvents(template, Optional.empty()) { event -> FacebookInvocationRequest.create(request, event.asTextMessageEvent())?.let { diff --git a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/JaicpEvents.kt b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/JaicpEvents.kt index 6b5c3f62..b76beeb8 100644 --- a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/JaicpEvents.kt +++ b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/JaicpEvents.kt @@ -3,17 +3,17 @@ package com.justai.jaicf.channel.jaicp /** * Events which can be send with JaicpBotRequest * - * @property fileEvent - is sent when user sends file or image. File will be uploaded to s3 storage, + * @property FILE_EVENT - is sent when user sends file or image. File will be uploaded to s3 storage, * link will be provided in request.telephony?.jaicp?.data - * @property liveChatFinished - is sent when livechat is finished and request execution is returned to bot. - * @property noLivechatOperatorsOnline - is sent when scenario attempted switchToLiveChat, but no operators were online. + * @property LIVE_CHAT_FINISHED - is sent when livechat is finished and request execution is returned to bot. + * @property NO_LIVE_CHAT_OPERATORS_ONLINE - is sent when scenario attempted switchToLiveChat, but no operators were online. * * @see com.justai.jaicf.channel.jaicp.channels.TelephonyEvents * @see com.justai.jaicf.channel.jaicp.reactions.switchToLiveChat * */ @Suppress("MemberVisibilityCanBePrivate") object JaicpEvents { - const val fileEvent = "fileEvent" - const val liveChatFinished = "livechatFinished" - const val noLivechatOperatorsOnline = "noLivechatOperatorsOnline" + const val FILE_EVENT = "fileEvent" + const val LIVE_CHAT_FINISHED = "livechatFinished" + const val NO_LIVE_CHAT_OPERATORS_ONLINE = "noLivechatOperatorsOnline" } \ No newline at end of file diff --git a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/execution/ThreadPoolRequestExecutor.kt b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/execution/ThreadPoolRequestExecutor.kt index 112d7e72..0a840b4c 100644 --- a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/execution/ThreadPoolRequestExecutor.kt +++ b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/execution/ThreadPoolRequestExecutor.kt @@ -94,7 +94,7 @@ private fun tryProcessAsExternalInvocation( } catch (e: Exception) { return false } - channel.processExternalInvocation( + channel.processInvocation( request = InvocationEventRequest(data.chatId, event, request.raw), requestContext = RequestContext.fromHttp(request.asHttpBotRequest()) ) diff --git a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/http/ChatAdapterConnector.kt b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/http/ChatAdapterConnector.kt index ff415c1f..7f3b7b81 100644 --- a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/http/ChatAdapterConnector.kt +++ b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/http/ChatAdapterConnector.kt @@ -48,22 +48,20 @@ internal class ChatAdapterConnector private constructor( fun initLiveChat(liveChatInitRequest: LiveChatInitRequest) { try { - initLiveChat0(liveChatInitRequest) - } catch (e: ClientRequestException){ - when(e.response?.status){ + runBlocking { + httpClient.post("$baseUrl/initLiveChatSwitch") { + body = liveChatInitRequest + contentType(ContentType.Application.Json) + } + } + } catch (e: ClientRequestException) { + when (e.response?.status) { HttpStatusCode.NotFound -> throw NoOperatorsOnlineException(liveChatInitRequest.request) HttpStatusCode.BadRequest -> throw NoOperatorChannelConfiguredException(liveChatInitRequest.request) } } } - private fun initLiveChat0(liveChatInitRequest: LiveChatInitRequest) = runBlocking { - httpClient.post("$baseUrl/initLiveChatSwitch") { - body = liveChatInitRequest - contentType(ContentType.Application.Json) - } - } - companion object { private var INSTANCE: ChatAdapterConnector? = null diff --git a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/JaicpAsyncReactions.kt b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/JaicpAsyncReactions.kt index bdb5f900..b1ea8eea 100644 --- a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/JaicpAsyncReactions.kt +++ b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/JaicpAsyncReactions.kt @@ -5,9 +5,8 @@ import com.justai.jaicf.channel.jaicp.http.ChatAdapterConnector import com.justai.jaicf.channel.jaicp.livechat.LiveChatInitRequest import com.justai.jaicf.channel.jaicp.livechat.exceptions.NoOperatorChannelConfiguredException import com.justai.jaicf.channel.jaicp.livechat.exceptions.NoOperatorsOnlineException -import com.justai.jaicf.logging.Reaction +import com.justai.jaicf.channel.jaicp.reactions.reaction.SwitchReaction import com.justai.jaicf.reactions.jaicp.JaicpCompatibleAsyncReactions -import kotlinx.serialization.json.JsonObject /** * Switches to livechat operator if channel is connected to livechat in JAICP App Console. @@ -38,35 +37,3 @@ fun JaicpCompatibleAsyncReactions.switchToLiveChat(reply: LiveChatSwitchReply): return SwitchReaction.fromReply(switchRequest.switchData, loggingContext.botContext.dialogContext.currentState) .also { loggingContext.reactions.add(it) } } - -data class SwitchReaction( - val firstMessage: String? = null, - val closeChatPhrases: List = emptyList(), - val appendCloseChatButton: Boolean = false, - val ignoreOffline: Boolean = false, - val oneTimeMessage: Boolean = false, - val destination: String? = null, - val lastMessage: String? = null, - val attributes: JsonObject? = null, - val hiddenAttributes: JsonObject? = null, - val sendMessagesToOperator: Boolean = false, - val sendMessageHistoryAmount: Int? = null, - override val fromState: String -) : Reaction(fromState) { - companion object { - fun fromReply(switchReply: LiveChatSwitchReply, state: String) = SwitchReaction( - firstMessage = switchReply.firstMessage, - closeChatPhrases = switchReply.closeChatPhrases, - appendCloseChatButton = switchReply.appendCloseChatButton, - ignoreOffline = switchReply.ignoreOffline, - oneTimeMessage = switchReply.oneTimeMessage, - destination = switchReply.destination, - lastMessage = switchReply.lastMessage, - attributes = switchReply.attributes, - hiddenAttributes = switchReply.hiddenAttributes, - sendMessageHistoryAmount = switchReply.sendMessageHistoryAmount, - sendMessagesToOperator = switchReply.sendMessagesToOperator, - fromState = state - ) - } -} \ No newline at end of file diff --git a/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/reaction/SwitchReaction.kt b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/reaction/SwitchReaction.kt new file mode 100644 index 00000000..7768336b --- /dev/null +++ b/channels/jaicp/src/main/kotlin/com/justai/jaicf/channel/jaicp/reactions/reaction/SwitchReaction.kt @@ -0,0 +1,37 @@ +package com.justai.jaicf.channel.jaicp.reactions.reaction + +import com.justai.jaicf.channel.jaicp.dto.LiveChatSwitchReply +import com.justai.jaicf.logging.Reaction +import kotlinx.serialization.json.JsonObject + +data class SwitchReaction( + val firstMessage: String? = null, + val closeChatPhrases: List = emptyList(), + val appendCloseChatButton: Boolean = false, + val ignoreOffline: Boolean = false, + val oneTimeMessage: Boolean = false, + val destination: String? = null, + val lastMessage: String? = null, + val attributes: JsonObject? = null, + val hiddenAttributes: JsonObject? = null, + val sendMessagesToOperator: Boolean = false, + val sendMessageHistoryAmount: Int? = null, + override val fromState: String +) : Reaction(fromState) { + companion object { + fun fromReply(switchReply: LiveChatSwitchReply, state: String) = SwitchReaction( + firstMessage = switchReply.firstMessage, + closeChatPhrases = switchReply.closeChatPhrases, + appendCloseChatButton = switchReply.appendCloseChatButton, + ignoreOffline = switchReply.ignoreOffline, + oneTimeMessage = switchReply.oneTimeMessage, + destination = switchReply.destination, + lastMessage = switchReply.lastMessage, + attributes = switchReply.attributes, + hiddenAttributes = switchReply.hiddenAttributes, + sendMessageHistoryAmount = switchReply.sendMessageHistoryAmount, + sendMessagesToOperator = switchReply.sendMessagesToOperator, + fromState = state + ) + } +} \ No newline at end of file diff --git a/channels/slack/src/main/kotlin/com/justai/jaicf/channel/slack/SlackChannel.kt b/channels/slack/src/main/kotlin/com/justai/jaicf/channel/slack/SlackChannel.kt index 96ca7f4c..1ddd651f 100644 --- a/channels/slack/src/main/kotlin/com/justai/jaicf/channel/slack/SlackChannel.kt +++ b/channels/slack/src/main/kotlin/com/justai/jaicf/channel/slack/SlackChannel.kt @@ -101,9 +101,10 @@ class SlackChannel private constructor( override fun provideTimestamp(): String = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()).toString() - override fun processExternalInvocation(request: InvocationRequest, requestContext: RequestContext) { + override fun processInvocation(request: InvocationRequest, requestContext: RequestContext) { val invocationRequest = SlackInvocationRequest.create(request) ?: return - val slackRequest = buildSlackRequest(getRequestTemplateFromResources(request, REQUEST_TEMPLATE_PATH).asHttpBotRequest()) + val slackRequest = + buildSlackRequest(getRequestTemplateFromResources(request, REQUEST_TEMPLATE_PATH).asHttpBotRequest()) botApi.process(invocationRequest, SlackReactions(slackRequest.context), requestContext) } diff --git a/channels/telegram/src/main/kotlin/com/justai/jaicf/channel/telegram/TelegramChannel.kt b/channels/telegram/src/main/kotlin/com/justai/jaicf/channel/telegram/TelegramChannel.kt index b67231c1..353ccde3 100644 --- a/channels/telegram/src/main/kotlin/com/justai/jaicf/channel/telegram/TelegramChannel.kt +++ b/channels/telegram/src/main/kotlin/com/justai/jaicf/channel/telegram/TelegramChannel.kt @@ -15,6 +15,7 @@ import com.justai.jaicf.context.RequestContext import com.justai.jaicf.helpers.kotlin.PropertyWithBackingField import com.justai.jaicf.channel.invocationapi.InvocableBotChannel import com.justai.jaicf.channel.invocationapi.InvocationRequest +import java.util.* import java.util.concurrent.TimeUnit class TelegramChannel( @@ -100,9 +101,12 @@ class TelegramChannel( return null } - override fun provideTimestamp(): String = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()).toString() + override fun getRequestTemplateFromResources(request: InvocationRequest, resourceName: String): String = + super.getRequestTemplateFromResources(request, resourceName) + .replace("\"{{ timestamp }}\"", TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()).toString()) + .replace("{{ messageId }}", UUID.randomUUID().toString()) - override fun processExternalInvocation(request: InvocationRequest, requestContext: RequestContext) { + override fun processInvocation(request: InvocationRequest, requestContext: RequestContext) { val template = getRequestTemplateFromResources(request, REQUEST_TEMPLATE_PATH) val message = gson.fromJson(template, Update::class.java).message ?: return val telegramRequest = TelegramInvocationRequest.create(request, message) ?: return diff --git a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocableBotChannel.kt b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocableBotChannel.kt index 0eca9786..4cc454a2 100644 --- a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocableBotChannel.kt +++ b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocableBotChannel.kt @@ -1,6 +1,5 @@ package com.justai.jaicf.channel.invocationapi -import com.justai.jaicf.channel.http.HttpBotRequest import com.justai.jaicf.channel.http.asHttpBotRequest import com.justai.jaicf.context.RequestContext import com.justai.jaicf.helpers.logging.WithLogger @@ -9,10 +8,11 @@ import kotlin.random.Random /** * Base class for all channels able to process requests from external service. - * Allows to send [InvocationEventRequest] or [InvocationQueryRequest] with client identifier to implementations at any time. + * Any class implementing [InvocableBotChannel] receives method [processInvocation] allowing to process query or event requests with client identifier from any external source. * * @see InvocationRequest - * + * @see InvocationQueryRequest + * @see InvocationEventRequest * */ interface InvocableBotChannel : WithLogger { /** @@ -23,7 +23,7 @@ interface InvocableBotChannel : WithLogger { * * @see InvocableBotChannel */ - fun processExternalInvocation(request: InvocationRequest, requestContext: RequestContext) + fun processInvocation(request: InvocationRequest, requestContext: RequestContext) /** * Provides a messageId for substitution in request template @@ -64,10 +64,10 @@ interface InvocableBotChannel : WithLogger { * @see InvocationServlet * @see botInvocationRouting * */ -internal fun InvocableBotChannel.processExternalInvocation( +internal fun InvocableBotChannel.processInvocation( queryParams: InvocationQueryParams, requestData: String -) = processExternalInvocation( +) = processInvocation( request = when (queryParams.type) { InvocationRequestType.EVENT -> InvocationEventRequest(queryParams.clientId, queryParams.input, requestData) InvocationRequestType.QUERY -> InvocationQueryRequest(queryParams.clientId, queryParams.input, requestData) diff --git a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationQueryParams.kt b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationQueryParams.kt index 0240215c..90593ace 100644 --- a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationQueryParams.kt +++ b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationQueryParams.kt @@ -33,7 +33,7 @@ internal class InvocationQueryParams(queryParamsMap: Map>) } val clientId: String = requireNotNull(queryParamsMap["clientId"]?.firstOrNull()) { - "clientId path variable must be specified for gateway call" + "clientId path variable must be specified for invocation api call" } } diff --git a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRequest.kt b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRequest.kt index 2be48cb2..aad63b43 100644 --- a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRequest.kt +++ b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRequest.kt @@ -4,7 +4,7 @@ import com.justai.jaicf.api.BotRequest import com.justai.jaicf.api.EventBotRequest import com.justai.jaicf.api.QueryBotRequest -val BotRequest.invocationApi get() = this as? InvocationRequest +val BotRequest.invocationRequest get() = this as? InvocationRequest /** * A request processed by [InvocableBotChannel] implementation. diff --git a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRouting.kt b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRouting.kt index 558d114b..8bcc35fc 100644 --- a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRouting.kt +++ b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationRouting.kt @@ -33,16 +33,16 @@ typealias RouteToInvocableChannel = Pair fun Routing.botInvocationRouting(vararg routes: RouteToInvocableChannel) { routes.forEach { channel -> post(channel.first) { - channel.second.processExternalInvocation(call) + channel.second.processInvocation(call) } get(channel.first) { - channel.second.processExternalInvocation(call) + channel.second.processInvocation(call) } } } -private suspend fun InvocableBotChannel.processExternalInvocation(call: ApplicationCall) = - processExternalInvocation(queryParams = InvocationQueryParams(call.request), requestData = call.receiveText()) +private suspend fun InvocableBotChannel.processInvocation(call: ApplicationCall) = + processInvocation(queryParams = InvocationQueryParams(call.request), requestData = call.receiveText()) diff --git a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationServlet.kt b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationServlet.kt index 4bd4d395..812cd0c9 100644 --- a/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationServlet.kt +++ b/core/src/main/kotlin/com/justai/jaicf/channel/invocationapi/InvocationServlet.kt @@ -34,16 +34,16 @@ open class InvocationServlet( ) : HttpServlet(), WithLogger { override fun doPost(req: HttpServletRequest?, resp: HttpServletResponse?) { - req?.run { channel.processExternalInvocation(req) } + req?.run { channel.processInvocation(req) } } override fun doGet(req: HttpServletRequest?, resp: HttpServletResponse?) { - req?.run { channel.processExternalInvocation(req) } + req?.run { channel.processInvocation(req) } } } /** * Processes invocation request from [InvocationServlet] * */ -private fun InvocableBotChannel.processExternalInvocation(req: HttpServletRequest) = - processExternalInvocation(InvocationQueryParams(req), req.inputStream.bufferedReader().readText()) +private fun InvocableBotChannel.processInvocation(req: HttpServletRequest) = + processInvocation(InvocationQueryParams(req), req.inputStream.bufferedReader().readText())