mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-20 14:25:46 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 618017c160 | |||
| 33c8ee0803 | |||
| 0c0ec22348 | |||
| 24bffbbd97 | |||
| a615d1c4fd | |||
| a76b7977b3 | |||
| 6004879aef |
@@ -1,5 +1,13 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 0.38.2
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* `Version`:
|
||||||
|
* `MicroUtils`: `0.9.0` -> `0.9.1`
|
||||||
|
* `API`
|
||||||
|
* New extensions `TelegramBot#copyMessages` for media groups
|
||||||
|
|
||||||
## 0.38.1
|
## 0.38.1
|
||||||
|
|
||||||
* `Core`:
|
* `Core`:
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ uuid_version=0.3.1
|
|||||||
ktor_version=1.6.7
|
ktor_version=1.6.7
|
||||||
|
|
||||||
|
|
||||||
micro_utils_version=0.9.0
|
micro_utils_version=0.9.1
|
||||||
|
|
||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.38.1
|
library_version=0.38.2
|
||||||
|
|
||||||
github_release_plugin_version=2.2.12
|
github_release_plugin_version=2.2.12
|
||||||
|
|||||||
97
readmes/exceptions_handling.md
Normal file
97
readmes/exceptions_handling.md
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# Exceptions handling
|
||||||
|
|
||||||
|
Unfortunatelly, exceptions handling in this library is a bit difficult in some places, but that have at least two reasons: flexibility and usability.
|
||||||
|
|
||||||
|
## "In place" handling
|
||||||
|
|
||||||
|
In case you know, where exceptions are happening, you may use several tools for exceptions catching:
|
||||||
|
|
||||||
|
* Catching with result
|
||||||
|
* Catching with callback
|
||||||
|
|
||||||
|
### Catching with result
|
||||||
|
|
||||||
|
If you prefer to receive `Result` objects instead of some weird callbacks, you may use the next syntax:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
safelyWithResult {
|
||||||
|
// do something
|
||||||
|
}.onSuccess { // will be called if everything is right
|
||||||
|
// handle success
|
||||||
|
}.onFailure { // will be called if something went wrong
|
||||||
|
// handle error
|
||||||
|
it.printStackTrace()
|
||||||
|
}.getOrThrow() // will return value or throw exception
|
||||||
|
```
|
||||||
|
|
||||||
|
### Catching with callback
|
||||||
|
|
||||||
|
Also there is more simple (in some cases) way to handle exceptions with callbacks:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
safely(
|
||||||
|
{
|
||||||
|
// handle error
|
||||||
|
it.printStackTrace()
|
||||||
|
null // return value
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bonus: different types of handling
|
||||||
|
|
||||||
|
There are two types of handling:
|
||||||
|
|
||||||
|
* Just safely - when you are using something to obviously retrieve value or throw exception. When handling callback has been skipped, it will throw exception by default. For example:
|
||||||
|
```kotlin
|
||||||
|
safely(
|
||||||
|
{
|
||||||
|
it.printStackTrace()
|
||||||
|
"error"
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
error("Hi :)") // emulate exception throwing
|
||||||
|
"ok"
|
||||||
|
} // result will be with type String
|
||||||
|
```
|
||||||
|
* Safely without exceptions - almost the same as `safely`, but this type by default allow to return nullable value (when exception was thrown) instead of just throwing (as with `safely`):
|
||||||
|
```kotlin
|
||||||
|
safelyWithouExceptions {
|
||||||
|
// do something
|
||||||
|
} // will returns nullable result type
|
||||||
|
```
|
||||||
|
|
||||||
|
## Global exceptions handling
|
||||||
|
|
||||||
|
The most simple way to configure exceptions handling is to change `CoroutineContext` when you are creating your `CoroutineScope` for bot processing:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val bot = telegramBot("TOKEN")
|
||||||
|
|
||||||
|
bot.buildBehaviour (
|
||||||
|
scope = scope,
|
||||||
|
defaultExceptionsHandler = {
|
||||||
|
it.printStackTrace()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val bot = telegramBotWithBehaviour (
|
||||||
|
"TOKEN",
|
||||||
|
scope = scope,
|
||||||
|
defaultExceptionsHandler = {
|
||||||
|
it.printStackTrace()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here we have used `ContextSafelyExceptionHandler` class. It will pass default handling of exceptions and will call the block in most cases when something inside of your bot logic has thrown exception.
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
package dev.inmo.tgbotapi.extensions.api.send
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup
|
||||||
|
import dev.inmo.tgbotapi.requests.send.CopyMessage
|
||||||
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
|
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
|
||||||
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.MediaGroupUpdate
|
||||||
|
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChatId: ChatIdentifier,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
): List<MediaGroupMessage<MediaGroupContent>> {
|
||||||
|
val first = messages.first().content.toMediaGroupMemberInputMedia().let {
|
||||||
|
if (text != null) {
|
||||||
|
when (it) {
|
||||||
|
is InputMediaAudio -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
is InputMediaDocument -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
is InputMediaPhoto -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
is InputMediaVideo -> it.copy(text = text, parseMode = parseMode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendMediaGroup(
|
||||||
|
toChatId,
|
||||||
|
listOf(first) + messages.drop(1).map {
|
||||||
|
it.content.toMediaGroupMemberInputMedia()
|
||||||
|
},
|
||||||
|
disableNotification,
|
||||||
|
protectContent,
|
||||||
|
replyToMessageId,
|
||||||
|
allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, messages, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: ChatIdentifier,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat, update.data, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
text: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, update, text, parseMode, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChatId: ChatIdentifier,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
): List<MediaGroupMessage<MediaGroupContent>> {
|
||||||
|
val first = messages.first().content.toMediaGroupMemberInputMedia().let {
|
||||||
|
when (it) {
|
||||||
|
is InputMediaAudio -> InputMediaAudio(it.file, entities, it.duration, it.performer, it.title, it.thumb)
|
||||||
|
is InputMediaDocument -> InputMediaDocument(it.file, entities, it.thumb, it.disableContentTypeDetection)
|
||||||
|
is InputMediaPhoto -> InputMediaPhoto(it.file, entities)
|
||||||
|
is InputMediaVideo -> InputMediaVideo(it.file, entities, it.width, it.height, it.duration, it.thumb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendMediaGroup(
|
||||||
|
toChatId,
|
||||||
|
listOf(first) + messages.drop(1).map {
|
||||||
|
it.content.toMediaGroupMemberInputMedia()
|
||||||
|
},
|
||||||
|
disableNotification,
|
||||||
|
protectContent,
|
||||||
|
replyToMessageId,
|
||||||
|
allowSendingWithoutReply
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
messages: List<MediaGroupMessage<MediaGroupContent>>,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, messages, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: ChatIdentifier,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat, update.data, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements
|
||||||
|
* will be copied as they are
|
||||||
|
*/
|
||||||
|
suspend inline fun TelegramBot.copyMessages(
|
||||||
|
toChat: Chat,
|
||||||
|
update: SentMediaGroupUpdate,
|
||||||
|
entities: TextSourcesList,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
protectContent: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null,
|
||||||
|
allowSendingWithoutReply: Boolean? = null
|
||||||
|
) = copyMessages(toChat.id, update, entities, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
|
||||||
Reference in New Issue
Block a user