1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-06-03 00:15:27 +00:00
tgbotapi/TelegramBotAPI-extensions-utils/src/jvmMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/updates/retrieving/Webhook.kt

208 lines
7.6 KiB
Kotlin
Raw Normal View History

2020-05-13 17:22:35 +00:00
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
2020-05-13 17:22:35 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.nonstrictJsonFormat
2020-08-10 04:46:18 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.flowsUpdatesFilter
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.MultipartFile
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.base.MultipartRequestImpl
import com.github.insanusmokrassar.TelegramBotAPI.requests.webhook.SetWebhook
2020-05-13 17:22:35 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UpdateDeserializationStrategy
2020-08-10 04:46:18 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.*
import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.webhook.WebhookPrivateKeyConfig
2020-05-14 18:28:16 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.utils.ExceptionHandler
import com.github.insanusmokrassar.TelegramBotAPI.utils.handleSafely
import io.ktor.application.call
import io.ktor.request.receiveText
import io.ktor.response.respond
import io.ktor.routing.*
import io.ktor.server.engine.*
2020-07-02 10:15:06 +00:00
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import java.util.concurrent.Executors
2020-05-13 17:22:35 +00:00
/**
2020-05-14 07:11:46 +00:00
* Allows to include webhook in custom route everywhere in your server
*
* @param [scope] Will be used for mapping of media groups
* @param [exceptionsHandler] Pass this parameter to set custom exception handler for getting updates
* @param [block] Some receiver block like [com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.FlowsUpdatesFilter]
*
* @see com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.FlowsUpdatesFilter
* @see UpdatesFilter
* @see UpdatesFilter.asUpdateReceiver
*/
2020-05-14 18:28:16 +00:00
fun Route.includeWebhookHandlingInRoute(
scope: CoroutineScope,
2020-05-14 18:28:16 +00:00
exceptionsHandler: ExceptionHandler<Unit>? = null,
block: UpdateReceiver<Update>
) {
val transformer = scope.updateHandlerWithMediaGroupsAdaptation(block)
post {
handleSafely(
exceptionsHandler ?: {}
) {
val asJson =
nonstrictJsonFormat.parseJson(call.receiveText())
val update = nonstrictJsonFormat.fromJson(
UpdateDeserializationStrategy,
asJson
)
transformer(update)
}
call.respond("Ok")
}
}
2020-08-10 04:46:18 +00:00
fun Route.includeWebhookHandlingInRouteWithFlows(
scope: CoroutineScope,
exceptionsHandler: ExceptionHandler<Unit>? = null,
block: FlowsUpdatesFilter.() -> Unit
) = includeWebhookHandlingInRoute(
scope,
exceptionsHandler,
flowsUpdatesFilter(block = block).asUpdateReceiver
)
/**
* Setting up ktor server, set webhook info via [SetWebhook] request.
*
2020-05-14 18:28:16 +00:00
* @param listenPort port which will be listen by bot
2020-05-15 16:14:19 +00:00
* @param listenRoute address to listen by bot. If null - will be set up in root of host
* @param scope Scope which will be used for
2020-05-14 07:11:46 +00:00
* @param privateKeyConfig If configured - server will be created with [sslConnector]. [connector] will be used otherwise
*
* @see com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.FlowsUpdatesFilter
* @see UpdatesFilter
* @see UpdatesFilter.asUpdateReceiver
*/
2020-05-14 18:28:16 +00:00
fun startListenWebhooks(
listenPort: Int,
engineFactory: ApplicationEngineFactory<*, *>,
2020-05-14 18:28:16 +00:00
exceptionsHandler: ExceptionHandler<Unit>,
listenHost: String = "0.0.0.0",
2020-05-15 16:14:19 +00:00
listenRoute: String? = null,
privateKeyConfig: WebhookPrivateKeyConfig? = null,
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
block: UpdateReceiver<Update>
): ApplicationEngine {
val env = applicationEngineEnvironment {
module {
routing {
2020-05-15 16:14:19 +00:00
listenRoute ?.also {
2020-05-16 14:43:09 +00:00
createRouteFromPath(it).includeWebhookHandlingInRoute(scope, exceptionsHandler, block)
2020-05-15 16:14:19 +00:00
} ?: includeWebhookHandlingInRoute(scope, exceptionsHandler, block)
}
}
privateKeyConfig ?.let {
sslConnector(
privateKeyConfig.keyStore,
privateKeyConfig.aliasName,
privateKeyConfig::keyStorePassword,
privateKeyConfig::aliasPassword
) {
host = listenHost
2020-05-16 14:43:09 +00:00
port = listenPort
}
} ?: connector {
host = listenHost
2020-05-16 14:43:09 +00:00
port = listenPort
}
}
2020-05-17 09:09:48 +00:00
return embeddedServer(engineFactory, env).also {
it.start(false)
}
}
private suspend fun RequestsExecutor.internalSetWebhookInfoAndStartListenWebhooks(
listenPort: Int,
engineFactory: ApplicationEngineFactory<*, *>,
setWebhookRequest: Request<Boolean>,
exceptionsHandler: ExceptionHandler<Unit> = {},
listenHost: String = "0.0.0.0",
2020-05-16 14:43:09 +00:00
listenRoute: String? = null,
privateKeyConfig: WebhookPrivateKeyConfig? = null,
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
block: UpdateReceiver<Update>
2020-05-17 09:09:48 +00:00
): ApplicationEngine {
return try {
execute(setWebhookRequest)
2020-05-17 09:09:48 +00:00
startListenWebhooks(listenPort, engineFactory, exceptionsHandler, listenHost, listenRoute, privateKeyConfig, scope, block)
} catch (e: Exception) {
throw e
}
}
/**
* Setting up ktor server, set webhook info via [SetWebhook] request.
*
2020-05-14 18:28:16 +00:00
* @param listenPort port which will be listen by bot
* @param listenRoute address to listen by bot
* @param scope Scope which will be used for
*
* @see com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.FlowsUpdatesFilter
* @see UpdatesFilter
* @see UpdatesFilter.asUpdateReceiver
*/
2020-05-14 18:28:16 +00:00
@Suppress("unused")
suspend fun RequestsExecutor.setWebhookInfoAndStartListenWebhooks(
listenPort: Int,
engineFactory: ApplicationEngineFactory<*, *>,
2020-05-14 18:28:16 +00:00
setWebhookRequest: SetWebhook,
exceptionsHandler: ExceptionHandler<Unit> = {},
listenHost: String = "0.0.0.0",
listenRoute: String = "/",
privateKeyConfig: WebhookPrivateKeyConfig? = null,
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
block: UpdateReceiver<Update>
2020-05-17 09:09:48 +00:00
): ApplicationEngine = internalSetWebhookInfoAndStartListenWebhooks(
listenPort,
engineFactory,
setWebhookRequest as Request<Boolean>,
exceptionsHandler,
listenHost,
listenRoute,
privateKeyConfig,
scope,
block
)
/**
* Setting up ktor server, set webhook info via [SetWebhook] request.
*
* @param listenPort port which will be listen by bot
* @param listenRoute address to listen by bot
* @param scope Scope which will be used for
*
* @see com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.FlowsUpdatesFilter
* @see UpdatesFilter
* @see UpdatesFilter.asUpdateReceiver
*/
@Suppress("unused")
suspend fun RequestsExecutor.setWebhookInfoAndStartListenWebhooks(
listenPort: Int,
engineFactory: ApplicationEngineFactory<*, *>,
setWebhookRequest: MultipartRequestImpl<SetWebhook, Map<String, MultipartFile>, Boolean>,
exceptionsHandler: ExceptionHandler<Unit> = {},
listenHost: String = "0.0.0.0",
2020-05-16 14:43:09 +00:00
listenRoute: String? = null,
privateKeyConfig: WebhookPrivateKeyConfig? = null,
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
block: UpdateReceiver<Update>
2020-05-17 09:09:48 +00:00
): ApplicationEngine = internalSetWebhookInfoAndStartListenWebhooks(
listenPort,
engineFactory,
setWebhookRequest as Request<Boolean>,
exceptionsHandler,
listenHost,
listenRoute,
privateKeyConfig,
scope,
block
)