mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-12-23 00:57:13 +00:00
commit
59680439fa
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,5 +1,23 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 0.14.0
|
||||
|
||||
* Now library have no default engine for both webhooks and requests executor. It is required for clients to set
|
||||
some default library
|
||||
* All proxy help methods was removed . They are will be replaced in separated project
|
||||
* `Ktor` version `1.1.3` -> `1.1.4`
|
||||
* Requests results now always decoding as `UTF-8`
|
||||
* `AbstractRequestCallFactory` was added with cache of methods urls to avoid memory leaks
|
||||
* Small refactoring of work with response in `KtorRequestsExecutor`
|
||||
* Kotlin version `1.3.30` -> `1.3.31`
|
||||
* Kotlin coroutines `1.2.0` -> `1.2.1`
|
||||
* `CommonForwardedMessage` was renamed to `UserForwardedMessage`
|
||||
* All forwarded messages are now just childs of `ForwardedMessage`:
|
||||
* `AnonymousForwardedMessage` - for messages without forwarded info
|
||||
* `UserForwardedMessage` - for messages from users and groups (contains not message id)
|
||||
* `ForwardedFromChannelMessage` - for messages from channels
|
||||
* Changed logic of forwarded messages preparing
|
||||
|
||||
## 0.13.0 Telegram Polls
|
||||
|
||||
* Type `PollOption` and `AnonymousPollOption` added
|
||||
|
98
README.md
98
README.md
@ -46,23 +46,82 @@ compile "com.github.insanusmokrassar:TelegramBotAPI:${telegrambotapi.version}"
|
||||
|
||||
## How to work with library?
|
||||
|
||||
By default in any documentation will be meaning that you have variable in scope with names
|
||||
For now, this library have no some API god-object. Instead of this, this library has several
|
||||
important objects:
|
||||
|
||||
| Name of variable | Description | Where to get? (Examples) |
|
||||
|:----------------:|:-----------:|:------------------------:|
|
||||
| executor | [RequestsExecutor](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/RequestsExecutor.kt) | [Ktor RequestExecutor realisation](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt) |
|
||||
* [RequestsExecutor](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/RequestsExecutor.kt)
|
||||
* [Requests](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests)
|
||||
* [Types](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types)
|
||||
|
||||
## Requests Examples
|
||||
### Types
|
||||
|
||||
### Get Me
|
||||
Types declare different objects representation. For example, `Chat` for now represented as
|
||||
interface and has several realisations:
|
||||
|
||||
* PrivateChat
|
||||
* GroupChat
|
||||
* SupergroupChat
|
||||
* ChannelChat
|
||||
|
||||
Instead of common garbage with all information as in original [Chat](https://core.telegram.org/bots/api#chat),
|
||||
here it was separated for more obvious difference between chats types and their possible content.
|
||||
|
||||
The same principle work with a lot of others things in this Telegram bot API.
|
||||
|
||||
### Requests
|
||||
|
||||
Requests usually are very simple objects, but some of them are using their own
|
||||
build factories. For example, the next code show, how to get information about bot:
|
||||
|
||||
```kotlin
|
||||
executor.execute(GetMe())
|
||||
val requestsExecutor: RequestsExecutor = ...
|
||||
requestsExecutor.execute(GetMe())
|
||||
```
|
||||
|
||||
The result type of [GetMe](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/GetMe) request is
|
||||
[User](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/User). In fact, in this result must contain
|
||||
`isBot` equal to `true` always.
|
||||
|
||||
|
||||
### RequestsExecutor
|
||||
|
||||
It is base object which can be used to execute requests in API. For now by default included Ktor
|
||||
realisation of `RequestsExecutor`, but it is possible, that in future it will be extracted in separated
|
||||
project. How to create `RequestsExecutor`:
|
||||
|
||||
```kotlin
|
||||
val requestsExecutor = KtorRequestsExecutor(TOKEN)
|
||||
```
|
||||
|
||||
As a result you will receive `User` object. This object used as is now (as in API documentation), but it is possible
|
||||
that this class will be renamed to `RawUser` and you will be able to get real realisation of this object like `Bot` (in
|
||||
cases when `isBot` == `true`) or `User` (otherwise)
|
||||
Here `KtorRequestsExecutor` - default realisation with Ktor. `TOKEN` is just a token of bot which was retrieved
|
||||
according to [instruction](https://core.telegram.org/bots#3-how-do-i-create-a-bot).
|
||||
|
||||
Besides, for correct usage of this, you must implement in your project both one of engines for client and server
|
||||
Ktor libraries:
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
// ...
|
||||
implementation "io.ktor:ktor-server-cio:$ktor_version"
|
||||
implementation "io.ktor:ktor-client-okhttp:$ktor_version"
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
It is able to avoid using of `server` dependency in case if will not be used `Webhook`s. In this case,
|
||||
dependencies list will be simplify:
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
// ...
|
||||
implementation "io.ktor:ktor-client-okhttp:$ktor_version"
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Here was used `okhttp` realisation of client, but there are several others engines for Ktor. More information
|
||||
available on ktor.io site for [client](https://ktor.io/clients/http-client/engines.html) and [server](https://ktor.io/quickstart/artifacts.html)
|
||||
engines.
|
||||
|
||||
## Getting updates
|
||||
|
||||
@ -95,3 +154,22 @@ Template for Nginx server config you can find in [this gist](https://gist.github
|
||||
For webhook you can provide `File` with public part of certificate, `URL` where bot will be available and inner `PORT` which
|
||||
will be used to start receiving of updates. Actually, you can skip passing of `File` when you have something like
|
||||
nginx for proxy forwarding.
|
||||
|
||||
In case of using `nginx` with reverse-proxy config, setting up of Webhook will look like:
|
||||
|
||||
```kotlin
|
||||
requestsExecutor.setWebhook(
|
||||
WEBHOOK_URL,
|
||||
INTERNAL_PORT,
|
||||
filter,
|
||||
ENGINE_FACTORY
|
||||
)
|
||||
```
|
||||
|
||||
Here:
|
||||
|
||||
* `WEBHOOK_URL` - the url which will be used by Telegram system to send updates
|
||||
* `INTERNAL_PORT` - the port which will be used in bot for listening of updates
|
||||
* `filter` - instance of [UpdatesFilter](src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/UpdatesFilter.kt),
|
||||
which will be used to filter incoming updates
|
||||
* `ENGINE_FACTORY` - used factory name, for example, `CIO` in case of usage `io.ktor:ktor-server-cio` as server engine
|
||||
|
13
build.gradle
13
build.gradle
@ -1,4 +1,4 @@
|
||||
project.version = "0.13.0"
|
||||
project.version = "0.14.0"
|
||||
project.group = "com.github.insanusmokrassar"
|
||||
|
||||
buildscript {
|
||||
@ -26,7 +26,6 @@ repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url "https://kotlin.bintray.com/kotlinx" }
|
||||
maven { url "https://dl.bintray.com/kotlin/ktor" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -35,14 +34,10 @@ dependencies {
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$kotlin_serialisation_runtime_version"
|
||||
implementation "joda-time:joda-time:$joda_time_version"
|
||||
|
||||
implementation "io.ktor:ktor-client-core:$ktor_version"
|
||||
implementation "io.ktor:ktor-client-okhttp:$ktor_version"
|
||||
implementation "io.ktor:ktor-client:$ktor_version"
|
||||
|
||||
implementation "io.ktor:ktor-server-core:$ktor_version"
|
||||
implementation "io.ktor:ktor-server-netty:$ktor_version"
|
||||
|
||||
// Use JUnit test framework
|
||||
testImplementation 'junit:junit:4.12'
|
||||
implementation "io.ktor:ktor-server:$ktor_version"
|
||||
implementation "io.ktor:ktor-server-host-common:$ktor_version"
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
|
@ -1,9 +1,9 @@
|
||||
kotlin.code.style=official
|
||||
kotlin_version=1.3.30
|
||||
kotlin_coroutines_version=1.2.0
|
||||
kotlin_version=1.3.31
|
||||
kotlin_coroutines_version=1.2.1
|
||||
kotlin_serialisation_runtime_version=0.11.0
|
||||
joda_time_version=2.10.1
|
||||
ktor_version=1.1.3
|
||||
ktor_version=1.1.4
|
||||
|
||||
gradle_bintray_plugin_version=1.8.4
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI
|
||||
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.KtorRequestsExecutor
|
||||
import io.ktor.client.engine.okhttp.OkHttp
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runBlocking {
|
||||
KtorRequestsExecutor(
|
||||
args[0],
|
||||
OkHttp.create()
|
||||
).apply {
|
||||
// It is just template of creating requests executor
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.RetryAfterError
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.HttpClientCall
|
||||
import io.ktor.client.engine.HttpClientEngine
|
||||
import io.ktor.client.engine.okhttp.OkHttp
|
||||
import io.ktor.util.cio.toByteArray
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.io.charsets.Charset
|
||||
@ -20,7 +19,7 @@ import kotlinx.serialization.json.Json
|
||||
|
||||
class KtorRequestsExecutor(
|
||||
token: String,
|
||||
private val client: HttpClient = HttpClient(OkHttp),
|
||||
private val client: HttpClient = HttpClient(),
|
||||
hostUrl: String = "https://api.telegram.org",
|
||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||
excludeDefaultFactories: Boolean = false,
|
||||
@ -29,11 +28,11 @@ class KtorRequestsExecutor(
|
||||
) : BaseRequestsExecutor(token, hostUrl) {
|
||||
constructor(
|
||||
token: String,
|
||||
engine: HttpClientEngine = OkHttp.create(),
|
||||
engine: HttpClientEngine? = null,
|
||||
hostUrl: String = "https://api.telegram.org"
|
||||
) : this(
|
||||
token,
|
||||
HttpClient(engine),
|
||||
engine ?.let { HttpClient(engine) } ?: HttpClient(),
|
||||
hostUrl
|
||||
)
|
||||
|
||||
@ -61,7 +60,9 @@ class KtorRequestsExecutor(
|
||||
if (call == null) {
|
||||
throw IllegalArgumentException("Can't execute request: $request")
|
||||
}
|
||||
val content = call.response.content.toByteArray().toString(Charset.defaultCharset())
|
||||
val content = call.response.use {
|
||||
it.content.toByteArray().toString(Charsets.UTF_8)
|
||||
}
|
||||
val responseObject = jsonFormatter.parse(
|
||||
Response.serializer(request.resultSerializer()),
|
||||
content
|
||||
|
@ -1,32 +0,0 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor
|
||||
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.ProxySettings
|
||||
import io.ktor.http.HttpHeaders
|
||||
import okhttp3.Credentials
|
||||
import okhttp3.OkHttpClient
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Proxy
|
||||
|
||||
fun OkHttpClient.Builder.useWith(proxySettings: ProxySettings) {
|
||||
proxy(
|
||||
Proxy(
|
||||
Proxy.Type.SOCKS,
|
||||
InetSocketAddress(
|
||||
proxySettings.host,
|
||||
proxySettings.port
|
||||
)
|
||||
)
|
||||
)
|
||||
proxySettings.password ?.let {
|
||||
password ->
|
||||
proxyAuthenticator {
|
||||
_, response ->
|
||||
response.request().newBuilder().apply {
|
||||
addHeader(
|
||||
HttpHeaders.ProxyAuthorization,
|
||||
Credentials.basic(proxySettings.username ?: "", password)
|
||||
)
|
||||
}.build()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base
|
||||
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.KtorCallFactory
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.HttpClientCall
|
||||
import io.ktor.client.call.call
|
||||
import io.ktor.client.request.accept
|
||||
import io.ktor.client.request.url
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpMethod
|
||||
|
||||
abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||
private val methodsCache: MutableMap<String, String> = mutableMapOf()
|
||||
override suspend fun <T : Any> prepareCall(
|
||||
client: HttpClient,
|
||||
baseUrl: String,
|
||||
request: Request<T>
|
||||
): HttpClientCall? {
|
||||
val preparedBody = prepareCallBody(client, baseUrl, request) ?: return null
|
||||
|
||||
return client.call {
|
||||
url(
|
||||
methodsCache[request.method()] ?: "$baseUrl/${request.method()}".also {
|
||||
methodsCache[request.method()] = it
|
||||
}
|
||||
)
|
||||
method = HttpMethod.Post
|
||||
accept(ContentType.Application.Json)
|
||||
|
||||
body = preparedBody
|
||||
build()
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun <T : Any> prepareCallBody(
|
||||
client: HttpClient,
|
||||
baseUrl: String,
|
||||
request: Request<T>
|
||||
): Any?
|
||||
}
|
@ -1,48 +1,37 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base
|
||||
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.KtorCallFactory
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.*
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.utils.mapWithCommonValues
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.HttpClientCall
|
||||
import io.ktor.client.call.call
|
||||
import io.ktor.client.request.accept
|
||||
import io.ktor.client.request.forms.MultiPartFormDataContent
|
||||
import io.ktor.client.request.forms.formData
|
||||
import io.ktor.client.request.url
|
||||
import io.ktor.http.*
|
||||
|
||||
class MultipartRequestCallFactory : KtorCallFactory {
|
||||
override suspend fun <T: Any> prepareCall(
|
||||
class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
||||
|
||||
override fun <T : Any> prepareCallBody(
|
||||
client: HttpClient,
|
||||
baseUrl: String,
|
||||
request: Request<T>
|
||||
): HttpClientCall? = (request as? MultipartRequest) ?.let {
|
||||
castedRequest ->
|
||||
client.call {
|
||||
url("$baseUrl/${castedRequest.method()}")
|
||||
method = HttpMethod.Post
|
||||
accept(ContentType.Application.Json)
|
||||
body = MultiPartFormDataContent(
|
||||
formData {
|
||||
val params = castedRequest.paramsJson.mapWithCommonValues()
|
||||
for ((key, value) in castedRequest.mediaMap + params) {
|
||||
when (value) {
|
||||
is MultipartFile -> append(
|
||||
key,
|
||||
value.file.asInput(),
|
||||
Headers.build {
|
||||
append(HttpHeaders.ContentType, value.mimeType)
|
||||
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
|
||||
}
|
||||
)
|
||||
is FileId -> append(key, value.fileId)
|
||||
else -> append(key, value.toString())
|
||||
}
|
||||
): Any? = (request as? MultipartRequest) ?.let { castedRequest ->
|
||||
MultiPartFormDataContent(
|
||||
formData {
|
||||
val params = castedRequest.paramsJson.mapWithCommonValues()
|
||||
for ((key, value) in castedRequest.mediaMap + params) {
|
||||
when (value) {
|
||||
is MultipartFile -> append(
|
||||
key,
|
||||
value.file.asInput(),
|
||||
Headers.build {
|
||||
append(HttpHeaders.ContentType, value.mimeType)
|
||||
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
|
||||
}
|
||||
)
|
||||
is FileId -> append(key, value.fileId)
|
||||
else -> append(key, value.toString())
|
||||
}
|
||||
}
|
||||
)
|
||||
build()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
@ -1,36 +1,23 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base
|
||||
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.KtorCallFactory
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.*
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.utils.toJsonWithoutNulls
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.HttpClientCall
|
||||
import io.ktor.client.call.call
|
||||
import io.ktor.client.request.accept
|
||||
import io.ktor.client.request.url
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpMethod
|
||||
import io.ktor.http.content.TextContent
|
||||
|
||||
class SimpleRequestCallFactory : KtorCallFactory {
|
||||
override suspend fun <T: Any> prepareCall(
|
||||
class SimpleRequestCallFactory : AbstractRequestCallFactory() {
|
||||
override fun <T : Any> prepareCallBody(
|
||||
client: HttpClient,
|
||||
baseUrl: String,
|
||||
request: Request<T>
|
||||
): HttpClientCall? = (request as? SimpleRequest<T>) ?.let {
|
||||
castedRequest ->
|
||||
client.call {
|
||||
url("$baseUrl/${castedRequest.method()}")
|
||||
method = HttpMethod.Post
|
||||
accept(ContentType.Application.Json)
|
||||
): Any? = (request as? SimpleRequest<T>) ?.let { _ ->
|
||||
val content = request.toJsonWithoutNulls(SimpleRequestSerializer).toString()
|
||||
|
||||
val content = request.toJsonWithoutNulls(SimpleRequestSerializer).toString()
|
||||
|
||||
body = TextContent(
|
||||
content,
|
||||
ContentType.Application.Json
|
||||
)
|
||||
build()
|
||||
}
|
||||
TextContent(
|
||||
content,
|
||||
ContentType.Application.Json
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI.bot
|
||||
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.useWith
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.ProxySettings
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
@Deprecated(
|
||||
"Replaced in settings package",
|
||||
ReplaceWith("ProxySettings", "com.github.insanusmokrassar.TelegramBotAPI.bot.settings.ProxySettings")
|
||||
)
|
||||
typealias ProxySettings = com.github.insanusmokrassar.TelegramBotAPI.bot.settings.ProxySettings
|
||||
|
||||
|
||||
@Deprecated(
|
||||
"Replaced in Ktor package",
|
||||
ReplaceWith("useWith", "com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.useWith")
|
||||
)
|
||||
fun OkHttpClient.Builder.useWith(proxySettings: ProxySettings) = useWith(proxySettings)
|
@ -64,6 +64,7 @@ const val inlineMessageIdField = "inline_message_id"
|
||||
const val callbackDataField = "callback_data"
|
||||
const val callbackQueryIdField = "callback_query_id"
|
||||
const val inlineQueryIdField = "inline_query_id"
|
||||
const val inlineKeyboardField = "inline_keyboard"
|
||||
const val showAlertField = "show_alert"
|
||||
const val cachedTimeField = "cached_time"
|
||||
const val foursquareIdField = "foursquare_id"
|
||||
|
@ -1,5 +1,10 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardButtons
|
||||
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable(InlineKeyboardButtonSerializer::class)
|
||||
interface InlineKeyboardButton {
|
||||
val text: String
|
||||
}
|
||||
}
|
||||
|
||||
object InlineKeyboardButtonSerializer : KSerializer<InlineKeyboardButton> by ContextSerializer(InlineKeyboardButton::class)
|
||||
|
@ -1,16 +1,12 @@
|
||||
package com.github.insanusmokrassar.TelegramBotAPI.types.buttons
|
||||
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardButtons.InlineKeyboardButton
|
||||
import com.github.insanusmokrassar.TelegramBotAPI.types.inlineKeyboardField
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.internal.ArrayListSerializer
|
||||
|
||||
@Serializable
|
||||
data class InlineKeyboardMarkup(
|
||||
@SerialName("inline_keyboard")
|
||||
@Serializable(with = KeyboardSerializer::class)
|
||||
@SerialName(inlineKeyboardField)
|
||||
val keyboard: Matrix<InlineKeyboardButton>
|
||||
) : KeyboardMarkup
|
||||
|
||||
object KeyboardSerializer : KSerializer<Matrix<InlineKeyboardButton>> by ArrayListSerializer(
|
||||
ArrayListSerializer(ContextSerializer(InlineKeyboardButton::class))
|
||||
)
|
||||
|
@ -12,21 +12,20 @@ data class AnonymousForwardedMessage(
|
||||
val senderName: String
|
||||
) : ForwardedMessage()
|
||||
|
||||
sealed class PublicForwardedMessage : ForwardedMessage() {
|
||||
abstract val messageId: MessageIdentifier
|
||||
abstract val from: User?
|
||||
}
|
||||
|
||||
data class CommonForwardedMessage(
|
||||
override val messageId: MessageIdentifier,
|
||||
data class UserForwardedMessage(
|
||||
override val dateOfOriginal: TelegramDate,
|
||||
override val from: User
|
||||
) : PublicForwardedMessage()
|
||||
val from: User
|
||||
) : ForwardedMessage()
|
||||
|
||||
@Deprecated(
|
||||
"Renamed according to correct meaning",
|
||||
ReplaceWith("UserForwardedMessage", "com.github.insanusmokrassar.TelegramBotAPI.types.message.UserForwardedMessage")
|
||||
)
|
||||
typealias CommonForwardedMessage = UserForwardedMessage
|
||||
|
||||
data class ForwardedFromChannelMessage(
|
||||
override val messageId: MessageIdentifier,
|
||||
override val dateOfOriginal: TelegramDate,
|
||||
override val from: User?,
|
||||
val messageId: MessageIdentifier,
|
||||
val channelChat: Chat,
|
||||
val signature: String? = null
|
||||
) : PublicForwardedMessage()
|
||||
) : ForwardedMessage()
|
||||
|
@ -134,26 +134,22 @@ data class RawMessage(
|
||||
@Transient
|
||||
private val forwarded: ForwardedMessage? by lazy {
|
||||
forward_date ?: return@lazy null // According to the documentation, now any forwarded message contains this field
|
||||
forward_from_message_id ?.let {
|
||||
forward_from ?: throw IllegalStateException("For common forwarded messages author of original message declared as set up required")
|
||||
forward_from_chat ?.let {
|
||||
ForwardedFromChannelMessage(
|
||||
forward_from_message_id,
|
||||
forward_date,
|
||||
forward_from,
|
||||
forward_from_chat.extractChat(),
|
||||
forward_signature
|
||||
)
|
||||
} ?: CommonForwardedMessage(
|
||||
forward_from_message_id,
|
||||
forward_date,
|
||||
forward_from
|
||||
)
|
||||
} ?: forward_sender_name ?.let {
|
||||
AnonymousForwardedMessage(
|
||||
when {
|
||||
forward_sender_name != null -> AnonymousForwardedMessage(
|
||||
forward_date,
|
||||
forward_sender_name
|
||||
)
|
||||
forward_from_chat != null -> ForwardedFromChannelMessage(
|
||||
forward_date,
|
||||
forward_from_message_id ?: throw IllegalStateException("Channel forwarded message must contain message id, but was not"),
|
||||
forward_from_chat.extractChat(),
|
||||
forward_signature
|
||||
)
|
||||
forward_from != null -> UserForwardedMessage(
|
||||
forward_date,
|
||||
forward_from
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@ import io.ktor.response.respond
|
||||
import io.ktor.routing.post
|
||||
import io.ktor.routing.routing
|
||||
import io.ktor.server.engine.*
|
||||
import io.ktor.server.netty.Netty
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.serialization.json.Json
|
||||
@ -36,12 +35,12 @@ import java.util.concurrent.TimeUnit
|
||||
suspend fun RequestsExecutor.setWebhook(
|
||||
url: String,
|
||||
port: Int,
|
||||
engineFactory: ApplicationEngineFactory<*, *>,
|
||||
certificate: InputFile? = null,
|
||||
privateKeyConfig: WebhookPrivateKeyConfig? = null,
|
||||
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
|
||||
allowedUpdates: List<String>? = null,
|
||||
maxAllowedConnections: Int? = null,
|
||||
engineFactory: ApplicationEngineFactory<*, *> = Netty,
|
||||
block: UpdateReceiver<Update>
|
||||
): Job {
|
||||
val executeDeferred = certificate ?.let {
|
||||
@ -69,20 +68,17 @@ suspend fun RequestsExecutor.setWebhook(
|
||||
val env = applicationEngineEnvironment {
|
||||
|
||||
module {
|
||||
fun Application.main() {
|
||||
routing {
|
||||
post {
|
||||
val deserialized = call.receiveText()
|
||||
val update = Json.nonstrict.parse(
|
||||
RawUpdate.serializer(),
|
||||
deserialized
|
||||
)
|
||||
updatesChannel.send(update.asUpdate)
|
||||
call.respond("Ok")
|
||||
}
|
||||
routing {
|
||||
post {
|
||||
val deserialized = call.receiveText()
|
||||
val update = Json.nonstrict.parse(
|
||||
RawUpdate.serializer(),
|
||||
deserialized
|
||||
)
|
||||
updatesChannel.send(update.asUpdate)
|
||||
call.respond("Ok")
|
||||
}
|
||||
}
|
||||
main()
|
||||
}
|
||||
privateKeyConfig ?.let {
|
||||
sslConnector(
|
||||
@ -140,19 +136,19 @@ suspend fun RequestsExecutor.setWebhook(
|
||||
url: String,
|
||||
port: Int,
|
||||
filter: UpdatesFilter,
|
||||
engineFactory: ApplicationEngineFactory<*, *>,
|
||||
certificate: InputFile? = null,
|
||||
privateKeyConfig: WebhookPrivateKeyConfig? = null,
|
||||
scope: CoroutineScope = CoroutineScope(Executors.newFixedThreadPool(4).asCoroutineDispatcher()),
|
||||
maxAllowedConnections: Int? = null,
|
||||
engineFactory: ApplicationEngineFactory<*, *> = Netty
|
||||
maxAllowedConnections: Int? = null
|
||||
): Job = setWebhook(
|
||||
url,
|
||||
port,
|
||||
engineFactory,
|
||||
certificate,
|
||||
privateKeyConfig,
|
||||
scope,
|
||||
filter.allowedUpdates,
|
||||
maxAllowedConnections,
|
||||
engineFactory,
|
||||
filter.asUpdateReceiver
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user