mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-12-07 14:55:55 +00:00
Compare commits
13 Commits
d55d8fa000
...
1.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e73aac750 | |||
| 82c6eda0b7 | |||
| e9ff93cde1 | |||
| 9b179ea1c9 | |||
| 72d20d2344 | |||
| bcd288fe05 | |||
| 75477060e9 | |||
| 60df609486 | |||
| 556b492b35 | |||
| 53e8c53fb1 | |||
| 69d36c5c1b | |||
| ad97008f12 | |||
| 3e58114eeb |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,5 +1,16 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 1.1.0
|
||||
|
||||
* `Utils`:
|
||||
* New parameter `additionalApplicationEngineEnvironmentConfigurator` in `RequestsExecutor#setWebhookInfoAndStartListenWebhooks` and `startListenWebhooks`
|
||||
|
||||
## 1.0.1
|
||||
|
||||
* `Versions`:
|
||||
* `Serialization`: `1.3.2` -> `1.3.3`
|
||||
* `MicroUtils`: `0.10.3` -> `0.10.4`
|
||||
|
||||
## 1.0.0
|
||||
|
||||
__All the `tgbotapi.extensions.*` packages have been removed__
|
||||
@@ -7,7 +18,7 @@ __All the `tgbotapi.extensions.*` packages have been removed__
|
||||
* `Versions`:
|
||||
* `Kotlin`: `1.6.10` -> `1.6.21`
|
||||
* `Ktor`: `1.6.8` -> `2.0.1`
|
||||
* `MicroUtils`: `0.9.24` -> `0.10.2`
|
||||
* `MicroUtils`: `0.9.24` -> `0.10.3`
|
||||
* `Core`:
|
||||
* **`Ktor` package renamed. Migration:** `dev.inmo.tgbotapi.bot.Ktor` -> `dev.inmo.tgbotapi.bot.ktor`
|
||||
* **`CallbackQuery` package renamed. Migration:** `dev.inmo.tgbotapi.types.CallbackQuery([\s\\.])` -> `dev.inmo.tgbotapi.types.queries.callback$1`
|
||||
@@ -52,13 +63,14 @@ __All the `tgbotapi.extensions.*` packages have been removed__
|
||||
* `SimpleFilter` now is a `fun interface` instead of just callback (fix of [#546](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/546))
|
||||
* New extension `BehaviourContext#createSubContext`. It uses separated `AccumulatorFlow` and will retrieve updates by itself
|
||||
* New extension `BehaviourContext#doInContext`
|
||||
* Extension `BehaviourContext#doInSubContextWithUpdatesFilter` has been renamed to `BehaviourContext#createSubContextAndDoWithUpdatesFilter`
|
||||
* Extension `BehaviourContext#doInSubContext` has been deprecated
|
||||
* `BehaviourContextWithFSM`:
|
||||
* `launchStateHandling` lost its parameter `contextUpdatesFlow: Flow`
|
||||
* `handleState` of `BehaviourContextWithFSM` now will get/create sub context for the state and launch handling in it
|
||||
* `BehaviourWithFSMStateHandler` now extends `StatesHandler`
|
||||
* `BehaviourWithFSMStateHandlerHolder` now extends `CheckableHandlerHolder` and `BehaviourWithFSMStateHandler`
|
||||
* Function `checkHandleable` of `BehaviourWithFSMStateHandlerHolder` now is `suspend`
|
||||
*
|
||||
|
||||
## 0.38.23
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ kotlin.incremental.js=true
|
||||
|
||||
kotlin_version=1.6.21
|
||||
kotlin_coroutines_version=1.6.1
|
||||
kotlin_serialisation_runtime_version=1.3.2
|
||||
kotlin_serialisation_runtime_version=1.3.3
|
||||
klock_version=2.7.0
|
||||
uuid_version=0.4.0
|
||||
ktor_version=2.0.1
|
||||
|
||||
micro_utils_version=0.10.3
|
||||
micro_utils_version=0.10.4
|
||||
|
||||
javax_activation_version=1.1.1
|
||||
|
||||
@@ -20,6 +20,6 @@ javax_activation_version=1.1.1
|
||||
dokka_version=1.6.21
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=1.0.0
|
||||
library_version=1.1.0
|
||||
|
||||
github_release_plugin_version=2.3.7
|
||||
|
||||
@@ -94,7 +94,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
|
||||
private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>()
|
||||
private var actualHandlersList = additionalHandlers + handlers
|
||||
|
||||
private suspend fun getSubContext(context: Any) = updatesFlows.getOrPut(context) {
|
||||
private fun getSubContext(context: Any) = updatesFlows.getOrPut(context) {
|
||||
createSubContext()
|
||||
}
|
||||
|
||||
|
||||
@@ -34,10 +34,9 @@ class BehaviourWithFSMStateHandlerHolder<I : O, O : State>(
|
||||
handleState(state as I)
|
||||
}
|
||||
|
||||
override suspend fun StatesMachine<in O>.handleState(state: O): O? = if (this is BehaviourContextWithFSM) {
|
||||
handleState(state)
|
||||
} else {
|
||||
null
|
||||
override suspend fun StatesMachine<in O>.handleState(state: O): O? = with(delegateTo) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
handleState(state as I)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,10 +113,10 @@ inline fun <T> BehaviourContext(
|
||||
crossinline block: BehaviourContext.() -> T
|
||||
) = DefaultBehaviourContext(bot, scope, upstreamUpdatesFlow = flowsUpdatesFilter.allUpdatesFlow, triggersHolder = triggersHolder).run(block)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.createSubContext(
|
||||
fun <BC : BehaviourContext> BC.createSubContext(
|
||||
scope: CoroutineScope = LinkedSupervisorScope(),
|
||||
triggersHolder: TriggersHolder = this.triggersHolder,
|
||||
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow.accumulatorFlow(scope),
|
||||
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
||||
updatesFilter: CustomBehaviourContextAndTypeReceiver<BC, Boolean, Update>? = null,
|
||||
) = copy(
|
||||
scope = scope,
|
||||
@@ -132,20 +132,51 @@ suspend fun <BC : BehaviourContext> BC.createSubContext(
|
||||
) as BC
|
||||
|
||||
/**
|
||||
* Creates new one [BehaviourContext], adding subsequent [FlowsUpdatesFilter] in case [updatesFilter] is provided and
|
||||
* [CoroutineScope] as new [BehaviourContext.scope]
|
||||
* Launch [behaviourContextReceiver] in context of [this] as [BehaviourContext] and as [kotlin.coroutines.CoroutineContext]
|
||||
*
|
||||
* @param stopOnCompletion ___FALSE BY DEFAULT___. Will stop [this] in case if passed true
|
||||
*/
|
||||
suspend fun <T, BC : BehaviourContext> BC.doInContext(
|
||||
stopOnCompletion: Boolean = true,
|
||||
stopOnCompletion: Boolean = false,
|
||||
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
|
||||
): T {
|
||||
return behaviourContextReceiver().also { if (stopOnCompletion) stop() }
|
||||
return withContext(coroutineContext) {
|
||||
behaviourContextReceiver().also { if (stopOnCompletion) stop() }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new one [BehaviourContext], adding subsequent [FlowsUpdatesFilter] in case [updatesFilter] is provided and
|
||||
* [CoroutineScope] as new [BehaviourContext.scope]
|
||||
* Creates new one [BehaviourContext] using [createSubContext] and launches [behaviourContextReceiver] in a new context
|
||||
* using [doInContext]
|
||||
*
|
||||
* @param stopOnCompletion ___TRUE BY DEFAULT___
|
||||
*/
|
||||
suspend fun <T, BC : BehaviourContext> BC.createSubContextAndDoWithUpdatesFilter(
|
||||
scope: CoroutineScope = LinkedSupervisorScope(),
|
||||
triggersHolder: TriggersHolder = this.triggersHolder,
|
||||
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
||||
updatesFilter: CustomBehaviourContextAndTypeReceiver<BC, Boolean, Update>? = null,
|
||||
stopOnCompletion: Boolean = true,
|
||||
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
|
||||
): T {
|
||||
return createSubContext(
|
||||
scope,
|
||||
triggersHolder,
|
||||
updatesUpstreamFlow,
|
||||
updatesFilter
|
||||
).doInContext(
|
||||
stopOnCompletion,
|
||||
behaviourContextReceiver
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new one [BehaviourContext] using [createSubContext] and launches [behaviourContextReceiver] in a new context
|
||||
* using [doInContext]
|
||||
*
|
||||
* @param stopOnCompletion ___TRUE BY DEFAULT___
|
||||
*/
|
||||
@Deprecated("Renamed", ReplaceWith("createSubContextAndDoWithUpdatesFilter", "dev.inmo.tgbotapi.extensions.behaviour_builder.createSubContextAndDoWithUpdatesFilter"))
|
||||
suspend fun <T, BC : BehaviourContext> BC.doInSubContextWithUpdatesFilter(
|
||||
updatesFilter: CustomBehaviourContextAndTypeReceiver<BC, Boolean, Update>?,
|
||||
stopOnCompletion: Boolean = true,
|
||||
@@ -165,13 +196,21 @@ suspend fun <T, BC : BehaviourContext> BC.doInSubContextWithUpdatesFilter(
|
||||
)
|
||||
}
|
||||
|
||||
@Deprecated("Redundant", ReplaceWith("createSubContextAndDoWithUpdatesFilter", "dev.inmo.tgbotapi.extensions.behaviour_builder.createSubContextAndDoWithUpdatesFilter"))
|
||||
suspend fun <T> BehaviourContext.doInSubContext(
|
||||
stopOnCompletion: Boolean = true,
|
||||
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
||||
scope: CoroutineScope = LinkedSupervisorScope(),
|
||||
triggersHolder: TriggersHolder = this.triggersHolder,
|
||||
behaviourContextReceiver: BehaviourContextReceiver<T>
|
||||
) = doInSubContextWithUpdatesFilter(updatesFilter = null, stopOnCompletion, updatesUpstreamFlow, scope, triggersHolder, behaviourContextReceiver)
|
||||
) = createSubContextAndDoWithUpdatesFilter(
|
||||
scope,
|
||||
triggersHolder,
|
||||
updatesUpstreamFlow,
|
||||
updatesFilter = null,
|
||||
stopOnCompletion,
|
||||
behaviourContextReceiver
|
||||
)
|
||||
|
||||
/**
|
||||
* This method will cancel ALL subsequent contexts, expectations and waiters
|
||||
|
||||
@@ -21,12 +21,9 @@ internal suspend inline fun <BC : BehaviourContext, reified T> BC.on(
|
||||
scope,
|
||||
markerFactory::invoke
|
||||
) { triggerData ->
|
||||
val scope = LinkedSupervisorScope()
|
||||
doInSubContextWithUpdatesFilter(
|
||||
createSubContextAndDoWithUpdatesFilter(
|
||||
updatesFilter = subcontextUpdatesFilter ?.toOneType(triggerData),
|
||||
stopOnCompletion = false,
|
||||
updatesUpstreamFlow = allUpdatesFlow.accumulatorFlow(scope),
|
||||
scope = scope
|
||||
stopOnCompletion = false
|
||||
) {
|
||||
scenarioReceiver(triggerData)
|
||||
}
|
||||
|
||||
@@ -391,6 +391,8 @@ const val requireShippingAddressField = "need_shipping_address"
|
||||
const val shouldSendPhoneNumberToProviderField = "send_phone_number_to_provider"
|
||||
const val shouldSendEmailToProviderField = "send_email_to_provider"
|
||||
|
||||
const val resizeKeyboardField = "resize_keyboard"
|
||||
const val oneTimeKeyboardField = "one_time_keyboard"
|
||||
const val inputFieldPlaceholderField = "input_field_placeholder"
|
||||
|
||||
const val priceDependOnShipAddressField = "is_flexible"
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package dev.inmo.tgbotapi.types.buttons
|
||||
|
||||
import dev.inmo.tgbotapi.types.inputFieldPlaceholderField
|
||||
import dev.inmo.tgbotapi.types.inputFieldPlaceholderLimit
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ReplyKeyboardMarkup(
|
||||
val keyboard: Matrix<KeyboardButton>,
|
||||
@SerialName("resize_keyboard")
|
||||
@SerialName(resizeKeyboardField)
|
||||
val resizeKeyboard: Boolean? = null,
|
||||
@SerialName("one_time_keyboard")
|
||||
@SerialName(oneTimeKeyboardField)
|
||||
val oneTimeKeyboard: Boolean? = null,
|
||||
@SerialName(inputFieldPlaceholderField)
|
||||
val inputFieldPlaceholder: String? = null,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.ExceptionHandler
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.micro_utils.coroutines.*
|
||||
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
||||
import dev.inmo.tgbotapi.extensions.utils.nonstrictJsonFormat
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.flowsUpdatesFilter
|
||||
@@ -10,6 +9,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.UpdateDeserializationStrategy
|
||||
import dev.inmo.tgbotapi.updateshandlers.*
|
||||
import dev.inmo.tgbotapi.updateshandlers.webhook.WebhookPrivateKeyConfig
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.application.call
|
||||
import io.ktor.server.engine.*
|
||||
import io.ktor.server.request.receiveText
|
||||
@@ -39,18 +39,22 @@ fun Route.includeWebhookHandlingInRoute(
|
||||
) {
|
||||
val transformer = scope.updateHandlerWithMediaGroupsAdaptation(block, mediaGroupsDebounceTimeMillis)
|
||||
post {
|
||||
safely(
|
||||
exceptionsHandler ?: {}
|
||||
) {
|
||||
val asJson =
|
||||
nonstrictJsonFormat.parseToJsonElement(call.receiveText())
|
||||
val update = nonstrictJsonFormat.decodeFromJsonElement(
|
||||
UpdateDeserializationStrategy,
|
||||
asJson
|
||||
)
|
||||
transformer(update)
|
||||
try {
|
||||
runCatchingSafely {
|
||||
val asJson = nonstrictJsonFormat.parseToJsonElement(call.receiveText())
|
||||
val update = nonstrictJsonFormat.decodeFromJsonElement(
|
||||
UpdateDeserializationStrategy,
|
||||
asJson
|
||||
)
|
||||
transformer(update)
|
||||
}.onSuccess {
|
||||
call.respond(HttpStatusCode.OK)
|
||||
}.onFailure {
|
||||
call.respond(HttpStatusCode.InternalServerError)
|
||||
}.getOrThrow()
|
||||
} catch (e: Throwable) {
|
||||
exceptionsHandler ?.invoke(e)
|
||||
}
|
||||
call.respond("Ok")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +91,7 @@ fun startListenWebhooks(
|
||||
privateKeyConfig: WebhookPrivateKeyConfig? = null,
|
||||
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
|
||||
mediaGroupsDebounceTimeMillis: Long = 1000L,
|
||||
additionalApplicationEngineEnvironmentConfigurator: ApplicationEngineEnvironmentBuilder.() -> Unit = {},
|
||||
block: UpdateReceiver<Update>
|
||||
): ApplicationEngine {
|
||||
val env = applicationEngineEnvironment {
|
||||
@@ -98,6 +103,7 @@ fun startListenWebhooks(
|
||||
} ?: includeWebhookHandlingInRoute(scope, exceptionsHandler, mediaGroupsDebounceTimeMillis, block)
|
||||
}
|
||||
}
|
||||
|
||||
privateKeyConfig ?.let {
|
||||
sslConnector(
|
||||
privateKeyConfig.keyStore,
|
||||
@@ -113,6 +119,7 @@ fun startListenWebhooks(
|
||||
port = listenPort
|
||||
}
|
||||
|
||||
additionalApplicationEngineEnvironmentConfigurator()
|
||||
}
|
||||
|
||||
return embeddedServer(engineFactory, env).also {
|
||||
@@ -142,10 +149,11 @@ suspend fun RequestsExecutor.setWebhookInfoAndStartListenWebhooks(
|
||||
privateKeyConfig: WebhookPrivateKeyConfig? = null,
|
||||
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
|
||||
mediaGroupsDebounceTimeMillis: Long = 1000L,
|
||||
additionalApplicationEngineEnvironmentConfigurator: ApplicationEngineEnvironmentBuilder.() -> Unit = {},
|
||||
block: UpdateReceiver<Update>
|
||||
): ApplicationEngine = try {
|
||||
execute(setWebhookRequest)
|
||||
startListenWebhooks(listenPort, engineFactory, exceptionsHandler, listenHost, listenRoute, privateKeyConfig, scope, mediaGroupsDebounceTimeMillis, block)
|
||||
startListenWebhooks(listenPort, engineFactory, exceptionsHandler, listenHost, listenRoute, privateKeyConfig, scope, mediaGroupsDebounceTimeMillis, additionalApplicationEngineEnvironmentConfigurator, block)
|
||||
} catch (e: Exception) {
|
||||
throw e
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user