mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-11-16 03:50:24 +00:00
Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d2c299301a | |||
| 25fb6b2b46 | |||
| 5b5de5253c | |||
| 9a7dd6ec9a | |||
| 4085f721be | |||
| ffc915cae1 | |||
| a6c90b3df5 | |||
| a6d9fa6ce3 | |||
| 7fd2442f8b | |||
| 8b37ecea9e | |||
| 35fc9f60df | |||
| 68e89dc1ad | |||
| 129fb31b74 | |||
| a2c353ca41 | |||
| cb74abfce5 | |||
| ca7314923e | |||
| 74f625a53a | |||
| 3a5fed3dd9 | |||
| 6158143220 | |||
| f8182ddb85 | |||
| b7c3f9f607 | |||
| 8763ea23fa | |||
| b412e7b3b7 | |||
| 98e5d182bb | |||
| ffc0f5abb7 | |||
| 816cf00dac | |||
| e34bc7453e | |||
| 3b2ccbf33b | |||
| 6ecfbdf56d | |||
| b49e1c50f5 | |||
| d7389dfcfe | |||
| cf5cee3e53 | |||
| 8593263506 | |||
| 4422a4d09b | |||
| 9ecb50e377 | |||
| 8a4b40c6ec | |||
| bba667db30 | |||
| ca0d256bbb | |||
| dc2fd07632 | |||
| 32fe008eef | |||
| 2b938903b6 | |||
| 080db09d2c | |||
| 0efa52fe00 | |||
| c4214798e3 | |||
| fdf510153d | |||
| edb16d7107 | |||
| c49f400201 | |||
| db7de6edf8 | |||
| a0b14233e0 | |||
| 1a479706e2 | |||
| 2719e166a8 | |||
| 051684db23 | |||
| 805cec76ce | |||
| 899c195fd5 | |||
| f5937fc4d6 | |||
| 8cf7b349df | |||
| bf8f8b9e6f | |||
| edc0b1c492 | |||
| a85d58aac1 | |||
| 10860e1bb2 | |||
| 46e6eeca9d | |||
| 80be86454d | |||
| d5f5a0e30b | |||
| 826c27874d | |||
| 4e917e8cf8 | |||
| 051210caf5 | |||
| 284fe58848 | |||
| 38c9732da5 | |||
| dee13c03ae | |||
| 6103b70a47 | |||
| 96ffae2062 | |||
| 4180721aed | |||
| 4ab0845333 | |||
| 3f9a4e95a3 | |||
| 834d60ff16 | |||
| 650d96974f | |||
| 7f5cd0567b |
3
.github/workflows/greetings.yml
vendored
3
.github/workflows/greetings.yml
vendored
@@ -5,6 +5,9 @@ on: [pull_request, issues]
|
||||
jobs:
|
||||
greeting:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1
|
||||
with:
|
||||
|
||||
2
.github/workflows/kdocs.yml
vendored
2
.github/workflows/kdocs.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
java-version: 17
|
||||
- name: Build
|
||||
run: ./gradlew dokkaHtmlMultiModule
|
||||
- name: Publish KDocs
|
||||
|
||||
9
.github/workflows/packages_publishing.yml
vendored
9
.github/workflows/packages_publishing.yml
vendored
@@ -7,9 +7,9 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
java-version: 17
|
||||
- name: Setup LibCurl
|
||||
run: sudo apt install -y libcurl4-openssl-dev
|
||||
run: sudo apt update && sudo apt install -y libcurl4-openssl-dev
|
||||
- name: Rewrite version
|
||||
run: |
|
||||
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
|
||||
@@ -22,9 +22,10 @@ jobs:
|
||||
run: ./gradlew build
|
||||
- name: Publish to Gitea
|
||||
continue-on-error: true
|
||||
run: ./gradlew publishAllPublicationsToGiteaRepository
|
||||
run: ./gradlew publishAllPublicationsToInmoNexusRepository
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
INMONEXUS_USER: ${{ secrets.INMONEXUS_USER }}
|
||||
INMONEXUS_PASSWORD: ${{ secrets.INMONEXUS_PASSWORD }}
|
||||
- name: Publish to GithubPackages
|
||||
continue-on-error: true
|
||||
run: ./gradlew publishAllPublicationsToGithubPackagesRepository --no-parallel
|
||||
|
||||
71
CHANGELOG.md
71
CHANGELOG.md
@@ -1,5 +1,76 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 9.4.3
|
||||
|
||||
**IetfLanguageCode has been renamed to IetfLang in MicroUtils**
|
||||
|
||||
* `Version`:
|
||||
* `Kotlin`: `1.9.21` -> `1.9.22`
|
||||
* `MicroUtils`: `0.20.19` -> `0.20.23`
|
||||
|
||||
## 9.4.2
|
||||
|
||||
* `Version`:
|
||||
* `Serialization`: `1.6.1` -> `1.6.2`
|
||||
* `Ktor`: `2.3.6` -> `2.3.7`
|
||||
* `MicroUtils`: `0.20.15` -> `0.20.19`
|
||||
* `UUID`: `0.8.1` -> `0.8.2`
|
||||
|
||||
## 9.4.1
|
||||
|
||||
* Replace warning about two bots from `LongPolling` to `DefaultKtorRequestsExecutor`
|
||||
|
||||
## 9.4.0
|
||||
|
||||
* `Version`:
|
||||
* `Kotlin`: `1.9.20` -> `1.9.21`
|
||||
* `Serialization`: `1.6.0` -> `1.6.1`
|
||||
* `Ktor`: `2.3.5` -> `2.3.6`
|
||||
* `MicroUtils`: `0.20.12` -> `0.20.15`
|
||||
|
||||
## 9.3.0
|
||||
|
||||
This release become possible thanks to [Anton Lakotka](https://youtrack.jetbrains.com/users/anton.lakotka)
|
||||
|
||||
**THIS RELEASE CONTAINS UPDATES UP TO RELEASE CANDIDATES VERSIONS**
|
||||
|
||||
**UPDATE MAY HAVE BREAKING CHANGES**
|
||||
|
||||
**SINCE THIS UPDATE IT WILL BE REQUIRED TO USE JDK 17+ FOR DEVELOPMENT**
|
||||
|
||||
* `Version`:
|
||||
* `Kotlin`: `1.8.22` -> `1.9.20`
|
||||
* `Serialization`: `1.5.1` -> `1.6.0`
|
||||
* `KorLibs`: `4.0.3` -> `4.0.10`
|
||||
* `UUID`: `0.7.1` -> `0.8.1`
|
||||
* `Ktor`: `2.3.4` -> `2.3.5`
|
||||
* `MicroUtils`: `0.19.9` -> `0.20.12`
|
||||
|
||||
## 9.2.4
|
||||
|
||||
* `Utils`:
|
||||
* New extensions `*.parseCommandsWithNamedArgs`
|
||||
* `BehaviourBuilder`:
|
||||
* In expectaters and triggers of `commands` add `*WithNamedArgs` variants
|
||||
* In expectaters and triggers of `commands` add opportunity to use custom separator
|
||||
|
||||
## 9.2.3
|
||||
|
||||
* `Core`:
|
||||
* Fix in `VoiceContent#createResend`
|
||||
|
||||
## 9.2.2
|
||||
|
||||
* `Core`:
|
||||
* Fix of [#793](https://github.com/InsanusMokrassar/ktgbotapi/issues/793): Add `PreviewChat`
|
||||
|
||||
## 9.2.1
|
||||
|
||||
* `Version`:
|
||||
* `Ktor`: `2.3.3` -> `2.3.4`
|
||||
* `Core`:
|
||||
* All `ChatMember` inheritors have fixes `status` field
|
||||
|
||||
## 9.2.0
|
||||
|
||||
**Add support of [Telegram Bots API 6.9](https://core.telegram.org/bots/api-changelog#september-22-2023)**
|
||||
|
||||
@@ -16,6 +16,7 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.dokka)
|
||||
alias(libs.plugins.versions)
|
||||
}
|
||||
|
||||
// temporal crutch until legacy tests will be stabled or legacy target will be removed
|
||||
@@ -24,7 +25,7 @@ allprojects {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
google()
|
||||
maven { url "https://git.inmo.dev/api/packages/InsanusMokrassar/maven" }
|
||||
maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
|
||||
}
|
||||
if (it != rootProject.findProject("docs")) {
|
||||
tasks.whenTaskAdded { task ->
|
||||
|
||||
@@ -55,7 +55,7 @@ Object callback = {
|
||||
|
||||
sourceLink {
|
||||
localDirectory.set(file("../"))
|
||||
remoteUrl.set(new URL("https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/"))
|
||||
remoteUrl.set(new URL("https://github.com/InsanusMokrassar/ktgbotapi/tree/master"))
|
||||
remoteLineSuffix.set("#L")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@ kotlin.incremental=true
|
||||
kotlin.incremental.js=true
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=9.2.0
|
||||
library_version=9.4.3
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
[versions]
|
||||
|
||||
kotlin = "1.8.22"
|
||||
kotlin-serialization = "1.5.1"
|
||||
kotlin = "1.9.22"
|
||||
kotlin-serialization = "1.6.2"
|
||||
kotlin-coroutines = "1.7.3"
|
||||
|
||||
javax-activation = "1.1.1"
|
||||
|
||||
korlibs = "4.0.3"
|
||||
uuid = "0.7.1"
|
||||
ktor = "2.3.3"
|
||||
korlibs = "4.0.10"
|
||||
uuid = "0.8.2"
|
||||
ktor = "2.3.7"
|
||||
|
||||
ksp = "1.8.22-1.0.11"
|
||||
kotlin-poet = "1.14.2"
|
||||
ksp = "1.9.21-1.0.16"
|
||||
kotlin-poet = "1.15.3"
|
||||
|
||||
microutils = "0.19.9"
|
||||
microutils = "0.20.23"
|
||||
kslog = "1.3.1"
|
||||
|
||||
versions = "0.50.0"
|
||||
|
||||
github-release-plugin = "2.4.1"
|
||||
dokka = "1.8.20"
|
||||
dokka = "1.9.10"
|
||||
|
||||
[libraries]
|
||||
|
||||
@@ -52,6 +55,8 @@ microutils-languageCodes = { module = "dev.inmo:micro_utils.language_codes", ver
|
||||
microutils-ktor-common = { module = "dev.inmo:micro_utils.ktor.common", version.ref = "microutils" }
|
||||
microutils-fsm-common = { module = "dev.inmo:micro_utils.fsm.common", version.ref = "microutils" }
|
||||
|
||||
kslog = { module = "dev.inmo:kslog", version.ref = "kslog" }
|
||||
|
||||
# ksp dependencies
|
||||
|
||||
kotlin-poet = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlin-poet" }
|
||||
@@ -71,3 +76,4 @@ kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
||||
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||
kotlin-dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
|
||||
versions = { id = "com.github.ben-manes.versions", version.ref = "versions" }
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
|
||||
@@ -5,7 +5,7 @@ kotlin {
|
||||
jvm {
|
||||
compilations.main {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
jvmTarget = "17"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ kotlin {
|
||||
}
|
||||
linuxX64()
|
||||
mingwX64()
|
||||
linuxArm64()
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
@@ -40,10 +41,18 @@ kotlin {
|
||||
implementation libs.kotlin.test.junit
|
||||
}
|
||||
}
|
||||
all {
|
||||
languageSettings {
|
||||
optIn('dev.inmo.tgbotapi.utils.RiskFeature')
|
||||
optIn('dev.inmo.tgbotapi.utils.PreviewFeature')
|
||||
optIn('dev.inmo.micro_utils.common.Warning')
|
||||
optIn('dev.inmo.micro_utils.common.PreviewFeature')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
task javadocsJar(type: Jar) {
|
||||
archiveClassifier.convention("javadoc")
|
||||
archiveClassifier.set("javadoc")
|
||||
archiveClassifier = 'javadoc'
|
||||
}
|
||||
|
||||
publishing {
|
||||
@@ -20,22 +19,22 @@ publishing {
|
||||
}
|
||||
|
||||
developers {
|
||||
|
||||
|
||||
developer {
|
||||
id = "InsanusMokrassar"
|
||||
name = "Ovsiannikov Aleksei"
|
||||
email = "ovsyannikov.alexey95@gmail.com"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
licenses {
|
||||
|
||||
|
||||
license {
|
||||
name = "Apache Software License 2.0"
|
||||
url = "https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
@@ -43,58 +42,77 @@ publishing {
|
||||
maven {
|
||||
name = "GithubPackages"
|
||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI")
|
||||
|
||||
|
||||
credentials {
|
||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
|
||||
if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
|
||||
maven {
|
||||
name = "Gitea"
|
||||
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
|
||||
|
||||
credentials(HttpHeaderCredentials) {
|
||||
name = "Authorization"
|
||||
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
|
||||
name = "InmoNexus"
|
||||
url = uri("https://nexus.inmo.dev/repository/maven-releases/")
|
||||
|
||||
credentials {
|
||||
username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
|
||||
password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
|
||||
}
|
||||
|
||||
authentication {
|
||||
header(HttpHeaderAuthentication)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
||||
|
||||
|
||||
credentials {
|
||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
||||
apply plugin: 'signing'
|
||||
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
|
||||
|
||||
sign publishing.publications
|
||||
}
|
||||
|
||||
|
||||
task signAll {
|
||||
tasks.withType(Sign).forEach {
|
||||
dependsOn(it)
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround to make android sign operations depend on signing tasks
|
||||
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
|
||||
def signingTasks = project.getTasks().withType(Sign.class)
|
||||
mustRunAfter(signingTasks)
|
||||
}
|
||||
// Workaround to make test tasks use sign
|
||||
project.getTasks().withType(Sign.class).configureEach { signTask ->
|
||||
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
|
||||
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
|
||||
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
|
||||
|
||||
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
|
||||
def debugTestTask = tasks.findByName("linkDebugTest$pubName")
|
||||
if (debugTestTask != null) {
|
||||
signTask.mustRunAfter(debugTestTask)
|
||||
}
|
||||
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
|
||||
def testTask = tasks.findByName("compileTestKotlin$pubName")
|
||||
if (testTask != null) {
|
||||
signTask.mustRunAfter(testTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"${project.description}","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"${project.description}","url":"https://insanusmokrassar.github.io/TelegramBotAPI/TelegramBotAPI","vcsUrl":"https://github.com/insanusmokrassar/TelegramBotAPI.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"},{"name":"InmoNexus","url":"https://nexus.inmo.dev/repository/maven-releases/"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.DeleteMyCommands
|
||||
import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
||||
@@ -8,10 +8,10 @@ import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
|
||||
suspend fun TelegramBot.deleteMyCommands(
|
||||
scope: BotCommandScope = BotCommandScopeDefault,
|
||||
languageCode: IetfLanguageCode?
|
||||
languageCode: IetfLang?
|
||||
) = execute(DeleteMyCommands(scope, languageCode))
|
||||
|
||||
suspend fun TelegramBot.deleteMyCommands(
|
||||
scope: BotCommandScope = BotCommandScopeDefault,
|
||||
languageCode: String? = null
|
||||
) = deleteMyCommands(scope, languageCode ?.let(::IetfLanguageCode))
|
||||
) = deleteMyCommands(scope, languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||
import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
||||
@@ -8,10 +8,10 @@ import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
|
||||
suspend fun TelegramBot.getMyCommands(
|
||||
scope: BotCommandScope = BotCommandScopeDefault,
|
||||
languageCode: IetfLanguageCode? = null
|
||||
languageCode: IetfLang? = null
|
||||
) = execute(GetMyCommands(scope, languageCode))
|
||||
|
||||
suspend fun TelegramBot.getMyCommands(
|
||||
scope: BotCommandScope = BotCommandScopeDefault,
|
||||
languageCode: String?
|
||||
) = getMyCommands(scope, languageCode ?.let(::IetfLanguageCode))
|
||||
) = getMyCommands(scope, languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyDescription
|
||||
import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
||||
import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
|
||||
suspend fun TelegramBot.getMyDescription(
|
||||
languageCode: IetfLanguageCode? = null
|
||||
languageCode: IetfLang? = null
|
||||
) = execute(GetMyDescription(languageCode))
|
||||
|
||||
suspend fun TelegramBot.getMyDescription(
|
||||
languageCode: String?
|
||||
) = getMyDescription(languageCode ?.let(::IetfLanguageCode))
|
||||
) = getMyDescription(languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyName
|
||||
import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
||||
import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
|
||||
suspend fun TelegramBot.getMyName(
|
||||
languageCode: IetfLanguageCode? = null
|
||||
languageCode: IetfLang? = null
|
||||
) = execute(GetMyName(languageCode))
|
||||
|
||||
suspend fun TelegramBot.getMyName(
|
||||
languageCode: String?
|
||||
) = getMyName(languageCode ?.let(::IetfLanguageCode))
|
||||
) = getMyName(languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyShortDescription
|
||||
@@ -8,9 +8,9 @@ import dev.inmo.tgbotapi.types.commands.BotCommandScope
|
||||
import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
|
||||
suspend fun TelegramBot.getMyShortDescription(
|
||||
languageCode: IetfLanguageCode? = null
|
||||
languageCode: IetfLang? = null
|
||||
) = execute(GetMyShortDescription(languageCode))
|
||||
|
||||
suspend fun TelegramBot.getMyShortDescription(
|
||||
languageCode: String?
|
||||
) = getMyShortDescription(languageCode ?.let(::IetfLanguageCode))
|
||||
) = getMyShortDescription(languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.SetMyCommands
|
||||
import dev.inmo.tgbotapi.types.BotCommand
|
||||
@@ -10,20 +10,20 @@ import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
suspend fun TelegramBot.setMyCommands(
|
||||
commands: List<BotCommand>,
|
||||
scope: BotCommandScope = BotCommandScopeDefault,
|
||||
languageCode: IetfLanguageCode?
|
||||
languageCode: IetfLang?
|
||||
) = execute(SetMyCommands(commands, scope, languageCode))
|
||||
|
||||
suspend fun TelegramBot.setMyCommands(
|
||||
vararg commands: BotCommand,
|
||||
scope: BotCommandScope = BotCommandScopeDefault,
|
||||
languageCode: IetfLanguageCode?
|
||||
languageCode: IetfLang?
|
||||
) = setMyCommands(commands.toList(), scope, languageCode)
|
||||
|
||||
suspend fun TelegramBot.setMyCommands(
|
||||
commands: List<BotCommand>,
|
||||
scope: BotCommandScope = BotCommandScopeDefault,
|
||||
languageCode: String? = null
|
||||
) = setMyCommands(commands, scope, languageCode ?.let(::IetfLanguageCode))
|
||||
) = setMyCommands(commands, scope, languageCode ?.let(::IetfLang))
|
||||
|
||||
suspend fun TelegramBot.setMyCommands(
|
||||
vararg commands: BotCommand,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyDescription
|
||||
@@ -10,10 +10,10 @@ import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
|
||||
suspend fun TelegramBot.setMyDescription(
|
||||
description: String? = null,
|
||||
languageCode: IetfLanguageCode? = null
|
||||
languageCode: IetfLang? = null
|
||||
) = execute(SetMyDescription(description, languageCode))
|
||||
|
||||
suspend fun TelegramBot.setMyDescription(
|
||||
description: String?,
|
||||
languageCode: String?
|
||||
) = setMyDescription(description, languageCode ?.let(::IetfLanguageCode))
|
||||
) = setMyDescription(description, languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyCommands
|
||||
import dev.inmo.tgbotapi.requests.bot.GetMyName
|
||||
@@ -10,10 +10,10 @@ import dev.inmo.tgbotapi.types.commands.BotCommandScopeDefault
|
||||
|
||||
suspend fun TelegramBot.setMyName(
|
||||
name: String? = null,
|
||||
languageCode: IetfLanguageCode? = null
|
||||
languageCode: IetfLang? = null
|
||||
) = execute(SetMyName(name, languageCode))
|
||||
|
||||
suspend fun TelegramBot.setMyName(
|
||||
name: String?,
|
||||
languageCode: String?
|
||||
) = setMyName(name, languageCode ?.let(::IetfLanguageCode))
|
||||
) = setMyName(name, languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.bot.SetMyShortDescription
|
||||
|
||||
suspend fun TelegramBot.setMyShortDescription(
|
||||
shortDescription: String? = null,
|
||||
languageCode: IetfLanguageCode? = null
|
||||
languageCode: IetfLang? = null
|
||||
) = execute(SetMyShortDescription(shortDescription, languageCode))
|
||||
|
||||
suspend fun TelegramBot.setMyShortDescription(
|
||||
shortDescription: String?,
|
||||
languageCode: String?
|
||||
) = setMyShortDescription(shortDescription, languageCode ?.let(::IetfLanguageCode))
|
||||
) = setMyShortDescription(shortDescription, languageCode ?.let(::IetfLang))
|
||||
|
||||
@@ -13,6 +13,8 @@ kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api project(":tgbotapi.core")
|
||||
api project(":tgbotapi.utils")
|
||||
api project(":tgbotapi.behaviour_builder")
|
||||
api libs.microutils.fsm.common
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api project(":tgbotapi.utils")
|
||||
api project(path: ':tgbotapi.core')
|
||||
api project(path: ':tgbotapi.utils')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.doWithRegistration
|
||||
import dev.inmo.tgbotapi.extensions.utils.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.TelegramBotCommandsDefaults
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgsSources
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithNamedArgs
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.types.BotCommand
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||
@@ -79,35 +83,54 @@ fun Flow<CommonMessage<TextContent>>.requireCommandsWithoutParams() = filter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the commands with their arguments and source messages
|
||||
* Uses [parseCommandsWithArgsSources] on incoming text sources and map them with [CommonMessage]
|
||||
*/
|
||||
fun Flow<CommonMessage<TextContent>>.commandsWithParams(): Flow<Pair<CommonMessage<TextContent>, List<Pair<BotCommandTextSource, Array<TextSource>>>>> = mapNotNull {
|
||||
var currentCommandTextSource: BotCommandTextSource? = null
|
||||
val currentArgs = mutableListOf<TextSource>()
|
||||
val result = mutableListOf<Pair<BotCommandTextSource, Array<TextSource>>>()
|
||||
|
||||
fun addCurrentCommandToResult() {
|
||||
currentCommandTextSource ?.let {
|
||||
result.add(it to currentArgs.toTypedArray())
|
||||
currentArgs.clear()
|
||||
}
|
||||
}
|
||||
|
||||
it.content.textSources.forEach {
|
||||
it.ifBotCommandTextSource {
|
||||
addCurrentCommandToResult()
|
||||
currentCommandTextSource = it
|
||||
return@forEach
|
||||
}
|
||||
currentArgs.add(it)
|
||||
}
|
||||
addCurrentCommandToResult()
|
||||
|
||||
result.toList().takeIf { it.isNotEmpty() } ?.let { result ->
|
||||
it to result
|
||||
}
|
||||
it to it.content.textSources.parseCommandsWithArgsSources().toList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] on incoming text sources and map them with [CommonMessage]
|
||||
*/
|
||||
fun Flow<CommonMessage<TextContent>>.commandsWithArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, Array<String>>>>> = mapNotNull {
|
||||
val commandsWithArgs = it.content.textSources.parseCommandsWithArgs(argsSeparator).toList().ifEmpty {
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
it to commandsWithArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] on incoming text sources and map them with [CommonMessage]
|
||||
*/
|
||||
fun Flow<CommonMessage<TextContent>>.commandsWithArgs(
|
||||
argsSeparator: String
|
||||
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, Array<String>>>>> = commandsWithArgs(Regex(argsSeparator))
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithNamedArgs] on incoming text sources and map them with [CommonMessage]
|
||||
*/
|
||||
fun Flow<CommonMessage<TextContent>>.commandsWithNamedArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, List<Pair<String, String>>>>>> = mapNotNull {
|
||||
val commandsWithArgs = it.content.textSources.parseCommandsWithNamedArgs(argsSeparator, nameArgSeparator).toList().ifEmpty {
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
it to commandsWithArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithNamedArgs] on incoming text sources and map them with [CommonMessage]
|
||||
*/
|
||||
fun Flow<CommonMessage<TextContent>>.commandsWithNamedArgs(
|
||||
argsSeparator: String,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
): Flow<Pair<CommonMessage<TextContent>, List<Pair<String, List<Pair<String, String>>>>>> = commandsWithNamedArgs(Regex(argsSeparator), nameArgSeparator)
|
||||
|
||||
/**
|
||||
* Flat [commandsWithParams]. Each [Pair] of [BotCommandTextSource] and its [Array] of arg text sources will
|
||||
* be associated with its source message
|
||||
|
||||
@@ -11,7 +11,9 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByC
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
|
||||
import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.TelegramBotCommandsDefaults
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithNamedArgs
|
||||
import dev.inmo.tgbotapi.types.BotCommand
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.content.TextMessage
|
||||
@@ -124,6 +126,7 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
|
||||
) = command(
|
||||
commandRegex,
|
||||
@@ -132,7 +135,7 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory
|
||||
) {
|
||||
val args = it.parseCommandsWithParams().let { commandsWithArgs ->
|
||||
val args = it.parseCommandsWithArgs(argsSeparator = argsSeparator).let { commandsWithArgs ->
|
||||
val key = commandsWithArgs.keys.firstOrNull { it.matches(commandRegex) } ?: return@let null
|
||||
commandsWithArgs[key]
|
||||
} ?: emptyArray()
|
||||
@@ -144,12 +147,14 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
|
||||
) = commandWithArgs(
|
||||
command.toRegex(),
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
@@ -158,12 +163,72 @@ suspend fun <BC : BehaviourContext> BC.commandWithArgs(
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
|
||||
) = commandWithArgs(
|
||||
botCommand.command,
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.commandWithNamedArgs(
|
||||
commandRegex: Regex,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
|
||||
) = command(
|
||||
commandRegex,
|
||||
requireOnlyCommandInMessage = false,
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory
|
||||
) {
|
||||
val args = it.parseCommandsWithNamedArgs(argsSeparator = argsSeparator, nameArgSeparator = nameArgSeparator).let { commandsWithArgs ->
|
||||
val key = commandsWithArgs.keys.firstOrNull { it.matches(commandRegex) } ?: return@let null
|
||||
commandsWithArgs[key]
|
||||
} ?: emptyList()
|
||||
scenarioReceiver(it, args)
|
||||
}
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.commandWithNamedArgs(
|
||||
command: String,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
|
||||
) = commandWithNamedArgs(
|
||||
command.toRegex(),
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
nameArgSeparator = nameArgSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.commandWithNamedArgs(
|
||||
botCommand: BotCommand,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
|
||||
) = commandWithNamedArgs(
|
||||
botCommand.command,
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
nameArgSeparator = nameArgSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
@@ -172,21 +237,99 @@ suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
|
||||
): Job = commandWithArgs(commandRegex, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||
): Job = commandWithArgs(
|
||||
commandRegex = commandRegex,
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
||||
command: String,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
|
||||
): Job = onCommandWithArgs(command.toRegex(), initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||
): Job = onCommandWithArgs(
|
||||
commandRegex = command.toRegex(),
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.onCommandWithArgs(
|
||||
botCommand: BotCommand,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, Array<String>>
|
||||
): Job = onCommandWithArgs(botCommand.command, initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||
): Job = onCommandWithArgs(
|
||||
command = botCommand.command,
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.onCommandWithNamedArgs(
|
||||
commandRegex: Regex,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
|
||||
) = commandWithNamedArgs(
|
||||
commandRegex,
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
nameArgSeparator = nameArgSeparator,
|
||||
scenarioReceiver = scenarioReceiver,
|
||||
)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.onCommandWithNamedArgs(
|
||||
command: String,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
|
||||
) = onCommandWithNamedArgs(
|
||||
command.toRegex(),
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
nameArgSeparator = nameArgSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
suspend fun <BC : BehaviourContext> BC.onCommandWithNamedArgs(
|
||||
botCommand: BotCommand,
|
||||
initialFilter: CommonMessageFilter<TextContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, TextMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in TextMessage, Any> = ByChatMessageMarkerFactory,
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
scenarioReceiver: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, TextMessage, List<Pair<String, String>>>
|
||||
) = onCommandWithNamedArgs(
|
||||
botCommand.command,
|
||||
initialFilter = initialFilter,
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory,
|
||||
argsSeparator = argsSeparator,
|
||||
nameArgSeparator = nameArgSeparator,
|
||||
scenarioReceiver = scenarioReceiver
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByC
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
|
||||
import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.content.TextMessage
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
@@ -65,7 +65,7 @@ suspend fun <BC : BehaviourContext> BC.unhandledCommandWithArgs(
|
||||
subcontextUpdatesFilter = subcontextUpdatesFilter,
|
||||
markerFactory = markerFactory
|
||||
) {
|
||||
val args = it.parseCommandsWithParams().let { commandsWithArgs ->
|
||||
val args = it.parseCommandsWithArgs().let { commandsWithArgs ->
|
||||
commandsWithArgs
|
||||
}
|
||||
scenarioReceiver(it, args)
|
||||
|
||||
@@ -4,22 +4,18 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitDeepLinks
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
|
||||
import dev.inmo.tgbotapi.extensions.utils.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.content.TextMessage
|
||||
import dev.inmo.tgbotapi.types.message.textsources.RegularTextSource
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
import io.ktor.http.decodeURLQueryComponent
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.filter
|
||||
|
||||
private val startRegex = Regex("start")
|
||||
suspend fun <BC : BehaviourContext> BC.onDeepLink(
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.behaviour_builder
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
actual var defaultCoroutineScopeProvider: () -> CoroutineScope = { CoroutineScope(Dispatchers.Default) }
|
||||
@@ -31,6 +31,8 @@ kotlin {
|
||||
api libs.microutils.languageCodes
|
||||
|
||||
api libs.ktor.client.core
|
||||
|
||||
api libs.kslog
|
||||
}
|
||||
}
|
||||
commonTest {
|
||||
@@ -55,6 +57,12 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
linuxArm64Main {
|
||||
dependencies {
|
||||
api libs.ktor.client.cio
|
||||
}
|
||||
}
|
||||
|
||||
mingwX64Main {
|
||||
dependencies {
|
||||
api libs.ktor.client.winhttp
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
package dev.inmo.tgbotapi.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
|
||||
/**
|
||||
* All inheritors of this interface have [chat] field and related to this [chat]
|
||||
*/
|
||||
interface WithChat {
|
||||
val chat: Chat
|
||||
interface WithPreviewChat {
|
||||
val chat: PreviewChat
|
||||
}
|
||||
|
||||
/**
|
||||
* All inheritors of this interface have [chat] field and related to this [chat]
|
||||
*/
|
||||
@Deprecated("Renamed", ReplaceWith("WithPreviewChat", "dev.inmo.tgbotapi.abstracts.WithPreviewChat"))
|
||||
typealias WithChat = WithPreviewChat
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor
|
||||
|
||||
import dev.inmo.kslog.common.KSLog
|
||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
||||
import io.ktor.client.*
|
||||
@@ -14,12 +16,35 @@ import kotlinx.serialization.json.Json
|
||||
* * On JS, JVM and MingwX64 platforms it is [dev.inmo.tgbotapi.bot.ktor.base.DefaultKtorRequestsExecutor]
|
||||
* * On LinuxX64 it is [dev.inmo.tgbotapi.bot.ktor.base.MultipleClientKtorRequestsExecutor]
|
||||
*/
|
||||
expect class KtorRequestsExecutor (
|
||||
expect class KtorRequestsExecutor internal constructor(
|
||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||
client: HttpClient,
|
||||
callsFactories: List<KtorCallFactory>,
|
||||
excludeDefaultFactories: Boolean,
|
||||
requestsLimiter: RequestLimiter,
|
||||
jsonFormatter: Json,
|
||||
pipelineStepsHolder: KtorPipelineStepsHolder,
|
||||
logger: KSLog,
|
||||
diff: Unit // just a diff property to know where constructor and where calling function with defaults
|
||||
) : BaseRequestsExecutor
|
||||
|
||||
fun KtorRequestsExecutor(
|
||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||
client: HttpClient = HttpClient(),
|
||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||
excludeDefaultFactories: Boolean = false,
|
||||
requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter,
|
||||
jsonFormatter: Json = nonstrictJsonFormat,
|
||||
pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder
|
||||
) : BaseRequestsExecutor
|
||||
pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder,
|
||||
logger: KSLog = DefaultKTgBotAPIKSLog,
|
||||
) = KtorRequestsExecutor(
|
||||
telegramAPIUrlsKeeper = telegramAPIUrlsKeeper,
|
||||
client = client,
|
||||
callsFactories = callsFactories,
|
||||
excludeDefaultFactories = excludeDefaultFactories,
|
||||
requestsLimiter = requestsLimiter,
|
||||
jsonFormatter = jsonFormatter,
|
||||
pipelineStepsHolder = pipelineStepsHolder,
|
||||
logger = logger,
|
||||
diff = kotlin.Unit,
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor
|
||||
|
||||
import dev.inmo.kslog.common.KSLog
|
||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.bot.ktor.base.*
|
||||
@@ -10,9 +11,9 @@ import io.ktor.client.HttpClient
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
@RiskFeature
|
||||
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
|
||||
SimpleRequestCallFactory(),
|
||||
MultipartRequestCallFactory(),
|
||||
fun createTelegramBotDefaultKtorCallRequestsFactories(logger: KSLog? = null) = listOf(
|
||||
SimpleRequestCallFactory(logger),
|
||||
MultipartRequestCallFactory(logger),
|
||||
DownloadFileRequestCallFactory,
|
||||
DownloadFileChannelRequestCallFactory
|
||||
)
|
||||
@@ -25,6 +26,8 @@ class KtorRequestsExecutorBuilder(
|
||||
var excludeDefaultFactories: Boolean = false
|
||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter
|
||||
var jsonFormatter: Json = nonstrictJsonFormat
|
||||
var logger: KSLog = DefaultKTgBotAPIKSLog
|
||||
var pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder
|
||||
|
||||
fun build() = KtorRequestsExecutor(
|
||||
telegramAPIUrlsKeeper,
|
||||
@@ -32,7 +35,9 @@ class KtorRequestsExecutorBuilder(
|
||||
callsFactories,
|
||||
excludeDefaultFactories,
|
||||
requestsLimiter,
|
||||
jsonFormatter
|
||||
jsonFormatter,
|
||||
pipelineStepsHolder,
|
||||
logger
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor.base
|
||||
|
||||
import dev.inmo.kslog.common.KSLog
|
||||
import dev.inmo.kslog.common.v
|
||||
import dev.inmo.kslog.common.w
|
||||
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||
import dev.inmo.tgbotapi.requests.GetUpdatesRequest
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.types.Response
|
||||
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.plugins.timeout
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.bodyAsText
|
||||
import io.ktor.http.ContentType
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlin.collections.set
|
||||
|
||||
var defaultUpdateTimeoutForZeroDelay = 1000L
|
||||
|
||||
abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||
abstract class AbstractRequestCallFactory(
|
||||
protected open val logger: KSLog = DefaultKTgBotAPIKSLog
|
||||
) : KtorCallFactory {
|
||||
private val methodsCache: MutableMap<String, String> = mutableMapOf()
|
||||
override suspend fun <T : Any> makeCall(
|
||||
client: HttpClient,
|
||||
@@ -26,6 +33,7 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||
jsonFormatter: Json
|
||||
): T? {
|
||||
val preparedBody = prepareCallBody(client, urlsKeeper, request) ?: return null
|
||||
logger.v { "Prepared body for $request: $preparedBody" }
|
||||
|
||||
client.post {
|
||||
url(
|
||||
@@ -54,7 +62,9 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||
setBody(preparedBody)
|
||||
}.let { response ->
|
||||
val content = response.bodyAsText()
|
||||
logger.v { "Raw answer for $request: $content" }
|
||||
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
||||
logger.v { "Answer as json for $request: $responseObject" }
|
||||
|
||||
return runCatchingSafely {
|
||||
(responseObject.result?.let {
|
||||
@@ -66,6 +76,8 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||
"Can't get result object from $content"
|
||||
)
|
||||
})
|
||||
}.onFailure {
|
||||
logger.w { "Got exception answer for $request: $it" }
|
||||
}.getOrThrow()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor.base
|
||||
|
||||
import dev.inmo.kslog.common.*
|
||||
import dev.inmo.micro_utils.coroutines.defaultSafelyExceptionHandler
|
||||
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.exceptions.BotException
|
||||
import dev.inmo.tgbotapi.bot.exceptions.CommonBotException
|
||||
import dev.inmo.tgbotapi.bot.exceptions.GetUpdatesConflict
|
||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.ktor.createTelegramBotDefaultKtorCallRequestsFactories
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||
@@ -19,19 +23,23 @@ import io.ktor.client.plugins.*
|
||||
import io.ktor.client.statement.*
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class DefaultKtorRequestsExecutor(
|
||||
class DefaultKtorRequestsExecutor internal constructor(
|
||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||
client: HttpClient = HttpClient(),
|
||||
callsFactories: List<KtorCallFactory> = emptyList(),
|
||||
excludeDefaultFactories: Boolean = false,
|
||||
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter,
|
||||
private val jsonFormatter: Json = nonstrictJsonFormat,
|
||||
private val pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder
|
||||
client: HttpClient,
|
||||
callsFactories: List<KtorCallFactory>,
|
||||
excludeDefaultFactories: Boolean,
|
||||
private val requestsLimiter: RequestLimiter,
|
||||
private val jsonFormatter: Json,
|
||||
private val pipelineStepsHolder: KtorPipelineStepsHolder,
|
||||
private val logger: KSLog,
|
||||
diff: Unit
|
||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
||||
if (!excludeDefaultFactories) {
|
||||
this + createTelegramBotDefaultKtorCallRequestsFactories()
|
||||
logger.v { "Installing default factories" }
|
||||
this + createTelegramBotDefaultKtorCallRequestsFactories(logger)
|
||||
} else {
|
||||
logger.v { "Default factories will not be installed" }
|
||||
this
|
||||
}
|
||||
}
|
||||
@@ -44,19 +52,23 @@ class DefaultKtorRequestsExecutor(
|
||||
|
||||
override suspend fun <T : Any> execute(request: Request<T>): T {
|
||||
return runCatchingSafely {
|
||||
logger.v { "Start request $request" }
|
||||
pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories)
|
||||
requestsLimiter.limit(request) {
|
||||
var result: T? = null
|
||||
lateinit var factoryHandledRequest: KtorCallFactory
|
||||
for (potentialFactory in callsFactories) {
|
||||
pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory)
|
||||
result = potentialFactory.makeCall(
|
||||
logger.v { "Trying factory $potentialFactory for $request" }
|
||||
val resultFromFactory = potentialFactory.makeCall(
|
||||
client,
|
||||
telegramAPIUrlsKeeper,
|
||||
request,
|
||||
jsonFormatter
|
||||
)
|
||||
result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory)
|
||||
logger.v { "Result of factory $potentialFactory handling $request: $resultFromFactory" }
|
||||
result = pipelineStepsHolder.onAfterCallFactoryMakeCall(resultFromFactory, request, potentialFactory)
|
||||
logger.v { "Result of pipeline $pipelineStepsHolder handling $resultFromFactory: $result" }
|
||||
if (result != null) {
|
||||
factoryHandledRequest = potentialFactory
|
||||
break
|
||||
@@ -69,6 +81,7 @@ class DefaultKtorRequestsExecutor(
|
||||
}
|
||||
}.let {
|
||||
val result = it.exceptionOrNull() ?.let { e ->
|
||||
logger.v(e) { "Got exception on handling of $request" }
|
||||
pipelineStepsHolder.onRequestException(request, e) ?.let { return@let it }
|
||||
|
||||
when (e) {
|
||||
@@ -88,9 +101,18 @@ class DefaultKtorRequestsExecutor(
|
||||
}
|
||||
is BotException -> e
|
||||
else -> CommonBotException(cause = e)
|
||||
}.also { newException ->
|
||||
logger.v(newException) { "Result exception on handling of $request is an exception" }
|
||||
if (newException is GetUpdatesConflict) {
|
||||
logger.w(newException) {
|
||||
"Warning!!! Other bot with the same bot token requests updates with getUpdate in parallel"
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?.let { Result.failure(it) } ?: it
|
||||
pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories)
|
||||
pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories).also {
|
||||
logger.v { "Result of handling $request: $it" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||
import dev.inmo.tgbotapi.requests.DownloadFileStream
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.receive
|
||||
@@ -15,6 +16,7 @@ import io.ktor.utils.io.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
@RiskFeature
|
||||
object DownloadFileChannelRequestCallFactory : KtorCallFactory {
|
||||
override suspend fun <T : Any> makeCall(
|
||||
client: HttpClient,
|
||||
|
||||
@@ -4,12 +4,14 @@ import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||
import dev.inmo.tgbotapi.requests.DownloadFile
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.readBytes
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
@RiskFeature
|
||||
object DownloadFileRequestCallFactory : KtorCallFactory {
|
||||
override suspend fun <T : Any> makeCall(
|
||||
client: HttpClient,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor.base
|
||||
|
||||
import dev.inmo.kslog.common.KSLog
|
||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import dev.inmo.tgbotapi.utils.mapWithCommonValues
|
||||
import io.ktor.client.HttpClient
|
||||
@@ -8,7 +10,7 @@ import io.ktor.client.request.forms.*
|
||||
import io.ktor.http.Headers
|
||||
import io.ktor.http.HttpHeaders
|
||||
|
||||
class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
||||
class MultipartRequestCallFactory(logger: KSLog? = null) : AbstractRequestCallFactory(logger ?: DefaultKTgBotAPIKSLog) {
|
||||
override fun <T : Any> prepareCallBody(
|
||||
client: HttpClient,
|
||||
urlsKeeper: TelegramAPIUrlsKeeper,
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor.base
|
||||
|
||||
import dev.inmo.kslog.common.KSLog
|
||||
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder
|
||||
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
||||
import io.ktor.client.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
@@ -45,6 +49,7 @@ class MultipleClientKtorRequestsExecutor (
|
||||
jsonFormatter: Json,
|
||||
pipelineStepsHolder: KtorPipelineStepsHolder,
|
||||
requestExecutorsCount: Int,
|
||||
logger: KSLog,
|
||||
clientFactory: () -> HttpClient
|
||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||
private val requestExecutors = (0 until requestExecutorsCount).map {
|
||||
@@ -55,7 +60,9 @@ class MultipleClientKtorRequestsExecutor (
|
||||
excludeDefaultFactories,
|
||||
requestsLimiter,
|
||||
jsonFormatter,
|
||||
pipelineStepsHolder
|
||||
pipelineStepsHolder,
|
||||
logger,
|
||||
Unit
|
||||
)
|
||||
}.toSet()
|
||||
private val freeClients = MutableStateFlow<Set<DefaultKtorRequestsExecutor>>(requestExecutors)
|
||||
@@ -68,14 +75,16 @@ class MultipleClientKtorRequestsExecutor (
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
internal constructor(
|
||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||
client: HttpClient,
|
||||
callsFactories: List<KtorCallFactory>,
|
||||
excludeDefaultFactories: Boolean,
|
||||
requestsLimiter: RequestLimiter,
|
||||
jsonFormatter: Json,
|
||||
pipelineStepsHolder: KtorPipelineStepsHolder
|
||||
pipelineStepsHolder: KtorPipelineStepsHolder,
|
||||
logger: KSLog,
|
||||
diff: Unit
|
||||
) : this(
|
||||
telegramAPIUrlsKeeper,
|
||||
callsFactories,
|
||||
@@ -84,6 +93,7 @@ class MultipleClientKtorRequestsExecutor (
|
||||
jsonFormatter,
|
||||
pipelineStepsHolder,
|
||||
client.engineConfig.threadsCount,
|
||||
logger,
|
||||
{ platformClientCopy(client) }
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor.base
|
||||
|
||||
import dev.inmo.kslog.common.KSLog
|
||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.content.TextContent
|
||||
|
||||
class SimpleRequestCallFactory : AbstractRequestCallFactory() {
|
||||
class SimpleRequestCallFactory(logger: KSLog? = null) : AbstractRequestCallFactory(logger ?: DefaultKTgBotAPIKSLog) {
|
||||
override fun <T : Any> prepareCallBody(
|
||||
client: HttpClient,
|
||||
urlsKeeper: TelegramAPIUrlsKeeper,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
|
||||
import dev.inmo.tgbotapi.types.commands.*
|
||||
import dev.inmo.tgbotapi.types.languageCodeField
|
||||
import dev.inmo.tgbotapi.types.scopeField
|
||||
@@ -14,8 +15,8 @@ data class DeleteMyCommands(
|
||||
@Serializable(BotCommandScopeSerializer::class)
|
||||
override val scope: BotCommandScope = BotCommandScopeDefault,
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : MyCommandsRequest<Boolean> {
|
||||
override fun method(): String = "deleteMyCommands"
|
||||
override val requestSerializer: SerializationStrategy<DeleteMyCommands>
|
||||
@@ -28,7 +29,7 @@ data class DeleteMyCommands(
|
||||
languageCode: String?
|
||||
) : this(
|
||||
scope,
|
||||
languageCode ?.let(::IetfLanguageCode)
|
||||
languageCode ?.let(::IetfLang)
|
||||
)
|
||||
|
||||
companion object : MyCommandsRequest<Boolean> by DeleteMyCommands()
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.commands.*
|
||||
import kotlinx.serialization.*
|
||||
@@ -15,8 +16,8 @@ data class GetMyCommands(
|
||||
@Serializable(BotCommandScopeSerializer::class)
|
||||
override val scope: BotCommandScope = BotCommandScopeDefault,
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : MyCommandsRequest<List<BotCommand>> {
|
||||
override fun method(): String = "getMyCommands"
|
||||
override val resultDeserializer: DeserializationStrategy<List<BotCommand>>
|
||||
@@ -29,7 +30,7 @@ data class GetMyCommands(
|
||||
languageCode: String?
|
||||
) : this(
|
||||
scope,
|
||||
languageCode ?.let(::IetfLanguageCode)
|
||||
languageCode ?.let(::IetfLang)
|
||||
)
|
||||
|
||||
companion object : MyCommandsRequest<List<BotCommand>> by GetMyCommands()
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
@@ -12,8 +13,8 @@ import kotlinx.serialization.builtins.serializer
|
||||
@Serializable
|
||||
class GetMyDescription(
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : SimpleRequest<BotDescription>, WithOptionalLanguageCode {
|
||||
override fun method(): String = "getMyDescription"
|
||||
override val resultDeserializer: DeserializationStrategy<BotDescription>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
@@ -12,8 +13,8 @@ import kotlinx.serialization.builtins.serializer
|
||||
@Serializable
|
||||
class GetMyName(
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : SimpleRequest<BotName>, WithOptionalLanguageCode {
|
||||
override fun method(): String = "getMyName"
|
||||
override val resultDeserializer: DeserializationStrategy<BotName>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
@@ -12,8 +13,8 @@ import kotlinx.serialization.builtins.serializer
|
||||
@Serializable
|
||||
class GetMyShortDescription(
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : SimpleRequest<BotShortDescription>, WithOptionalLanguageCode {
|
||||
override fun method(): String = "getMyShortDescription"
|
||||
override val resultDeserializer: DeserializationStrategy<BotShortDescription>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.commands.*
|
||||
import kotlinx.serialization.*
|
||||
@@ -15,8 +16,8 @@ class SetMyCommands(
|
||||
@Serializable(BotCommandScopeSerializer::class)
|
||||
override val scope: BotCommandScope = BotCommandScopeDefault,
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : MyCommandsRequest<Boolean> {
|
||||
override fun method(): String = "setMyCommands"
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
@@ -31,7 +32,7 @@ class SetMyCommands(
|
||||
) : this(
|
||||
commands,
|
||||
scope,
|
||||
languageCode ?.let(::IetfLanguageCode)
|
||||
languageCode ?.let(::IetfLang)
|
||||
)
|
||||
|
||||
init {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
@@ -14,8 +14,8 @@ class SetMyDescription(
|
||||
@SerialName(descriptionField)
|
||||
val description: String? = null,
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : SimpleRequest<Boolean>, WithOptionalLanguageCode {
|
||||
override fun method(): String = "setMyDescription"
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
@@ -14,8 +14,8 @@ class SetMyName(
|
||||
@SerialName(nameField)
|
||||
val name: String? = null,
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : SimpleRequest<Boolean>, WithOptionalLanguageCode {
|
||||
override fun method(): String = "setMyName"
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.requests.bot
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
@@ -14,8 +14,8 @@ class SetMyShortDescription(
|
||||
@SerialName(shortDescriptionField)
|
||||
val shortDescription: String? = null,
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null
|
||||
) : SimpleRequest<Boolean>, WithOptionalLanguageCode {
|
||||
override fun method(): String = "setMyShortDescription"
|
||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.abstracts
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
|
||||
interface WithOptionalLanguageCode {
|
||||
val ietfLanguageCode: IetfLanguageCode?
|
||||
val ietfLanguageCode: IetfLang?
|
||||
|
||||
val languageCode: String?
|
||||
get() = ietfLanguageCode ?.code
|
||||
|
||||
@@ -4,51 +4,51 @@ import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface UsernameChat : Chat {
|
||||
val username: Username?
|
||||
}
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface PrivateChat : Chat, UsernameChat {
|
||||
override val id: UserId
|
||||
val firstName: String
|
||||
val lastName: String
|
||||
}
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface PublicChat : Chat {
|
||||
val title: String
|
||||
}
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface SuperPublicChat : PublicChat, UsernameChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface ChannelChat : SuperPublicChat {
|
||||
override val id: ChatId
|
||||
}
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface GroupChat : PublicChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface SupergroupChat : GroupChat, SuperPublicChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface ForumChat : SupergroupChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface PossiblyPremiumChat : Chat {
|
||||
val isPremium: Boolean
|
||||
}
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
sealed interface AbleToAddInAttachmentMenuChat : Chat {
|
||||
val addedToAttachmentMenu: Boolean
|
||||
}
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
@Serializable(ChatSerializer::class)
|
||||
@ClassCastsIncluded(excludeRegex = ".*Impl")
|
||||
sealed interface Chat {
|
||||
val id: IdChatIdentifier
|
||||
|
||||
@@ -49,13 +49,54 @@ object ChatTypeSerializer : KSerializer<ChatType> {
|
||||
}
|
||||
|
||||
@RiskFeature
|
||||
object PreviewChatSerializer : KSerializer<Chat> {
|
||||
object ChatSerializer : KSerializer<Chat> {
|
||||
@OptIn(InternalSerializationApi::class)
|
||||
override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN)
|
||||
|
||||
override fun deserialize(decoder: Decoder): Chat {
|
||||
val decodedJson = JsonObject.serializer().deserialize(decoder)
|
||||
|
||||
return try {
|
||||
formatter.decodeFromJsonElement(ExtendedChatSerializer, decodedJson)
|
||||
} catch (e: SerializationException) {
|
||||
val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson")
|
||||
val isForum = decodedJson[isForumField] ?.jsonPrimitive ?.booleanOrNull == true
|
||||
|
||||
when (type) {
|
||||
ChatType.PrivateChatType -> formatter.decodeFromJsonElement(PrivateChatImpl.serializer(), decodedJson)
|
||||
ChatType.GroupChatType -> formatter.decodeFromJsonElement(GroupChatImpl.serializer(), decodedJson)
|
||||
ChatType.SupergroupChatType -> if (isForum) {
|
||||
formatter.decodeFromJsonElement(ForumChatImpl.serializer(), decodedJson)
|
||||
} else {
|
||||
formatter.decodeFromJsonElement(SupergroupChatImpl.serializer(), decodedJson)
|
||||
}
|
||||
ChatType.ChannelChatType -> formatter.decodeFromJsonElement(ChannelChatImpl.serializer(), decodedJson)
|
||||
is ChatType.UnknownChatType -> UnknownChatType(
|
||||
formatter.decodeFromJsonElement(Long.serializer(), decodedJson[chatIdField] ?: JsonPrimitive(-1)).toChatId(),
|
||||
decodedJson.toString(),
|
||||
decodedJson
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Chat) {
|
||||
when (value) {
|
||||
is ExtendedChat -> ExtendedChatSerializer.serialize(encoder, value)
|
||||
is PreviewChat -> PreviewChatSerializer.serialize(encoder, value)
|
||||
is ExtendedBot -> ExtendedBot.serializer().serialize(encoder, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RiskFeature
|
||||
object PreviewChatSerializer : KSerializer<PreviewChat> {
|
||||
@OptIn(InternalSerializationApi::class)
|
||||
override val descriptor: SerialDescriptor = buildSerialDescriptor("PreviewChatSerializer", PolymorphicKind.OPEN)
|
||||
|
||||
override fun deserialize(decoder: Decoder): PreviewChat {
|
||||
val decodedJson = JsonObject.serializer().deserialize(decoder)
|
||||
|
||||
val type = decodedJson[typeField] ?.jsonPrimitive ?.content ?.asChatType ?: error("Field $typeField must be presented, but absent in $decodedJson")
|
||||
val isForum = decodedJson[isForumField] ?.jsonPrimitive ?.booleanOrNull == true
|
||||
|
||||
@@ -76,16 +117,14 @@ object PreviewChatSerializer : KSerializer<Chat> {
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Chat) {
|
||||
override fun serialize(encoder: Encoder, value: PreviewChat) {
|
||||
when (value) {
|
||||
is ExtendedChat -> ExtendedChatSerializer.serialize(encoder, value)
|
||||
is PrivateChatImpl -> PrivateChatImpl.serializer().serialize(encoder, value)
|
||||
is GroupChatImpl -> GroupChatImpl.serializer().serialize(encoder, value)
|
||||
is SupergroupChatImpl -> SupergroupChatImpl.serializer().serialize(encoder, value)
|
||||
is ForumChatImpl -> ForumChatImpl.serializer().serialize(encoder, value)
|
||||
is ChannelChatImpl -> ChannelChatImpl.serializer().serialize(encoder, value)
|
||||
is CommonBot -> CommonBot.serializer().serialize(encoder, value)
|
||||
is ExtendedBot -> ExtendedBot.serializer().serialize(encoder, value)
|
||||
is CommonUser -> CommonUser.serializer().serialize(encoder, value)
|
||||
is UnknownChatType -> JsonObject.serializer().serialize(encoder, value.rawJson)
|
||||
}
|
||||
@@ -128,6 +167,7 @@ sealed class ExtendedChatSerializer : KSerializer<ExtendedChat> {
|
||||
is ExtendedSupergroupChatImpl -> ExtendedSupergroupChatImpl.serializer().serialize(encoder, value)
|
||||
is ExtendedForumChatImpl -> ExtendedForumChatImpl.serializer().serialize(encoder, value)
|
||||
is ExtendedChannelChatImpl -> ExtendedChannelChatImpl.serializer().serialize(encoder, value)
|
||||
is ExtendedBot -> ExtendedBot.serializer().serialize(encoder, value)
|
||||
is UnknownExtendedChat -> JsonObject.serializer().serialize(encoder, value.rawJson)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,8 +184,10 @@ data class ExtendedBot(
|
||||
@SerialName(canReadAllGroupMessagesField)
|
||||
val canReadAllGroupMessages: Boolean = false,
|
||||
@SerialName(supportInlineQueriesField)
|
||||
val supportsInlineQueries: Boolean = false
|
||||
) : Bot() {
|
||||
val supportsInlineQueries: Boolean = false,
|
||||
@SerialName(photoField)
|
||||
override val chatPhoto: ChatPhoto? = null
|
||||
) : Bot(), ExtendedChat {
|
||||
@SerialName(isBotField)
|
||||
private val isBot = true
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.types.chat
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCodeSerializer
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.micro_utils.language_codes.IetfLangSerializer
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
@@ -15,7 +15,7 @@ data class GroupChatImpl(
|
||||
override val id: ChatId,
|
||||
@SerialName(titleField)
|
||||
override val title: String
|
||||
) : GroupChat
|
||||
) : PreviewGroupChat
|
||||
|
||||
@Serializable
|
||||
@RiskFeature("This class is a subject of changes. It is better to use PrivateChat due")
|
||||
@@ -28,7 +28,7 @@ data class PrivateChatImpl(
|
||||
override val firstName: String = "",
|
||||
@SerialName(lastNameField)
|
||||
override val lastName: String = ""
|
||||
) : PrivateChat
|
||||
) : PreviewPrivateChat
|
||||
|
||||
@Serializable
|
||||
@RiskFeature("This class is a subject of changes. It is better to use SupergroupChat due")
|
||||
@@ -39,7 +39,7 @@ data class SupergroupChatImpl(
|
||||
override val title: String,
|
||||
@SerialName(usernameField)
|
||||
override val username: Username? = null
|
||||
) : SupergroupChat
|
||||
) : PreviewSupergroupChat
|
||||
|
||||
@Serializable
|
||||
@RiskFeature("This class is a subject of changes. It is better to use ForumChat due")
|
||||
@@ -50,7 +50,7 @@ data class ForumChatImpl(
|
||||
override val title: String,
|
||||
@SerialName(usernameField)
|
||||
override val username: Username? = null
|
||||
) : ForumChat
|
||||
) : PreviewForumChat
|
||||
|
||||
@Serializable
|
||||
@RiskFeature("This class is a subject of changes. It is better to use ChannelChat due")
|
||||
@@ -61,14 +61,20 @@ data class ChannelChatImpl(
|
||||
override val title: String,
|
||||
@SerialName(usernameField)
|
||||
override val username: Username? = null
|
||||
) : ChannelChat
|
||||
) : PreviewChannelChat
|
||||
|
||||
@Serializable(UserSerializer::class)
|
||||
sealed class User : PrivateChat
|
||||
|
||||
@Serializable(UserSerializer::class)
|
||||
sealed class PreviewUser : PreviewPrivateChat, User()
|
||||
|
||||
@Serializable(UserSerializer::class)
|
||||
sealed class Bot : User()
|
||||
|
||||
@Serializable(UserSerializer::class)
|
||||
sealed class PreviewBot : PreviewUser()
|
||||
|
||||
@Serializable
|
||||
data class CommonBot(
|
||||
override val id: UserId,
|
||||
@@ -78,7 +84,7 @@ data class CommonBot(
|
||||
override val lastName: String = "",
|
||||
@SerialName(usernameField)
|
||||
override val username: Username? = null,
|
||||
) : Bot() {
|
||||
) : PreviewBot() {
|
||||
@SerialName(isBotField)
|
||||
private val isBot = true
|
||||
}
|
||||
@@ -93,18 +99,18 @@ data class CommonUser(
|
||||
@SerialName(usernameField)
|
||||
override val username: Username? = null,
|
||||
@SerialName(languageCodeField)
|
||||
@Serializable(IetfLanguageCodeSerializer::class)
|
||||
override val ietfLanguageCode: IetfLanguageCode? = null,
|
||||
@Serializable(IetfLangSerializer::class)
|
||||
override val ietfLanguageCode: IetfLang? = null,
|
||||
@SerialName(isPremiumField)
|
||||
override val isPremium: Boolean = false,
|
||||
@SerialName(addedToAttachmentMenuField)
|
||||
override val addedToAttachmentMenu: Boolean = false
|
||||
) : User(), WithOptionalLanguageCode, PossiblyPremiumChat, AbleToAddInAttachmentMenuChat {
|
||||
) : PreviewUser(), WithOptionalLanguageCode, PossiblyPremiumChat, AbleToAddInAttachmentMenuChat {
|
||||
constructor(
|
||||
id: UserId,
|
||||
firstName: String,
|
||||
lastName: String = "",
|
||||
username: Username? = null,
|
||||
languageCode: String
|
||||
) : this(id, firstName, lastName, username, IetfLanguageCode(languageCode))
|
||||
) : this(id, firstName, lastName, username, IetfLang(languageCode))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package dev.inmo.tgbotapi.types.chat
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewChat : Chat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewUsernameChat : PreviewChat, UsernameChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewPrivateChat : PreviewUsernameChat, PrivateChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewPublicChat : PreviewChat, PublicChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewSuperPublicChat : PreviewPublicChat, PreviewUsernameChat, SuperPublicChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewChannelChat : PreviewSuperPublicChat, ChannelChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewGroupChat : PreviewPublicChat, GroupChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewSupergroupChat : PreviewGroupChat, PreviewSuperPublicChat, SupergroupChat
|
||||
|
||||
@Serializable(PreviewChatSerializer::class)
|
||||
sealed interface PreviewForumChat : PreviewSupergroupChat, ForumChat
|
||||
@@ -7,4 +7,4 @@ data class UnknownChatType(
|
||||
override val id: IdChatIdentifier,
|
||||
val raw: String,
|
||||
val rawJson: JsonObject
|
||||
) : Chat
|
||||
) : Chat, PreviewChat
|
||||
|
||||
@@ -45,6 +45,5 @@ data class AdministratorChatMemberImpl(
|
||||
) : AdministratorChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
override val status: ChatMember.Status
|
||||
get() = ChatMember.Status.Administrator
|
||||
override val status: ChatMember.Status = ChatMember.Status.Administrator
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
@@ -15,8 +16,11 @@ import kotlinx.serialization.json.jsonPrimitive
|
||||
|
||||
@Serializable(ChatMemberSerializer::class)
|
||||
sealed interface ChatMember : WithUser {
|
||||
@Serializable
|
||||
enum class Status(val status: String, val deserializationStrategy: DeserializationStrategy<ChatMember>) {
|
||||
@Serializable(StatusSerializer::class)
|
||||
enum class Status(
|
||||
val status: String,
|
||||
val deserializationStrategy: DeserializationStrategy<ChatMember>
|
||||
) {
|
||||
Creator("creator", OwnerChatMember.serializer()),
|
||||
Administrator("administrator", AdministratorChatMemberImpl.serializer()),
|
||||
Member("member", MemberChatMemberImpl.serializer()),
|
||||
@@ -24,6 +28,23 @@ sealed interface ChatMember : WithUser {
|
||||
Left("left", LeftChatMemberImpl.serializer()),
|
||||
Kicked("kicked", KickedChatMember.serializer())
|
||||
}
|
||||
|
||||
object StatusSerializer : KSerializer<Status> {
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = String.serializer().descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): Status {
|
||||
val status = decoder.decodeString()
|
||||
return Status.values().first {
|
||||
it.status == status
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Status) {
|
||||
encoder.encodeString(value.status)
|
||||
}
|
||||
}
|
||||
|
||||
val status: Status
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package dev.inmo.tgbotapi.types.chat.member
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.WithChat
|
||||
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
|
||||
import dev.inmo.tgbotapi.abstracts.WithUser
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -11,7 +12,7 @@ import kotlinx.serialization.Serializable
|
||||
@Serializable
|
||||
data class ChatMemberUpdated(
|
||||
@SerialName(chatField)
|
||||
override val chat: Chat,
|
||||
override val chat: PreviewChat,
|
||||
@SerialName(fromField)
|
||||
override val user: User,
|
||||
@SerialName(dateField)
|
||||
@@ -24,4 +25,4 @@ data class ChatMemberUpdated(
|
||||
val inviteLink: ChatInviteLink? = null,
|
||||
@SerialName(viaChatFolderInviteLinkField)
|
||||
val viaChatFolderInviteLink: Boolean? = false
|
||||
) : WithChat, WithUser
|
||||
) : WithPreviewChat, WithUser
|
||||
|
||||
@@ -13,6 +13,5 @@ data class KickedChatMember(
|
||||
) : BannedChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
override val status: ChatMember.Status
|
||||
get() = ChatMember.Status.Kicked
|
||||
override val status: ChatMember.Status = ChatMember.Status.Kicked
|
||||
}
|
||||
|
||||
@@ -11,6 +11,5 @@ data class LeftChatMemberImpl(
|
||||
) : LeftChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
override val status: ChatMember.Status
|
||||
get() = ChatMember.Status.Left
|
||||
override val status: ChatMember.Status = ChatMember.Status.Left
|
||||
}
|
||||
|
||||
@@ -11,6 +11,5 @@ data class MemberChatMemberImpl(
|
||||
) : MemberChatMember {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
override val status: ChatMember.Status
|
||||
get() = ChatMember.Status.Member
|
||||
override val status: ChatMember.Status = ChatMember.Status.Member
|
||||
}
|
||||
|
||||
@@ -45,6 +45,5 @@ data class OwnerChatMember(
|
||||
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
override val status: ChatMember.Status
|
||||
get() = ChatMember.Status.Creator
|
||||
override val status: ChatMember.Status = ChatMember.Status.Creator
|
||||
}
|
||||
|
||||
@@ -44,6 +44,5 @@ data class RestrictedChatMember(
|
||||
) : BannedChatMember, SpecialRightsChatMember, ChatPermissions {
|
||||
@SerialName(statusField)
|
||||
@Required
|
||||
override val status: ChatMember.Status
|
||||
get() = ChatMember.Status.Restricted
|
||||
override val status: ChatMember.Status = ChatMember.Status.Restricted
|
||||
}
|
||||
|
||||
@@ -5,12 +5,13 @@ import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.ChannelChat
|
||||
import dev.inmo.tgbotapi.types.chat.CommonBot
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChannelChat
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
data class ChannelContentMessageImpl<T: MessageContent>(
|
||||
override val messageId: MessageId,
|
||||
override val chat: ChannelChat,
|
||||
override val chat: PreviewChannelChat,
|
||||
override val content: T,
|
||||
override val date: DateTime,
|
||||
override val editDate: DateTime?,
|
||||
|
||||
@@ -3,12 +3,13 @@ package dev.inmo.tgbotapi.types.message
|
||||
import korlibs.time.DateTime
|
||||
import dev.inmo.tgbotapi.types.MessageId
|
||||
import dev.inmo.tgbotapi.types.chat.ChannelChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChannelChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||
|
||||
data class ChannelEventMessage<T : ChannelEvent>(
|
||||
override val messageId: MessageId,
|
||||
override val chat: ChannelChat,
|
||||
override val chat: PreviewChannelChat,
|
||||
override val chatEvent: T,
|
||||
override val date: DateTime
|
||||
) : ChatEventMessage<T>
|
||||
|
||||
@@ -4,13 +4,14 @@ import korlibs.time.DateTime
|
||||
import dev.inmo.tgbotapi.types.MessageId
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import dev.inmo.tgbotapi.types.chat.GroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewGroupChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.GroupEventMessage
|
||||
|
||||
data class CommonGroupEventMessage<T : GroupEvent>(
|
||||
override val messageId: MessageId,
|
||||
override val from: User,
|
||||
override val chat: GroupChat,
|
||||
override val chat: PreviewGroupChat,
|
||||
override val chatEvent: T,
|
||||
override val date: DateTime
|
||||
) : GroupEventMessage<T>
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.types.message
|
||||
|
||||
import korlibs.time.DateTime
|
||||
import dev.inmo.tgbotapi.types.MessageId
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewSupergroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import dev.inmo.tgbotapi.types.chat.SupergroupChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent
|
||||
@@ -10,7 +11,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.SupergroupEventMessage
|
||||
data class CommonSupergroupEventMessage<T : SupergroupEvent>(
|
||||
override val messageId: MessageId,
|
||||
override val from: User,
|
||||
override val chat: SupergroupChat,
|
||||
override val chat: PreviewSupergroupChat,
|
||||
override val chatEvent: T,
|
||||
override val date: DateTime
|
||||
) : SupergroupEventMessage<T>
|
||||
|
||||
@@ -10,8 +10,8 @@ import dev.inmo.tgbotapi.types.message.abstracts.*
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
data class ConnectedFromChannelGroupContentMessageImpl<T : MessageContent>(
|
||||
override val chat: GroupChat,
|
||||
override val channel: ChannelChat,
|
||||
override val chat: PreviewGroupChat,
|
||||
override val channel: PreviewChannelChat,
|
||||
override val messageId: MessageId,
|
||||
override val date: DateTime,
|
||||
override val forwardInfo: ForwardInfo?,
|
||||
@@ -26,8 +26,8 @@ data class ConnectedFromChannelGroupContentMessageImpl<T : MessageContent>(
|
||||
) : ConnectedFromChannelGroupContentMessage<T>
|
||||
|
||||
data class UnconnectedFromChannelGroupContentMessageImpl<T: MessageContent>(
|
||||
override val chat: GroupChat,
|
||||
override val channel: ChannelChat,
|
||||
override val chat: PreviewGroupChat,
|
||||
override val channel: PreviewChannelChat,
|
||||
override val messageId: MessageId,
|
||||
override val date: DateTime,
|
||||
override val forwardInfo: ForwardInfo?,
|
||||
@@ -42,7 +42,7 @@ data class UnconnectedFromChannelGroupContentMessageImpl<T: MessageContent>(
|
||||
) : UnconnectedFromChannelGroupContentMessage<T>
|
||||
|
||||
data class AnonymousGroupContentMessageImpl<T : MessageContent>(
|
||||
override val chat: GroupChat,
|
||||
override val chat: PreviewGroupChat,
|
||||
override val messageId: MessageId,
|
||||
override val date: DateTime,
|
||||
override val forwardInfo: ForwardInfo?,
|
||||
@@ -57,7 +57,7 @@ data class AnonymousGroupContentMessageImpl<T : MessageContent>(
|
||||
) : AnonymousGroupContentMessage<T>
|
||||
|
||||
data class CommonGroupContentMessageImpl<T : MessageContent>(
|
||||
override val chat: GroupChat,
|
||||
override val chat: PreviewGroupChat,
|
||||
override val messageId: MessageId,
|
||||
override val from: User,
|
||||
override val date: DateTime,
|
||||
@@ -72,8 +72,8 @@ data class CommonGroupContentMessageImpl<T : MessageContent>(
|
||||
) : CommonGroupContentMessage<T>
|
||||
|
||||
data class FromChannelForumContentMessageImpl<T: MessageContent>(
|
||||
override val chat: ForumChat,
|
||||
override val channel: ChannelChat,
|
||||
override val chat: PreviewForumChat,
|
||||
override val channel: PreviewChannelChat,
|
||||
override val messageId: MessageId,
|
||||
override val threadId: MessageThreadId,
|
||||
override val date: DateTime,
|
||||
@@ -89,7 +89,7 @@ data class FromChannelForumContentMessageImpl<T: MessageContent>(
|
||||
) : FromChannelForumContentMessage<T>
|
||||
|
||||
data class AnonymousForumContentMessageImpl<T : MessageContent>(
|
||||
override val chat: ForumChat,
|
||||
override val chat: PreviewForumChat,
|
||||
override val messageId: MessageId,
|
||||
override val threadId: MessageThreadId,
|
||||
override val date: DateTime,
|
||||
@@ -105,7 +105,7 @@ data class AnonymousForumContentMessageImpl<T : MessageContent>(
|
||||
) : AnonymousForumContentMessage<T>
|
||||
|
||||
data class CommonForumContentMessageImpl<T : MessageContent>(
|
||||
override val chat: ForumChat,
|
||||
override val chat: PreviewForumChat,
|
||||
override val messageId: MessageId,
|
||||
override val threadId: MessageThreadId,
|
||||
override val from: User,
|
||||
|
||||
@@ -4,13 +4,14 @@ import korlibs.time.DateTime
|
||||
import dev.inmo.tgbotapi.types.MessageId
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.FromUserMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||
import dev.inmo.tgbotapi.types.passport.PassportData
|
||||
|
||||
data class PassportMessage(
|
||||
override val messageId: MessageId,
|
||||
override val chat: Chat,
|
||||
override val chat: PreviewChat,
|
||||
override val from: User,
|
||||
override val date: DateTime,
|
||||
val passportData: PassportData
|
||||
|
||||
@@ -13,7 +13,7 @@ import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
data class PrivateContentMessageImpl<T: MessageContent>(
|
||||
override val messageId: MessageId,
|
||||
override val from: User,
|
||||
override val chat: Chat,
|
||||
override val chat: PreviewPrivateChat,
|
||||
override val content: T,
|
||||
override val date: DateTime,
|
||||
override val editDate: DateTime?,
|
||||
|
||||
@@ -2,13 +2,14 @@ package dev.inmo.tgbotapi.types.message
|
||||
|
||||
import korlibs.time.DateTime
|
||||
import dev.inmo.tgbotapi.types.MessageId
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewPrivateChat
|
||||
import dev.inmo.tgbotapi.types.chat.PrivateChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||
|
||||
data class PrivateEventMessage<T : PrivateEvent>(
|
||||
override val messageId: MessageId,
|
||||
override val chat: PrivateChat,
|
||||
override val chat: PreviewPrivateChat,
|
||||
override val chatEvent: T,
|
||||
override val date: DateTime
|
||||
) : ChatEventMessage<T>
|
||||
|
||||
@@ -43,11 +43,11 @@ internal data class RawMessage(
|
||||
@SerialName(messageIdField)
|
||||
val messageId: MessageId,
|
||||
val date: TelegramDate,
|
||||
private val chat: Chat,
|
||||
private val chat: PreviewChat,
|
||||
@SerialName(messageThreadIdField)
|
||||
private val messageThreadId: MessageThreadId? = null,
|
||||
private val from: User? = null,
|
||||
private val sender_chat: PublicChat? = null,
|
||||
private val sender_chat: PreviewPublicChat? = null,
|
||||
private val forward_from: User? = null,
|
||||
private val forward_from_chat: Chat? = null,
|
||||
private val forward_from_message_id: MessageId? = null,
|
||||
@@ -274,27 +274,27 @@ internal data class RawMessage(
|
||||
try {
|
||||
chatEvent?.let { chatEvent ->
|
||||
when (chat) {
|
||||
is SupergroupChat -> CommonSupergroupEventMessage(
|
||||
is PreviewSupergroupChat -> CommonSupergroupEventMessage(
|
||||
messageId,
|
||||
from ?: error("Supergroup events are expected to contain 'from' field"),
|
||||
chat,
|
||||
chatEvent as? SupergroupEvent ?: throwWrongChatEvent(SupergroupEvent::class, chatEvent),
|
||||
date.asDate
|
||||
)
|
||||
is GroupChat -> CommonGroupEventMessage(
|
||||
is PreviewGroupChat -> CommonGroupEventMessage(
|
||||
messageId,
|
||||
from ?: error("Supergroup events are expected to contain 'from' field"),
|
||||
chat,
|
||||
chatEvent as? GroupEvent ?: throwWrongChatEvent(GroupChat::class, chatEvent),
|
||||
date.asDate
|
||||
)
|
||||
is ChannelChat -> ChannelEventMessage(
|
||||
is PreviewChannelChat -> ChannelEventMessage(
|
||||
messageId,
|
||||
chat,
|
||||
chatEvent as? ChannelEvent ?: throwWrongChatEvent(ChannelEvent::class, chatEvent),
|
||||
date.asDate
|
||||
)
|
||||
is PrivateChat -> PrivateEventMessage(
|
||||
is PreviewPrivateChat -> PrivateEventMessage(
|
||||
messageId,
|
||||
chat,
|
||||
chatEvent as? PrivateEvent ?: throwWrongChatEvent(PrivateEvent::class, chatEvent),
|
||||
@@ -303,8 +303,8 @@ internal data class RawMessage(
|
||||
else -> error("Expected one of the public chats, but was $chat (in extracting of chat event message)")
|
||||
}
|
||||
} ?: content?.let { content -> when (chat) {
|
||||
is PublicChat -> when (chat) {
|
||||
is ChannelChat -> ChannelContentMessageImpl(
|
||||
is PreviewPublicChat -> when (chat) {
|
||||
is PreviewChannelChat -> ChannelContentMessageImpl(
|
||||
messageId,
|
||||
chat,
|
||||
content,
|
||||
@@ -318,17 +318,16 @@ internal data class RawMessage(
|
||||
author_signature,
|
||||
media_group_id
|
||||
)
|
||||
is ForumChat -> if (messageThreadId != null) {
|
||||
is PreviewForumChat -> if (messageThreadId != null) {
|
||||
val chatId = ChatIdWithThreadId(
|
||||
chat.id.chatId,
|
||||
messageThreadId
|
||||
)
|
||||
val actualForumChat = when (chat) {
|
||||
is ExtendedForumChatImpl -> chat.copy(id = chatId)
|
||||
is ForumChatImpl -> chat.copy(id = chatId)
|
||||
}
|
||||
when (sender_chat) {
|
||||
is ChannelChat -> FromChannelForumContentMessageImpl(
|
||||
is PreviewChannelChat -> FromChannelForumContentMessageImpl(
|
||||
actualForumChat,
|
||||
sender_chat,
|
||||
messageId,
|
||||
@@ -344,7 +343,7 @@ internal data class RawMessage(
|
||||
author_signature,
|
||||
media_group_id
|
||||
)
|
||||
is GroupChat -> AnonymousForumContentMessageImpl(
|
||||
is PreviewGroupChat -> AnonymousForumContentMessageImpl(
|
||||
actualForumChat,
|
||||
messageId,
|
||||
messageThreadId,
|
||||
@@ -377,7 +376,7 @@ internal data class RawMessage(
|
||||
}
|
||||
} else {
|
||||
when (sender_chat) {
|
||||
is ChannelChat -> if (is_automatic_forward == true) {
|
||||
is PreviewChannelChat -> if (is_automatic_forward == true) {
|
||||
ConnectedFromChannelGroupContentMessageImpl(
|
||||
chat,
|
||||
sender_chat,
|
||||
@@ -440,8 +439,8 @@ internal data class RawMessage(
|
||||
)
|
||||
}
|
||||
}
|
||||
is GroupChat -> when (sender_chat) {
|
||||
is ChannelChat -> if (is_automatic_forward == true) {
|
||||
is PreviewGroupChat -> when (sender_chat) {
|
||||
is PreviewChannelChat -> if (is_automatic_forward == true) {
|
||||
ConnectedFromChannelGroupContentMessageImpl(
|
||||
chat,
|
||||
sender_chat,
|
||||
@@ -474,7 +473,7 @@ internal data class RawMessage(
|
||||
media_group_id
|
||||
)
|
||||
}
|
||||
is GroupChat -> AnonymousGroupContentMessageImpl(
|
||||
is PreviewGroupChat -> AnonymousGroupContentMessageImpl(
|
||||
chat,
|
||||
messageId,
|
||||
date.asDate,
|
||||
@@ -504,7 +503,7 @@ internal data class RawMessage(
|
||||
)
|
||||
}
|
||||
}
|
||||
is PrivateChat -> PrivateContentMessageImpl(
|
||||
is PreviewPrivateChat -> PrivateContentMessageImpl(
|
||||
messageId,
|
||||
from ?: error("Was detected common message, but owner (sender) of the message was not found"),
|
||||
chat,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.chat.ChannelChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChannelChat
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
interface ChannelContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, SignedMessage, WithSenderChatMessage {
|
||||
override val chat: ChannelChat
|
||||
override val senderChat: ChannelChat
|
||||
override val chat: PreviewChannelChat
|
||||
override val senderChat: PreviewChannelChat
|
||||
get() = chat
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewGroupChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.GroupEvent
|
||||
|
||||
interface GroupEventMessage<T : GroupEvent> : ChatEventMessage<T>, FromUserMessage
|
||||
interface GroupEventMessage<T : GroupEvent> : ChatEventMessage<T>, FromUserMessage {
|
||||
override val chat: PreviewGroupChat
|
||||
}
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.chat.ChannelChat
|
||||
import dev.inmo.tgbotapi.types.chat.ForumChat
|
||||
import dev.inmo.tgbotapi.types.chat.GroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.*
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
sealed interface GroupContentMessage<T : MessageContent> : PublicContentMessage<T> {
|
||||
override val chat: GroupChat
|
||||
override val chat: PreviewGroupChat
|
||||
}
|
||||
|
||||
sealed interface ForumContentMessage<T : MessageContent> : GroupContentMessage<T>, PossiblyTopicMessage {
|
||||
override val chat: ForumChat
|
||||
override val chat: PreviewForumChat
|
||||
override val threadId: MessageThreadId
|
||||
}
|
||||
|
||||
|
||||
sealed interface FromChannelGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage {
|
||||
val channel: ChannelChat
|
||||
override val senderChat: ChannelChat
|
||||
val channel: PreviewChannelChat
|
||||
override val senderChat: PreviewChannelChat
|
||||
get() = channel
|
||||
}
|
||||
|
||||
@@ -26,7 +24,7 @@ interface ConnectedFromChannelGroupContentMessage<T: MessageContent> : FromChann
|
||||
interface UnconnectedFromChannelGroupContentMessage<T: MessageContent> : FromChannelGroupContentMessage<T>
|
||||
|
||||
interface AnonymousGroupContentMessage<T : MessageContent> : GroupContentMessage<T>, SignedMessage, WithSenderChatMessage {
|
||||
override val senderChat: GroupChat
|
||||
override val senderChat: PreviewGroupChat
|
||||
get() = chat
|
||||
}
|
||||
|
||||
@@ -35,7 +33,7 @@ interface CommonGroupContentMessage<T : MessageContent> : GroupContentMessage<T>
|
||||
interface FromChannelForumContentMessage<T: MessageContent> : FromChannelGroupContentMessage<T>, ForumContentMessage<T>
|
||||
|
||||
interface AnonymousForumContentMessage<T : MessageContent> : ForumContentMessage<T>, SignedMessage, WithSenderChatMessage {
|
||||
override val senderChat: GroupChat
|
||||
override val senderChat: PreviewGroupChat
|
||||
get() = chat
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import korlibs.time.DateTime
|
||||
import dev.inmo.tgbotapi.abstracts.WithChat
|
||||
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import dev.inmo.tgbotapi.types.MessageId
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
import dev.inmo.tgbotapi.types.message.RawMessage
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.descriptors.*
|
||||
@@ -12,14 +13,14 @@ import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
@ClassCastsIncluded(excludeRegex = ".*Impl")
|
||||
interface Message : WithChat {
|
||||
interface Message : WithPreviewChat {
|
||||
val messageId: MessageId
|
||||
val date: DateTime
|
||||
}
|
||||
|
||||
data class UnknownMessageType(
|
||||
override val messageId: MessageId,
|
||||
override val chat: Chat,
|
||||
override val chat: PreviewChat,
|
||||
override val date: DateTime,
|
||||
val insideException: Exception
|
||||
) : Message
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewPrivateChat
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
interface PrivateContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, FromUserMessage
|
||||
interface PrivateContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T>, FromUserMessage {
|
||||
override val chat: PreviewPrivateChat
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewPublicChat
|
||||
import dev.inmo.tgbotapi.types.chat.PublicChat
|
||||
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||
|
||||
sealed interface PublicContentMessage<T: MessageContent> : PossiblySentViaBotCommonMessage<T> {
|
||||
override val chat: PublicChat
|
||||
override val chat: PreviewPublicChat
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewGroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewSupergroupChat
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.SupergroupEvent
|
||||
|
||||
interface SupergroupEventMessage<T : SupergroupEvent> : GroupEventMessage<T>
|
||||
interface SupergroupEventMessage<T : SupergroupEvent> : GroupEventMessage<T> {
|
||||
override val chat: PreviewSupergroupChat
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package dev.inmo.tgbotapi.types.message.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
|
||||
interface WithSenderChatMessage {
|
||||
val senderChat: Chat
|
||||
val senderChat: PreviewChat
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ import dev.inmo.tgbotapi.types.MessageId
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyForwardedMessage
|
||||
import dev.inmo.tgbotapi.types.stories.Story
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@@ -25,7 +27,7 @@ data class StoryContent(
|
||||
replyToMessageId: MessageId?,
|
||||
allowSendingWithoutReply: Boolean?,
|
||||
replyMarkup: KeyboardMarkup?
|
||||
): Request<out Message> {
|
||||
): Request<PossiblyForwardedMessage> {
|
||||
return ForwardMessage(
|
||||
chat.id,
|
||||
toChatId = chatId,
|
||||
|
||||
@@ -10,6 +10,7 @@ import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.files.VoiceFile
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.threadId
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@@ -27,16 +28,16 @@ data class VoiceContent(
|
||||
allowSendingWithoutReply: Boolean?,
|
||||
replyMarkup: KeyboardMarkup?
|
||||
): Request<ContentMessage<VoiceContent>> = SendVoice(
|
||||
chatId,
|
||||
media.fileId,
|
||||
textSources,
|
||||
media.duration,
|
||||
messageThreadId,
|
||||
disableNotification,
|
||||
protectContent,
|
||||
replyToMessageId,
|
||||
allowSendingWithoutReply,
|
||||
replyMarkup
|
||||
chatId = chatId,
|
||||
voice = media.fileId,
|
||||
entities = textSources,
|
||||
threadId = messageThreadId,
|
||||
duration = media.duration,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
replyToMessageId = replyToMessageId,
|
||||
allowSendingWithoutReply = allowSendingWithoutReply,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
|
||||
override fun asTelegramMedia(): TelegramMediaAudio = TelegramMediaAudio(
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.inmo.tgbotapi.utils
|
||||
|
||||
import dev.inmo.kslog.common.KSLog
|
||||
import dev.inmo.kslog.common.TagLogger
|
||||
|
||||
/**
|
||||
* Default realization of [KSLog] which will be used everywhere where there is no some custom variant of [KSLog]
|
||||
*
|
||||
* By default, uses [TagLogger] with tag `KTgBot` (which in fact falling back to [KSLog.default] with `KTgBot` default tag)
|
||||
*/
|
||||
var DefaultKTgBotAPIKSLog: KSLog = TagLogger("KTgBot")
|
||||
@@ -1,8 +1,8 @@
|
||||
package dev.inmo.tgbotapi.types
|
||||
|
||||
import dev.inmo.micro_utils.language_codes.IetfLanguageCode
|
||||
import dev.inmo.micro_utils.language_codes.IetfLang
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalLanguageCode
|
||||
import java.util.*
|
||||
|
||||
fun IetfLanguageCode?.javaLocale() = this ?.code ?.let { Locale.forLanguageTag(it) }
|
||||
fun IetfLang?.javaLocale() = this ?.code ?.let { Locale.forLanguageTag(it) }
|
||||
fun WithOptionalLanguageCode?.javaLocale() = this ?.ietfLanguageCode ?.javaLocale()
|
||||
|
||||
1
tgbotapi.core/src/linuxArm64Main/kotlin/PackageInfo.kt
Normal file
1
tgbotapi.core/src/linuxArm64Main/kotlin/PackageInfo.kt
Normal file
@@ -0,0 +1 @@
|
||||
package dev.inmo.tgbotapi
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor
|
||||
|
||||
import dev.inmo.tgbotapi.bot.ktor.base.MultipleClientKtorRequestsExecutor
|
||||
|
||||
actual typealias KtorRequestsExecutor = MultipleClientKtorRequestsExecutor
|
||||
@@ -0,0 +1,22 @@
|
||||
package dev.inmo.tgbotapi.bot.ktor.base
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
|
||||
/**
|
||||
* This function is used in default constructor of [MultipleClientKtorRequestsExecutor] and on all non-native
|
||||
* platforms and MingwX64 should return [client]
|
||||
*
|
||||
* On LinuxX64 it will create copy with Curl engine or throw an exception if engine is different with Curl
|
||||
*
|
||||
* @throws IllegalArgumentException When pass non Curl-based [HttpClient] on LinuxX64
|
||||
*/
|
||||
internal actual inline fun platformClientCopy(client: HttpClient): HttpClient = (client.engineConfig as? CIOEngineConfig) ?.let {
|
||||
lateinit var config: HttpClientConfig<out CIOEngineConfig>
|
||||
client.config {
|
||||
config = this as HttpClientConfig<out CIOEngineConfig>
|
||||
}.close()
|
||||
HttpClient(CIO) {
|
||||
this.plusAssign(config)
|
||||
}
|
||||
} ?: throw IllegalArgumentException("On LinuxX64 TelegramBotAPI currently support only Curl Ktor HttpClient engine")
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.inmo.tgbotapi.requests.abstracts
|
||||
|
||||
import dev.inmo.micro_utils.common.MPPFile
|
||||
import dev.inmo.micro_utils.ktor.common.input
|
||||
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
|
||||
|
||||
actual fun MPPFile.asMultipartFile(): MultipartFile = MultipartFile(this.name) {
|
||||
input()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.tgbotapi.utils
|
||||
|
||||
import io.ktor.utils.io.ByteReadChannel
|
||||
import io.ktor.utils.io.core.Input
|
||||
import io.ktor.utils.io.readRemaining
|
||||
|
||||
actual suspend fun ByteReadChannel.asInput(): Input = readRemaining()
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.inmo.tgbotapi.utils
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
//actual typealias MimeType = MimeType
|
||||
|
||||
@OptIn(RiskFeature::class)
|
||||
@Serializable(MimeTypeSerializer::class)
|
||||
actual data class MimeType(
|
||||
actual val raw: String
|
||||
)
|
||||
internal actual fun createMimeType(raw: String): MimeType = MimeType(raw)
|
||||
@@ -4,6 +4,7 @@ import kotlinx.serialization.Serializable
|
||||
|
||||
//actual typealias MimeType = MimeType
|
||||
|
||||
@OptIn(RiskFeature::class)
|
||||
@Serializable(MimeTypeSerializer::class)
|
||||
actual data class MimeType(
|
||||
actual val raw: String
|
||||
|
||||
@@ -24,6 +24,7 @@ class TelegramBotAPISymbolProcessor(
|
||||
private val outputFile: String = "Output",
|
||||
private val outputFolder: String? = null
|
||||
) : SymbolProcessor {
|
||||
@OptIn(RiskFeature::class)
|
||||
private val classCastsIncludedClassName = ClassCastsIncluded::class.asClassName()
|
||||
@OptIn(KspExperimental::class, RiskFeature::class)
|
||||
override fun process(resolver: Resolver): List<KSAnnotated> {
|
||||
|
||||
@@ -13,7 +13,7 @@ kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api project(":tgbotapi.core")
|
||||
api project(path: ":tgbotapi.core")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,17 @@ import dev.inmo.tgbotapi.types.chat.ExtendedSupergroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.ForumChat
|
||||
import dev.inmo.tgbotapi.types.chat.GroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.PossiblyPremiumChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewBot
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChannelChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewForumChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewGroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewPrivateChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewPublicChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewSuperPublicChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewSupergroupChat
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewUser
|
||||
import dev.inmo.tgbotapi.types.chat.PreviewUsernameChat
|
||||
import dev.inmo.tgbotapi.types.chat.PrivateChat
|
||||
import dev.inmo.tgbotapi.types.chat.PublicChat
|
||||
import dev.inmo.tgbotapi.types.chat.SuperPublicChat
|
||||
@@ -1969,12 +1980,30 @@ public inline fun Chat.userOrThrow(): User = this as dev.inmo.tgbotapi.types.cha
|
||||
|
||||
public inline fun <T> Chat.ifUser(block: (User) -> T): T? = userOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewUserOrNull(): PreviewUser? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewUser
|
||||
|
||||
public inline fun Chat.previewUserOrThrow(): PreviewUser = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewUser
|
||||
|
||||
public inline fun <T> Chat.ifPreviewUser(block: (PreviewUser) -> T): T? = previewUserOrNull()
|
||||
?.let(block)
|
||||
|
||||
public inline fun Chat.botOrNull(): Bot? = this as? dev.inmo.tgbotapi.types.chat.Bot
|
||||
|
||||
public inline fun Chat.botOrThrow(): Bot = this as dev.inmo.tgbotapi.types.chat.Bot
|
||||
|
||||
public inline fun <T> Chat.ifBot(block: (Bot) -> T): T? = botOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewBotOrNull(): PreviewBot? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewBot
|
||||
|
||||
public inline fun Chat.previewBotOrThrow(): PreviewBot = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewBot
|
||||
|
||||
public inline fun <T> Chat.ifPreviewBot(block: (PreviewBot) -> T): T? = previewBotOrNull()
|
||||
?.let(block)
|
||||
|
||||
public inline fun Chat.commonBotOrNull(): CommonBot? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.CommonBot
|
||||
|
||||
@@ -1992,6 +2021,87 @@ public inline fun Chat.commonUserOrThrow(): CommonUser = this as
|
||||
public inline fun <T> Chat.ifCommonUser(block: (CommonUser) -> T): T? = commonUserOrNull()
|
||||
?.let(block)
|
||||
|
||||
public inline fun Chat.previewChatOrNull(): PreviewChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
|
||||
public inline fun Chat.previewChatOrThrow(): PreviewChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewChat(block: (PreviewChat) -> T): T? = previewChatOrNull()
|
||||
?.let(block)
|
||||
|
||||
public inline fun Chat.previewUsernameChatOrNull(): PreviewUsernameChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewUsernameChat
|
||||
|
||||
public inline fun Chat.previewUsernameChatOrThrow(): PreviewUsernameChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewUsernameChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewUsernameChat(block: (PreviewUsernameChat) -> T): T? =
|
||||
previewUsernameChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewPrivateChatOrNull(): PreviewPrivateChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewPrivateChat
|
||||
|
||||
public inline fun Chat.previewPrivateChatOrThrow(): PreviewPrivateChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewPrivateChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewPrivateChat(block: (PreviewPrivateChat) -> T): T? =
|
||||
previewPrivateChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewPublicChatOrNull(): PreviewPublicChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewPublicChat
|
||||
|
||||
public inline fun Chat.previewPublicChatOrThrow(): PreviewPublicChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewPublicChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewPublicChat(block: (PreviewPublicChat) -> T): T? =
|
||||
previewPublicChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewSuperPublicChatOrNull(): PreviewSuperPublicChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewSuperPublicChat
|
||||
|
||||
public inline fun Chat.previewSuperPublicChatOrThrow(): PreviewSuperPublicChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewSuperPublicChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewSuperPublicChat(block: (PreviewSuperPublicChat) -> T): T? =
|
||||
previewSuperPublicChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewChannelChatOrNull(): PreviewChannelChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewChannelChat
|
||||
|
||||
public inline fun Chat.previewChannelChatOrThrow(): PreviewChannelChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewChannelChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewChannelChat(block: (PreviewChannelChat) -> T): T? =
|
||||
previewChannelChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewGroupChatOrNull(): PreviewGroupChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewGroupChat
|
||||
|
||||
public inline fun Chat.previewGroupChatOrThrow(): PreviewGroupChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewGroupChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewGroupChat(block: (PreviewGroupChat) -> T): T? =
|
||||
previewGroupChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewSupergroupChatOrNull(): PreviewSupergroupChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewSupergroupChat
|
||||
|
||||
public inline fun Chat.previewSupergroupChatOrThrow(): PreviewSupergroupChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewSupergroupChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewSupergroupChat(block: (PreviewSupergroupChat) -> T): T? =
|
||||
previewSupergroupChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.previewForumChatOrNull(): PreviewForumChat? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.PreviewForumChat
|
||||
|
||||
public inline fun Chat.previewForumChatOrThrow(): PreviewForumChat = this as
|
||||
dev.inmo.tgbotapi.types.chat.PreviewForumChat
|
||||
|
||||
public inline fun <T> Chat.ifPreviewForumChat(block: (PreviewForumChat) -> T): T? =
|
||||
previewForumChatOrNull() ?.let(block)
|
||||
|
||||
public inline fun Chat.unknownChatTypeOrNull(): UnknownChatType? = this as?
|
||||
dev.inmo.tgbotapi.types.chat.UnknownChatType
|
||||
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.extensions
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.TextedWithTextSources
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.textsources.BotCommandTextSource
|
||||
import dev.inmo.tgbotapi.types.message.textsources.TextSource
|
||||
|
||||
object TelegramBotCommandsDefaults {
|
||||
const val defaultArgsSeparator = " "
|
||||
val defaultArgsSeparatorRegex = Regex(defaultArgsSeparator)
|
||||
const val defaultNamesArgsSeparator = "="
|
||||
val defaultNamesArgsSeparatorRegex = Regex(defaultNamesArgsSeparator)
|
||||
}
|
||||
|
||||
@Deprecated(message = "Replaced", replaceWith = ReplaceWith("TelegramBotCommandsDefaults.defaultArgsSeparatorRegex", "dev.inmo.tgbotapi.extensions.utils.extensions.TelegramBotCommandsDefaults"))
|
||||
val defaultArgsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun List<TextSource>.parseCommandsWithArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
): MutableMap<String, Array<String>> {
|
||||
val result = mutableMapOf<String, Array<String>>()
|
||||
var currentBotCommandSource: BotCommandTextSource? = null
|
||||
var currentArgs = ""
|
||||
|
||||
fun includeCurrent() = currentBotCommandSource?.let {
|
||||
currentArgs = currentArgs.trim()
|
||||
result[it.command] = if (currentArgs.isNotEmpty()) {
|
||||
currentArgs.split(argsSeparator).toTypedArray()
|
||||
} else {
|
||||
emptyArray()
|
||||
}
|
||||
currentArgs = ""
|
||||
currentBotCommandSource = null
|
||||
}
|
||||
|
||||
for (textSource in this) {
|
||||
if (textSource is BotCommandTextSource) {
|
||||
includeCurrent()
|
||||
currentBotCommandSource = textSource
|
||||
} else {
|
||||
currentArgs += textSource.source
|
||||
}
|
||||
}
|
||||
includeCurrent()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun TextedWithTextSources.parseCommandsWithArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
) = textSources?.parseCommandsWithArgs(argsSeparator) ?: emptyMap()
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun ContentMessage<TextContent>.parseCommandsWithArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
) = content.parseCommandsWithArgs(argsSeparator)
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun List<TextSource>.parseCommandsWithArgs(
|
||||
argsSeparator: String
|
||||
): MutableMap<String, Array<String>> = parseCommandsWithArgs(Regex(argsSeparator))
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun TextedWithTextSources.parseCommandsWithArgs(
|
||||
argsSeparator: String
|
||||
) = parseCommandsWithArgs(Regex(argsSeparator))
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun ContentMessage<TextContent>.parseCommandsWithArgs(
|
||||
argsSeparator: String
|
||||
) = parseCommandsWithArgs(Regex(argsSeparator))
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] to create base [argsSeparator] split args for commands and map their as k-v pairs.
|
||||
* Sample:
|
||||
*
|
||||
* ```bash
|
||||
* /command args1=value1 arg2=value2 arg1=value3
|
||||
* ```
|
||||
*
|
||||
* Will produce [Map] with one key `command` and the list of three pairs:
|
||||
*
|
||||
* 1. `args1` to `value1`
|
||||
* 2. `args2` to `value2`
|
||||
* 3. `args1` to `value3`
|
||||
*
|
||||
* @return Array of named arguments
|
||||
*/
|
||||
fun List<TextSource>.parseCommandsWithNamedArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
): Map<String, List<Pair<String, String>>> {
|
||||
val withArgs = parseCommandsWithArgs(argsSeparator)
|
||||
|
||||
return withArgs.mapValues { (k, v) ->
|
||||
v.flatMap {
|
||||
it.split(nameArgSeparator, 2).map { v -> it to v }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] to create base [argsSeparator] split args for commands and map their as k-v pairs.
|
||||
* Sample:
|
||||
*
|
||||
* ```bash
|
||||
* /command args1=value1 arg2=value2 arg1=value3
|
||||
* ```
|
||||
*
|
||||
* Will produce [Map] with one key `command` and the list of three pairs:
|
||||
*
|
||||
* 1. `args1` to `value1`
|
||||
* 2. `args2` to `value2`
|
||||
* 3. `args1` to `value3`
|
||||
*
|
||||
* @return Array of named arguments
|
||||
*/
|
||||
fun TextedWithTextSources.parseCommandsWithNamedArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
) = textSources?.parseCommandsWithNamedArgs(argsSeparator = argsSeparator, nameArgSeparator = nameArgSeparator) ?: emptyMap()
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] to create base [argsSeparator] split args for commands and map their as k-v pairs.
|
||||
* Sample:
|
||||
*
|
||||
* ```bash
|
||||
* /command args1=value1 arg2=value2 arg1=value3
|
||||
* ```
|
||||
*
|
||||
* Will produce [Map] with one key `command` and the list of three pairs:
|
||||
*
|
||||
* 1. `args1` to `value1`
|
||||
* 2. `args2` to `value2`
|
||||
* 3. `args1` to `value3`
|
||||
*
|
||||
* @return Array of named arguments
|
||||
*/
|
||||
fun ContentMessage<TextContent>.parseCommandsWithNamedArgs(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
) = content.parseCommandsWithNamedArgs(argsSeparator = argsSeparator, nameArgSeparator = nameArgSeparator)
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] to create base [argsSeparator] split args for commands and map their as k-v pairs.
|
||||
* Sample:
|
||||
*
|
||||
* ```bash
|
||||
* /command args1=value1 arg2=value2 arg1=value3
|
||||
* ```
|
||||
*
|
||||
* Will produce [Map] with one key `command` and the list of three pairs:
|
||||
*
|
||||
* 1. `args1` to `value1`
|
||||
* 2. `args2` to `value2`
|
||||
* 3. `args1` to `value3`
|
||||
*
|
||||
* @return Array of named arguments
|
||||
*/
|
||||
fun List<TextSource>.parseCommandsWithNamedArgs(
|
||||
argsSeparator: String,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
): Map<String, List<Pair<String, String>>> = parseCommandsWithNamedArgs(Regex(pattern = argsSeparator), nameArgSeparator)
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] to create base [argsSeparator] split args for commands and map their as k-v pairs.
|
||||
* Sample:
|
||||
*
|
||||
* ```bash
|
||||
* /command args1=value1 arg2=value2 arg1=value3
|
||||
* ```
|
||||
*
|
||||
* Will produce [Map] with one key `command` and the list of three pairs:
|
||||
*
|
||||
* 1. `args1` to `value1`
|
||||
* 2. `args2` to `value2`
|
||||
* 3. `args1` to `value3`
|
||||
*
|
||||
* @return Array of named arguments
|
||||
*/
|
||||
fun TextedWithTextSources.parseCommandsWithNamedArgs(
|
||||
argsSeparator: String,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
) = parseCommandsWithNamedArgs(argsSeparator = Regex(pattern = argsSeparator), nameArgSeparator = nameArgSeparator)
|
||||
|
||||
/**
|
||||
* Uses [parseCommandsWithArgs] to create base [argsSeparator] split args for commands and map their as k-v pairs.
|
||||
* Sample:
|
||||
*
|
||||
* ```bash
|
||||
* /command args1=value1 arg2=value2 arg1=value3
|
||||
* ```
|
||||
*
|
||||
* Will produce [Map] with one key `command` and the list of three pairs:
|
||||
*
|
||||
* 1. `args1` to `value1`
|
||||
* 2. `args2` to `value2`
|
||||
* 3. `args1` to `value3`
|
||||
*
|
||||
* @return Array of named arguments
|
||||
*/
|
||||
fun ContentMessage<TextContent>.parseCommandsWithNamedArgs(
|
||||
argsSeparator: String,
|
||||
nameArgSeparator: Regex = TelegramBotCommandsDefaults.defaultNamesArgsSeparatorRegex,
|
||||
) = parseCommandsWithNamedArgs(argsSeparator = Regex(pattern = argsSeparator), nameArgSeparator = nameArgSeparator)
|
||||
|
||||
|
||||
// Deprecations
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
@Deprecated("Renamed", ReplaceWith("parseCommandsWithArgs(argsSeparator)", "dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs"))
|
||||
fun List<TextSource>.parseCommandsWithParams(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
): MutableMap<String, Array<String>> = parseCommandsWithArgs(argsSeparator)
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
@Deprecated("Renamed", ReplaceWith("parseCommandsWithArgs(argsSeparator)", "dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs"))
|
||||
fun TextedWithTextSources.parseCommandsWithParams(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
) = parseCommandsWithArgs(argsSeparator)
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
@Deprecated("Renamed", ReplaceWith("parseCommandsWithArgs(argsSeparator)", "dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs"))
|
||||
fun ContentMessage<TextContent>.parseCommandsWithParams(
|
||||
argsSeparator: Regex = TelegramBotCommandsDefaults.defaultArgsSeparatorRegex
|
||||
) = parseCommandsWithArgs(argsSeparator)
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.extensions
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.TextedWithTextSources
|
||||
import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull
|
||||
import dev.inmo.tgbotapi.extensions.utils.ifBotCommandTextSource
|
||||
import dev.inmo.tgbotapi.extensions.utils.whenBotCommandTextSource
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.textsources.BotCommandTextSource
|
||||
import dev.inmo.tgbotapi.types.message.textsources.TextSource
|
||||
|
||||
// Sources
|
||||
|
||||
/**
|
||||
* Parse text sources to find commands with their arguments. This method will skip all the text sources __before__
|
||||
* first command and all following text sources until the next command will be guessed as an args of last found command
|
||||
*/
|
||||
fun List<TextSource>.parseCommandsWithArgsSources(): Map<BotCommandTextSource, Array<TextSource>> {
|
||||
var currentCommandTextSource: BotCommandTextSource? = null
|
||||
val currentArgs = mutableListOf<TextSource>()
|
||||
val result = mutableMapOf<BotCommandTextSource, Array<TextSource>>()
|
||||
|
||||
fun addCurrentCommandToResult() {
|
||||
currentCommandTextSource ?.let {
|
||||
result[it] = currentArgs.toTypedArray()
|
||||
currentArgs.clear()
|
||||
}
|
||||
}
|
||||
|
||||
forEach {
|
||||
it.whenBotCommandTextSource {
|
||||
addCurrentCommandToResult()
|
||||
currentCommandTextSource = it
|
||||
return@forEach
|
||||
}
|
||||
currentArgs.add(it)
|
||||
}
|
||||
addCurrentCommandToResult()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse text sources to find commands with their arguments. This method will skip all the text sources __before__
|
||||
* first command and all following text sources until the next command will be guessed as an args of last found command
|
||||
*/
|
||||
fun TextedWithTextSources.parseCommandsWithArgsSources() = textSources?.parseCommandsWithArgsSources() ?: emptyMap()
|
||||
|
||||
/**
|
||||
* Parse text sources to find commands with their arguments. This method will skip all the text sources __before__
|
||||
* first command and all following text sources until the next command will be guessed as an args of last found command
|
||||
*/
|
||||
fun ContentMessage<TextContent>.parseCommandsWithArgsSources() = content.parseCommandsWithArgsSources()
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.extensions
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.FromUser
|
||||
import dev.inmo.tgbotapi.abstracts.WithChat
|
||||
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
import dev.inmo.tgbotapi.types.UserId
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
@@ -15,13 +15,13 @@ import kotlinx.coroutines.flow.transform
|
||||
* Will pass only those [T] which have [sameChat] as [chatId]
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T : WithChat> Flow<T>.fromChat(chatId: ChatIdentifier): Flow<T> = filter { it.sameChat(chatId) }
|
||||
inline fun <T : WithPreviewChat> Flow<T>.fromChat(chatId: ChatIdentifier): Flow<T> = filter { it.sameChat(chatId) }
|
||||
|
||||
/**
|
||||
* Will pass only those [T] which have [sameChat] as [chatId]
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T : WithChat> Flow<T>.fromChat(chat: Chat): Flow<T> = fromChat(chat.id)
|
||||
inline fun <T : WithPreviewChat> Flow<T>.fromChat(chat: Chat): Flow<T> = fromChat(chat.id)
|
||||
|
||||
/**
|
||||
* @return [Flow] with the [FromUser.user] field [User.id] the same as [userId]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.extensions
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.WithChat
|
||||
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
|
||||
import dev.inmo.tgbotapi.extensions.utils.usernameChatOrNull
|
||||
import dev.inmo.tgbotapi.extensions.utils.whenUsernameChat
|
||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||
@@ -16,21 +16,23 @@ import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull
|
||||
* @return true in case if [this] message is placed in the chat with id == [chatId]
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun WithChat.sameChat(chatId: ChatIdentifier) = chat.id == chatId || (chatId is Username && chat.whenUsernameChat {
|
||||
it.username == chatId
|
||||
} ?: false)
|
||||
inline fun WithPreviewChat.sameChat(chatId: ChatIdentifier) =
|
||||
chat.id == chatId || (chatId is Username && chat.whenUsernameChat {
|
||||
it.username == chatId
|
||||
} ?: false)
|
||||
|
||||
/**
|
||||
* @return true in case if [this] message is placed in the [chat]
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun WithChat.sameChat(chat: Chat) = sameChat(chat.id) || chat.usernameChatOrNull() ?.username ?.let { sameChat(it) } ?: false
|
||||
inline fun WithPreviewChat.sameChat(chat: Chat) =
|
||||
sameChat(chat.id) || chat.usernameChatOrNull()?.username?.let { sameChat(it) } ?: false
|
||||
|
||||
/**
|
||||
* @return true in case if [this] message is placed in the same chat that [other]
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun WithChat.sameChat(other: Message) = sameChat(other.chat)
|
||||
inline fun WithPreviewChat.sameChat(other: Message) = sameChat(other.chat)
|
||||
|
||||
/**
|
||||
* @return true in case if [this] message is from the same chat (with id == [chatId]) and [this] [Message.messageId]
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.extensions
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.TextedWithTextSources
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.textsources.BotCommandTextSource
|
||||
import dev.inmo.tgbotapi.types.message.textsources.TextSource
|
||||
|
||||
|
||||
val defaultArgsSeparator = Regex(" ")
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun List<TextSource>.parseCommandsWithParams(
|
||||
argsSeparator: Regex = defaultArgsSeparator
|
||||
): MutableMap<String, Array<String>> {
|
||||
val result = mutableMapOf<String, Array<String>>()
|
||||
var currentBotCommandSource: BotCommandTextSource? = null
|
||||
var currentArgs = ""
|
||||
fun includeCurrent() = currentBotCommandSource ?.let {
|
||||
currentArgs = currentArgs.trim()
|
||||
result[it.command] = if (currentArgs.isNotEmpty()) {
|
||||
currentArgs.split(argsSeparator).toTypedArray()
|
||||
} else {
|
||||
emptyArray()
|
||||
}
|
||||
currentArgs = ""
|
||||
currentBotCommandSource = null
|
||||
}
|
||||
for (textSource in this) {
|
||||
if (textSource is BotCommandTextSource) {
|
||||
includeCurrent()
|
||||
currentBotCommandSource = textSource
|
||||
} else {
|
||||
currentArgs += textSource.source
|
||||
}
|
||||
}
|
||||
includeCurrent()
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun TextedWithTextSources.parseCommandsWithParams(
|
||||
argsSeparator: Regex = defaultArgsSeparator
|
||||
) = textSources ?.parseCommandsWithParams(argsSeparator) ?: emptyMap()
|
||||
|
||||
/**
|
||||
* Parse commands and their args. Logic will find command, get all subsequent data as args until new command
|
||||
*/
|
||||
fun ContentMessage<TextContent>.parseCommandsWithParams(
|
||||
argsSeparator: Regex = defaultArgsSeparator
|
||||
) = content.parseCommandsWithParams(argsSeparator)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user