mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2026-07-01 15:45:31 +00:00
Compare commits
33 Commits
v34.0.0
...
renovate/k
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fc794c229 | ||
| c7761fd294 | |||
| 0e9f9111eb | |||
| 763b07fc3c | |||
| 481a3b4ff1 | |||
| fc764d1f95 | |||
| 68987feabb | |||
| 5341b2eccf | |||
| 7e4efcd645 | |||
| 390770ca80 | |||
| b054f3d1b5 | |||
| 3a05a88d4f | |||
| edad79ace8 | |||
| c3495d8817 | |||
| 88a54350df | |||
| 8acd7453a6 | |||
| e793eea943 | |||
| 6b4999095e | |||
| 23578d25ef | |||
| b5238320a5 | |||
| 4cfc054526 | |||
| 1091dbdb5e | |||
| 313fcb3325 | |||
| 1c06ec8687 | |||
| 9fc80fdd4d | |||
| df5018ecf5 | |||
| 0188c65319 | |||
| c2b1a5d44b | |||
| 6bdd217530 | |||
| f6d5b3ea71 | |||
| 628e877064 | |||
| 8ba13ea5fc | |||
| b8e995f36d |
4
.github/workflows/kdocs.yml
vendored
4
.github/workflows/kdocs.yml
vendored
@@ -12,10 +12,10 @@ jobs:
|
||||
with:
|
||||
java-version: 17
|
||||
- name: Build
|
||||
run: ./gradlew dokkaHtmlMultiModule
|
||||
run: ./gradlew :docs:dokkaGenerate
|
||||
- name: Publish KDocs
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./build/dokka/htmlMultiModule
|
||||
publish_dir: ./docs/build/dokka/html
|
||||
publish_branch: kdocs
|
||||
|
||||
53
CHANGELOG.md
53
CHANGELOG.md
@@ -1,5 +1,58 @@
|
||||
# TelegramBotAPI changelog
|
||||
|
||||
## 35.1.0
|
||||
|
||||
* `Dependencies`:
|
||||
* `Kotlin`: `2.3.20` -> `2.3.21`
|
||||
* `Coroutines`: `1.10.2` -> `1.11.0`
|
||||
* `Ktor`: `3.4.2` -> `3.5.1`
|
||||
* `KSP`: `2.3.6` -> `2.3.9`
|
||||
* `MicroUtils`: `0.29.2` -> `0.30.0`
|
||||
* `Dokka`: `2.0.0` -> `2.2.0`
|
||||
* `Versions`: `0.53.0` -> `0.54.0`
|
||||
* `NMCP`: `1.4.4` -> `1.6.0`
|
||||
* `Build`:
|
||||
* Updated Gradle wrapper `8.13` -> `9.6.1` and migrated build scripts to be Gradle 9 compatible (`Project.exec` -> `providers.exec`, `tasks.whenTaskAdded` -> `tasks.configureEach`)
|
||||
* Migrated Dokka documentation to the Dokka Gradle Plugin v2: the `docs` module is now included in the build as the KDocs aggregator (`./gradlew :docs:dokkaGenerate`) and the `Publish KDocs` workflow was updated accordingly
|
||||
|
||||
## 35.0.0
|
||||
|
||||
**THIS UPDATE CONTAINS SUPPORT OF [TELEGRAM BOTS API 10.1](https://core.telegram.org/bots/api-changelog#june-11-2026)**
|
||||
|
||||
**Breaking changes**:
|
||||
|
||||
* `EditTextChatMessage.text` changed from `String` to `String?` (rich edits carry no text) — implementations overriding it must widen the type and readers must handle `null`
|
||||
* `EditChatMessageText.text` changed from `String` to `String?`; its `textSources` is now `null` when there is no text — code reading `text` as non-null must handle `null`
|
||||
* `ExtendedBot` gained the `supportsJoinRequestQueries` field inserted between `supportsGuestQueries` and `canConnectToBusiness` — positional constructor calls and `componentN` destructuring shift and must be updated
|
||||
|
||||
**Migration advice**: Handle nullable `text` on `EditTextChatMessage`/`EditChatMessageText`; construct `ExtendedBot` with named arguments
|
||||
|
||||
* `Core`:
|
||||
* (`Rich Messages`) Added `RichText` (`RichTextPlain`, `RichTextGroup`, `RichTextEntity`) hierarchy with all 25 `RichText*` entity types and a recursive serializer supporting plain strings, arrays and typed objects; every `RichText` exposes `rawText`, `markdown` and `html` renderings
|
||||
* (`Rich Messages`) Added `RichBlock` hierarchy with all 21 `RichBlock*` types plus `RichBlockCaption`, `RichBlockTableCell` and `RichBlockListItem`; every `RichBlock` exposes `markdown`/`html` source, the `RichBlockMedia` marker interface and `subBlocks`/`search` navigation helpers
|
||||
* (`Rich Messages`) Added `RichTextInfo` type (with `markdown`/`html` source built from its blocks) and `RichMessageContent` message content; `RichMessageContent.createResend` re-sends the content (forwarded when it contains media blocks, otherwise re-built through `SendRichMessage`); parsed `rich_message` in `RawMessage`; added `RichMessageContentMessage` typealias
|
||||
* (`Rich Messages`) Added `InputRichMessage` (internal constructor with `InputRichMessageHTML`/`InputRichMessageMarkdown` factories) and `InputRichMessageContent` usable as `InputMessageContent`
|
||||
* (`Rich Messages`) Added Rich Messages DSL builders `buildRichText`/`RichTextBuilder`, `buildRichBlocks`/`RichBlocksBuilder`, `buildRichTextInfo` and `RichBlockListBuilder` (marked with the `@RichTextDsl` DSL marker)
|
||||
* (`Rich Messages`) Added Rich Markdown/HTML source helpers `String.escapeRichMarkdown()` and `List<RichBlock>.toRichMarkdown()`/`toRichHtml()`
|
||||
* (`Rich Messages`) Added `SendRichMessage` and `SendRichMessageDraft` requests
|
||||
* (`Rich Messages`) Added `richMessage` parameter to `EditChatMessageText`; its `text` is now nullable (per API) and the `EditChatMessageRichText` factory builds a rich edit; widened `EditTextChatMessage.text` to nullable
|
||||
* (`Polls`) Added `Link` type (`dev.inmo.tgbotapi.types.Link`) implementing `PollMedia`, carrying the `url` of a link attached to a poll option
|
||||
* (`Polls`) Added `link` field parsing to `PollMedia` deserialization/serialization
|
||||
* (`Polls`) Added `TelegramMediaLink` (`InputMediaLink`) implementing `InputPollOptionMedia`, usable as a poll option media
|
||||
* (`Join Request Queries`) Added `ChatJoinRequestQueryId` value class and `queryId` field to `ChatJoinRequest`
|
||||
* (`Join Request Queries`) Added `supportsJoinRequestQueries` flag to `ExtendedBot` (`User.supports_join_request_queries`)
|
||||
* (`Join Request Queries`) Added `guardBot` field to `ExtendedChat` (`ChatFullInfo.guard_bot`), parsed for public chats
|
||||
* (`Join Request Queries`) Added `AnswerChatJoinRequestQuery` request and `ChatJoinRequestQueryResult` sealed interface (`Approve`/`Decline`/`Queue`/`Unknown`) serialized as a plain string
|
||||
* (`Join Request Queries`) Added `SendChatJoinRequestWebApp` request
|
||||
* `API`:
|
||||
* (`Rich Messages`) Added `sendRichMessage` and `sendRichMessageDraft` `TelegramBot` extensions
|
||||
* (`Join Request Queries`) Added `answerChatJoinRequestQuery` and `sendChatJoinRequestWebApp` `TelegramBot` extensions
|
||||
* `BehaviourBuilder`:
|
||||
* (`Rich Messages`) Added `onRichMessage` trigger and `waitRichMessage`/`waitRichMessageMessage` expectations
|
||||
* `Utils`:
|
||||
* (`Rich Messages`) Added `Flow<ContentMessage<*>>.onlyRichMessageContentMessages()`
|
||||
* (`Join Request Queries`) Added `ChatJoinRequest.query_id` raw accessor
|
||||
|
||||
## 34.0.0
|
||||
|
||||
**THIS UPDATE CONTAINS SUPPORT OF [TELEGRAM BOTS API 10.0](https://core.telegram.org/bots/api-changelog#may-8-2026)**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# TelegramBotAPI [](https://central.sonatype.com/artifact/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#may-8-2026)
|
||||
# TelegramBotAPI [](https://central.sonatype.com/artifact/dev.inmo/tgbotapi) [](https://core.telegram.org/bots/api-changelog#june-11-2026)
|
||||
|
||||
| Docs | [](https://tgbotapi.inmo.dev/index.html) [](https://docs.inmo.dev/tgbotapi/index.html) |
|
||||
|:----------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
|
||||
|
||||
@@ -48,3 +48,15 @@ Each section can be ommited if there are no any changes in the section. In case
|
||||
* `Core`:
|
||||
* (`Guest mode`) // change data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
When a property (or method) can be declared on an interface/class and implemented by each inheritor - it MUST be declared there and overridden per implementation. DO NOT implement such behaviour as a common extension property/function that dispatches with a `when (this)` over every subtype: those branches silently drift out of sync when new subtypes are added and are not part of the type contract. If a part of the implementation is reused across several inheritors, keep that part in a shared helper (a companion-object function of the owner, or an `internal` top-level function for logic shared between different types) and let the overrides reuse it.
|
||||
|
||||
---
|
||||
|
||||
All work MUST be performed in the normal (main) working worktree of the repository. DO NOT create or do the work inside a separate worktree (for example `.claude/worktrees/...`): commits made there leave the main checkout behind and force an extra fast-forward/pull to land the changes. If some environment forces an isolated worktree, fast-forward the main branch onto those commits and continue in the main worktree.
|
||||
|
||||
---
|
||||
|
||||
When a prompt contains a list of several subtasks, run each subtask as its own subagent (one subagent per subtask) instead of doing all of them inline in the main thread.
|
||||
|
||||
15
build.gradle
15
build.gradle
@@ -21,6 +21,11 @@ plugins {
|
||||
alias(libs.plugins.nmcp.aggregation)
|
||||
}
|
||||
|
||||
// docs is a dokka-only aggregator module, exclude it from binary compatibility validation
|
||||
apiValidation {
|
||||
ignoredProjects += ["docs"]
|
||||
}
|
||||
|
||||
|
||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
||||
nmcpAggregation {
|
||||
@@ -44,7 +49,7 @@ allprojects {
|
||||
mavenLocal()
|
||||
}
|
||||
if (it != rootProject.findProject("docs")) {
|
||||
tasks.whenTaskAdded { task ->
|
||||
tasks.configureEach { task ->
|
||||
if(task.name == "jsLegacyBrowserTest" || task.name == "jsLegacyNodeTest") {
|
||||
task.enabled = false
|
||||
}
|
||||
@@ -54,13 +59,9 @@ allprojects {
|
||||
apply from: "./extensions.gradle"
|
||||
|
||||
private String getCurrentVersionChangelog() {
|
||||
OutputStream changelogDataOS = new ByteArrayOutputStream()
|
||||
exec {
|
||||
standardOutput = changelogDataOS
|
||||
return providers.exec {
|
||||
commandLine './changelog_info_retriever', "$library_version", 'CHANGELOG.md'
|
||||
}
|
||||
|
||||
return changelogDataOS.toString().trim()
|
||||
}.standardOutput.asText.get().trim()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,14 +39,10 @@ private List<SourceDirectorySet> findSourcesWithName(String... approximateNames)
|
||||
}.collect { it.kotlin }
|
||||
}
|
||||
|
||||
Object callback = {
|
||||
switch (true) {
|
||||
case project.hasProperty("DOKKA_PATH"):
|
||||
outputDirectory = project.property("DOKKA_PATH").toString()
|
||||
break
|
||||
case System.getenv("DOKKA_PATH") != null:
|
||||
outputDirectory = System.getenv("DOKKA_PATH")
|
||||
break
|
||||
dokka {
|
||||
// aggregating every module's sources into one publication needs more heap than the worker default
|
||||
dokkaGeneratorIsolation = ProcessIsolation {
|
||||
it.maxHeapSize.set("4g")
|
||||
}
|
||||
|
||||
dokkaSourceSets {
|
||||
@@ -55,7 +51,7 @@ Object callback = {
|
||||
|
||||
sourceLink {
|
||||
localDirectory.set(file("../"))
|
||||
remoteUrl.set(new URL("https://github.com/InsanusMokrassar/ktgbotapi"))
|
||||
remoteUrl.set(new URI("https://github.com/InsanusMokrassar/ktgbotapi"))
|
||||
remoteLineSuffix.set("#L")
|
||||
}
|
||||
}
|
||||
@@ -73,6 +69,3 @@ Object callback = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.dokkaGfm(callback)
|
||||
tasks.dokkaHtml(callback)
|
||||
|
||||
@@ -6,4 +6,4 @@ kotlin.incremental=true
|
||||
kotlin.incremental.js=true
|
||||
|
||||
library_group=dev.inmo
|
||||
library_version=34.0.0
|
||||
library_version=35.1.0
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
[versions]
|
||||
|
||||
kotlin = "2.3.20"
|
||||
kotlin = "2.4.0"
|
||||
kotlin-serialization = "1.11.0"
|
||||
kotlin-coroutines = "1.10.2"
|
||||
kotlin-coroutines = "1.11.0"
|
||||
|
||||
javax-activation = "1.1.1"
|
||||
|
||||
korlibs = "5.4.0"
|
||||
uuid = "0.8.4"
|
||||
ktor = "3.4.2"
|
||||
ktor = "3.5.1"
|
||||
|
||||
ksp = "2.3.6"
|
||||
ksp = "2.3.9"
|
||||
kotlin-poet = "2.3.0"
|
||||
|
||||
microutils = "0.29.2"
|
||||
microutils = "0.30.0"
|
||||
kslog = "1.6.1"
|
||||
|
||||
versions = "0.53.0"
|
||||
versions = "0.54.0"
|
||||
|
||||
github-release-plugin = "2.5.2"
|
||||
dokka = "2.0.0"
|
||||
dokka = "2.2.0"
|
||||
|
||||
validator = "0.18.1"
|
||||
nmcp = "1.4.4"
|
||||
nmcp = "1.6.0"
|
||||
|
||||
[libraries]
|
||||
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
|
||||
315
gradlew
vendored
315
gradlew
vendored
@@ -1,78 +1,129 @@
|
||||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn ( ) {
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die ( ) {
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -81,92 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save ( ) {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
78
gradlew.bat
vendored
78
gradlew.bat
vendored
@@ -1,4 +1,22 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -9,25 +27,29 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -35,48 +57,36 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
pluginManagement {
|
||||
resolutionStrategy {
|
||||
eachPlugin {
|
||||
if (requested.id.id == "org.jetbrains.dokka") {
|
||||
useModule("org.jetbrains.dokka:dokka-gradle-plugin:${requested.version}")
|
||||
}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
@@ -19,3 +12,4 @@ include ":tgbotapi.behaviour_builder"
|
||||
include ":tgbotapi.behaviour_builder.fsm"
|
||||
include ":tgbotapi"
|
||||
include ":tgbotapi.webapps"
|
||||
include ":docs"
|
||||
|
||||
@@ -562,6 +562,12 @@ public final class dev/inmo/tgbotapi/extensions/api/chat/get/GetForumTopicIconSt
|
||||
public static final fun getForumTopicIconStickers (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/api/chat/invite_links/AnswerChatJoinRequestQueryKt {
|
||||
public static final fun answerChatJoinRequestQuery (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/ChatJoinRequest;Ldev/inmo/tgbotapi/requests/chat/invite_links/ChatJoinRequestQueryResult;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun answerChatJoinRequestQuery (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/update/ChatJoinRequestUpdate;Ldev/inmo/tgbotapi/requests/chat/invite_links/ChatJoinRequestQueryResult;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun answerChatJoinRequestQuery-Vwi-J50 (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/chat/invite_links/ChatJoinRequestQueryResult;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/api/chat/invite_links/ApproveChatJoinRequestKt {
|
||||
public static final fun approve (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/ChatJoinRequest;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun approveChatJoinRequest (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Ldev/inmo/tgbotapi/types/IdChatIdentifier;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@@ -687,6 +693,12 @@ public final class dev/inmo/tgbotapi/extensions/api/chat/invite_links/RevokeChat
|
||||
public static final fun revokeChatInviteLink (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/PublicChat;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/api/chat/invite_links/SendChatJoinRequestWebAppKt {
|
||||
public static final fun sendChatJoinRequestWebApp (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/ChatJoinRequest;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun sendChatJoinRequestWebApp (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/update/ChatJoinRequestUpdate;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun sendChatJoinRequestWebApp-Vwi-J50 (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/api/chat/members/BanChatMemberKt {
|
||||
public static final fun banChatMember (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Ldev/inmo/tgbotapi/types/IdChatIdentifier;Ldev/inmo/tgbotapi/types/TelegramDate;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun banChatMember (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/IdChatIdentifier;Ldev/inmo/tgbotapi/types/chat/User;Ldev/inmo/tgbotapi/types/TelegramDate;Ljava/lang/Boolean;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@@ -1950,6 +1962,18 @@ public final class dev/inmo/tgbotapi/extensions/api/send/SendMessageKt {
|
||||
public static synthetic fun sendTextMessage-kPvWKIg$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;Ljava/lang/String;Ldev/inmo/tgbotapi/types/message/ParseMode;Ldev/inmo/tgbotapi/types/LinkPreviewOptions;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/api/send/SendRichMessageDraftKt {
|
||||
public static final fun sendRichMessageDraft-tvXF6p8 (Ldev/inmo/tgbotapi/bot/RequestsExecutor;JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static synthetic fun sendRichMessageDraft-tvXF6p8$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;JJLdev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/api/send/SendRichMessageKt {
|
||||
public static final fun sendRichMessage-mNzvAxs (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Ldev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun sendRichMessage-mNzvAxs (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;Ldev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static synthetic fun sendRichMessage-mNzvAxs$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Ldev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
public static synthetic fun sendRichMessage-mNzvAxs$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;Ldev/inmo/tgbotapi/types/rich/InputRichMessage;Ldev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/api/send/SendStaticLocationKt {
|
||||
public static final fun sendLocation-Z2YO6e4 (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;DDLdev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun sendLocation-Z2YO6e4 (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/chat/Chat;DDLdev/inmo/tgbotapi/types/MessageThreadId;Ldev/inmo/tgbotapi/types/DirectMessageThreadId;Ljava/lang/String;ZZZLjava/lang/String;Ldev/inmo/tgbotapi/types/message/SuggestedPostParameters;Ldev/inmo/tgbotapi/types/ReplyParameters;Ldev/inmo/tgbotapi/types/buttons/KeyboardMarkup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.chat.invite_links.AnswerChatJoinRequestQuery
|
||||
import dev.inmo.tgbotapi.requests.chat.invite_links.ChatJoinRequestQueryResult
|
||||
import dev.inmo.tgbotapi.types.ChatJoinRequestQueryId
|
||||
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
|
||||
import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
|
||||
|
||||
public suspend fun TelegramBot.answerChatJoinRequestQuery(
|
||||
chatJoinRequestQueryId: ChatJoinRequestQueryId,
|
||||
result: ChatJoinRequestQueryResult
|
||||
): Unit = execute(AnswerChatJoinRequestQuery(chatJoinRequestQueryId, result))
|
||||
|
||||
public suspend fun TelegramBot.answerChatJoinRequestQuery(
|
||||
chatJoinRequest: ChatJoinRequest,
|
||||
result: ChatJoinRequestQueryResult
|
||||
): Unit = answerChatJoinRequestQuery(
|
||||
requireNotNull(chatJoinRequest.queryId) {
|
||||
"ChatJoinRequest.queryId is null, this request can't be answered with answerChatJoinRequestQuery"
|
||||
},
|
||||
result
|
||||
)
|
||||
|
||||
public suspend fun TelegramBot.answerChatJoinRequestQuery(
|
||||
chatJoinRequestUpdate: ChatJoinRequestUpdate,
|
||||
result: ChatJoinRequestQueryResult
|
||||
): Unit = answerChatJoinRequestQuery(chatJoinRequestUpdate.data, result)
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.chat.invite_links
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.chat.invite_links.SendChatJoinRequestWebApp
|
||||
import dev.inmo.tgbotapi.types.ChatJoinRequestQueryId
|
||||
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
|
||||
import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
|
||||
|
||||
public suspend fun TelegramBot.sendChatJoinRequestWebApp(
|
||||
chatJoinRequestQueryId: ChatJoinRequestQueryId,
|
||||
webAppUrl: String
|
||||
): Unit = execute(SendChatJoinRequestWebApp(chatJoinRequestQueryId, webAppUrl))
|
||||
|
||||
public suspend fun TelegramBot.sendChatJoinRequestWebApp(
|
||||
chatJoinRequest: ChatJoinRequest,
|
||||
webAppUrl: String
|
||||
): Unit = sendChatJoinRequestWebApp(
|
||||
requireNotNull(chatJoinRequest.queryId) {
|
||||
"ChatJoinRequest.queryId is null, this request can't be processed with sendChatJoinRequestWebApp"
|
||||
},
|
||||
webAppUrl
|
||||
)
|
||||
|
||||
public suspend fun TelegramBot.sendChatJoinRequestWebApp(
|
||||
chatJoinRequestUpdate: ChatJoinRequestUpdate,
|
||||
webAppUrl: String
|
||||
): Unit = sendChatJoinRequestWebApp(chatJoinRequestUpdate.data, webAppUrl)
|
||||
@@ -0,0 +1,70 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.send
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.send.SendRichMessage
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.message.SuggestedPostParameters
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.RichMessageContent
|
||||
import dev.inmo.tgbotapi.types.rich.InputRichMessage
|
||||
|
||||
public suspend fun TelegramBot.sendRichMessage(
|
||||
chatId: ChatIdentifier,
|
||||
richMessage: InputRichMessage,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
directMessageThreadId: DirectMessageThreadId? = chatId.directMessageThreadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowPaidBroadcast: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
suggestedPostParameters: SuggestedPostParameters? = null,
|
||||
replyParameters: ReplyParameters? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
): ChatContentMessage<RichMessageContent> = execute(
|
||||
SendRichMessage(
|
||||
chatId = chatId,
|
||||
richMessage = richMessage,
|
||||
threadId = threadId,
|
||||
directMessageThreadId = directMessageThreadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowPaidBroadcast = allowPaidBroadcast,
|
||||
effectId = effectId,
|
||||
suggestedPostParameters = suggestedPostParameters,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
)
|
||||
|
||||
public suspend fun TelegramBot.sendRichMessage(
|
||||
chat: Chat,
|
||||
richMessage: InputRichMessage,
|
||||
threadId: MessageThreadId? = chat.id.threadId,
|
||||
directMessageThreadId: DirectMessageThreadId? = chat.id.directMessageThreadId,
|
||||
businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowPaidBroadcast: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
suggestedPostParameters: SuggestedPostParameters? = null,
|
||||
replyParameters: ReplyParameters? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
): ChatContentMessage<RichMessageContent> = sendRichMessage(
|
||||
chatId = chat.id,
|
||||
richMessage = richMessage,
|
||||
threadId = threadId,
|
||||
directMessageThreadId = directMessageThreadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowPaidBroadcast = allowPaidBroadcast,
|
||||
effectId = effectId,
|
||||
suggestedPostParameters = suggestedPostParameters,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.inmo.tgbotapi.extensions.api.send
|
||||
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
import dev.inmo.tgbotapi.requests.send.SendRichMessageDraft
|
||||
import dev.inmo.tgbotapi.types.ChatId
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.rich.InputRichMessage
|
||||
|
||||
public suspend fun TelegramBot.sendRichMessageDraft(
|
||||
chatId: ChatId,
|
||||
draftId: Long,
|
||||
richMessage: InputRichMessage,
|
||||
threadId: MessageThreadId? = chatId.threadId
|
||||
): Unit = execute(
|
||||
SendRichMessageDraft(
|
||||
chatId = chatId,
|
||||
draftId = draftId,
|
||||
richMessage = richMessage,
|
||||
threadId = threadId
|
||||
)
|
||||
)
|
||||
@@ -394,6 +394,8 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/W
|
||||
public static synthetic fun waitPhoto$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitPoll (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun waitPoll$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitRichMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun waitRichMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitStaticLocation (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun waitStaticLocation$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitSticker (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
@@ -467,6 +469,8 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/W
|
||||
public static synthetic fun waitPhotoMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitPollMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun waitPollMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitRichMessageMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun waitRichMessageMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitStaticLocationMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun waitStaticLocationMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun waitStickerMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||
@@ -1299,6 +1303,8 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handl
|
||||
public static synthetic fun onPhoto$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
public static final fun onPoll (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/Job;
|
||||
public static synthetic fun onPoll$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
public static final fun onRichMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/Job;
|
||||
public static synthetic fun onRichMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
public static final fun onStaticLocation (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/Job;
|
||||
public static synthetic fun onStaticLocation$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
public static final fun onSticker (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter;Lkotlin/jvm/functions/Function4;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MarkerFactory;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/Job;
|
||||
|
||||
@@ -66,6 +66,10 @@ fun BehaviourContext.waitStory(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent(initRequest, errorFactory).mapContent<StoryContent>()
|
||||
fun BehaviourContext.waitRichMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContent(initRequest, errorFactory).mapContent<RichMessageContent>()
|
||||
fun BehaviourContext.waitVenue(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
|
||||
@@ -75,6 +75,10 @@ fun BehaviourContext.waitStoryMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<StoryContent>()
|
||||
fun BehaviourContext.waitRichMessageMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
) = waitContentMessage(initRequest, errorFactory).mapWithContent<RichMessageContent>()
|
||||
fun BehaviourContext.waitVenueMessage(
|
||||
initRequest: Request<*>? = null,
|
||||
errorFactory: NullableRequestBuilder<*> = { null }
|
||||
|
||||
@@ -304,6 +304,33 @@ fun <BC : BehaviourContext> BC.onStory(
|
||||
scenarioReceiver
|
||||
)
|
||||
|
||||
/**
|
||||
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||
* to combinate several filters
|
||||
* @param [markerFactory] **Pass null to handle requests fully parallel**. Will be used to identify different "stream".
|
||||
* [scenarioReceiver] will be called synchronously in one "stream". Output of [markerFactory] will be used as a key for
|
||||
* "stream"
|
||||
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||
* data
|
||||
*/
|
||||
fun <BC : BehaviourContext> BC.onRichMessage(
|
||||
initialFilter: CommonMessageFilter<RichMessageContent>? = CommonMessageFilterExcludeMediaGroups,
|
||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, RichMessageContentMessage, Update>? = MessageFilterByChat,
|
||||
markerFactory: MarkerFactory<in RichMessageContentMessage, Any>? = ByChatMessageMarkerFactory,
|
||||
additionalSubcontextInitialAction: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, Update, RichMessageContentMessage>? = null,
|
||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, RichMessageContentMessage>
|
||||
) = onContentMessageWithType(
|
||||
initialFilter,
|
||||
subcontextUpdatesFilter,
|
||||
markerFactory,
|
||||
additionalSubcontextInitialAction,
|
||||
scenarioReceiver
|
||||
)
|
||||
|
||||
/**
|
||||
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,96 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.invite_links
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.ChatJoinRequestQueryId
|
||||
import dev.inmo.tgbotapi.types.chatJoinRequestQueryIdField
|
||||
import dev.inmo.tgbotapi.types.resultField
|
||||
import dev.inmo.tgbotapi.utils.serializers.UnitFromBooleanSerializer
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
/**
|
||||
* Result of an [AnswerChatJoinRequestQuery]. Serialized as a plain string.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#answerchatjoinrequestquery">answerChatJoinRequestQuery</a>
|
||||
*/
|
||||
@Serializable(ChatJoinRequestQueryResult.Companion::class)
|
||||
sealed interface ChatJoinRequestQueryResult {
|
||||
val name: String
|
||||
|
||||
/**
|
||||
* Allow the user to join the chat.
|
||||
*/
|
||||
@Serializable(ChatJoinRequestQueryResult.Companion::class)
|
||||
data object Approve : ChatJoinRequestQueryResult {
|
||||
override val name: String = "approve"
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow the user to join the chat.
|
||||
*/
|
||||
@Serializable(ChatJoinRequestQueryResult.Companion::class)
|
||||
data object Decline : ChatJoinRequestQueryResult {
|
||||
override val name: String = "decline"
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave the decision to other administrators.
|
||||
*/
|
||||
@Serializable(ChatJoinRequestQueryResult.Companion::class)
|
||||
data object Queue : ChatJoinRequestQueryResult {
|
||||
override val name: String = "queue"
|
||||
}
|
||||
|
||||
/**
|
||||
* Any other result which is currently unknown to this library.
|
||||
*/
|
||||
@Serializable(ChatJoinRequestQueryResult.Companion::class)
|
||||
data class Unknown(override val name: String) : ChatJoinRequestQueryResult
|
||||
|
||||
companion object : KSerializer<ChatJoinRequestQueryResult> {
|
||||
override val descriptor: SerialDescriptor =
|
||||
PrimitiveSerialDescriptor("ChatJoinRequestQueryResult", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: ChatJoinRequestQueryResult) {
|
||||
encoder.encodeString(value.name)
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): ChatJoinRequestQueryResult {
|
||||
return when (val name = decoder.decodeString()) {
|
||||
Approve.name -> Approve
|
||||
Decline.name -> Decline
|
||||
Queue.name -> Queue
|
||||
else -> Unknown(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to process a received chat join request query.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#answerchatjoinrequestquery">answerChatJoinRequestQuery</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class AnswerChatJoinRequestQuery(
|
||||
@SerialName(chatJoinRequestQueryIdField)
|
||||
val chatJoinRequestQueryId: ChatJoinRequestQueryId,
|
||||
@SerialName(resultField)
|
||||
val result: ChatJoinRequestQueryResult
|
||||
) : SimpleRequest<Unit> {
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
|
||||
override val resultDeserializer: DeserializationStrategy<Unit>
|
||||
get() = UnitFromBooleanSerializer
|
||||
|
||||
override fun method(): String = "answerChatJoinRequestQuery"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package dev.inmo.tgbotapi.requests.chat.invite_links
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.ChatJoinRequestQueryId
|
||||
import dev.inmo.tgbotapi.types.chatJoinRequestQueryIdField
|
||||
import dev.inmo.tgbotapi.types.webAppUrlField
|
||||
import dev.inmo.tgbotapi.utils.serializers.UnitFromBooleanSerializer
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
|
||||
/**
|
||||
* Use this method to process a received chat join request query by showing a Mini App to the user before deciding the
|
||||
* outcome. Call [AnswerChatJoinRequestQuery] to resolve the join request query based on the user interaction with the
|
||||
* Mini App.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#sendchatjoinrequestwebapp">sendChatJoinRequestWebApp</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class SendChatJoinRequestWebApp(
|
||||
@SerialName(chatJoinRequestQueryIdField)
|
||||
val chatJoinRequestQueryId: ChatJoinRequestQueryId,
|
||||
@SerialName(webAppUrlField)
|
||||
val webAppUrl: String
|
||||
) : SimpleRequest<Unit> {
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
|
||||
override val resultDeserializer: DeserializationStrategy<Unit>
|
||||
get() = UnitFromBooleanSerializer
|
||||
|
||||
override fun method(): String = "sendChatJoinRequestWebApp"
|
||||
}
|
||||
@@ -3,5 +3,5 @@ package dev.inmo.tgbotapi.requests.edit.abstracts
|
||||
import dev.inmo.tgbotapi.abstracts.TextedOutput
|
||||
|
||||
interface EditTextChatMessage : TextedOutput {
|
||||
override val text: String
|
||||
override val text: String?
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import dev.inmo.tgbotapi.types.message.RawMessageEntity
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.toRawMessageEntities
|
||||
import dev.inmo.tgbotapi.types.rich.InputRichMessage
|
||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@@ -55,6 +56,24 @@ fun EditChatMessageText(
|
||||
replyMarkup
|
||||
)
|
||||
|
||||
fun EditChatMessageRichText(
|
||||
chatId: ChatIdentifier,
|
||||
messageId: MessageId,
|
||||
richMessage: InputRichMessage,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
replyMarkup: InlineKeyboardMarkup? = null
|
||||
) = EditChatMessageText(
|
||||
chatId = chatId,
|
||||
messageId = messageId,
|
||||
text = null,
|
||||
parseMode = null,
|
||||
rawEntities = null,
|
||||
businessConnectionId = businessConnectionId,
|
||||
linkPreviewOptions = null,
|
||||
replyMarkup = replyMarkup,
|
||||
richMessage = richMessage
|
||||
)
|
||||
|
||||
@ConsistentCopyVisibility
|
||||
@Serializable
|
||||
data class EditChatMessageText internal constructor(
|
||||
@@ -63,7 +82,7 @@ data class EditChatMessageText internal constructor(
|
||||
@SerialName(messageIdField)
|
||||
override val messageId: MessageId,
|
||||
@SerialName(textField)
|
||||
override val text: String,
|
||||
override val text: String? = null,
|
||||
@SerialName(parseModeField)
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(entitiesField)
|
||||
@@ -73,10 +92,12 @@ data class EditChatMessageText internal constructor(
|
||||
@SerialName(linkPreviewOptionsField)
|
||||
override val linkPreviewOptions: LinkPreviewOptions? = null,
|
||||
@SerialName(replyMarkupField)
|
||||
override val replyMarkup: InlineKeyboardMarkup? = null
|
||||
override val replyMarkup: InlineKeyboardMarkup? = null,
|
||||
@SerialName(richMessageField)
|
||||
val richMessage: InputRichMessage? = null
|
||||
) : EditChatMessage<TextContent>, EditTextChatMessage, EditReplyMessage, EditLinkPreviewOptionsContainer {
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text)
|
||||
text ?.let { rawEntities ?.asTextSources(it) }
|
||||
}
|
||||
|
||||
override fun method(): String = editMessageTextMethod
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package dev.inmo.tgbotapi.requests.send
|
||||
|
||||
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
|
||||
import dev.inmo.tgbotapi.requests.send.abstracts.SendContentMessageRequest
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.message.*
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||
import dev.inmo.tgbotapi.types.message.content.RichMessageContent
|
||||
import dev.inmo.tgbotapi.types.rich.InputRichMessage
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
|
||||
internal val RichMessageContentMessageResultDeserializer: DeserializationStrategy<ChatContentMessage<RichMessageContent>>
|
||||
= TelegramBotAPIMessageDeserializationStrategyClass()
|
||||
|
||||
/**
|
||||
* Use this method to send rich messages.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#sendrichmessage">sendRichMessage</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class SendRichMessage(
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
@SerialName(richMessageField)
|
||||
val richMessage: InputRichMessage,
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@SerialName(messageThreadIdField)
|
||||
@EncodeDefault
|
||||
override val threadId: MessageThreadId? = chatId.threadId,
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@EncodeDefault
|
||||
@SerialName(directMessagesTopicIdField)
|
||||
override val directMessageThreadId: DirectMessageThreadId? = chatId.directMessageThreadId,
|
||||
@SerialName(businessConnectionIdField)
|
||||
override val businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
@SerialName(disableNotificationField)
|
||||
override val disableNotification: Boolean = false,
|
||||
@SerialName(protectContentField)
|
||||
override val protectContent: Boolean = false,
|
||||
@SerialName(allowPaidBroadcastField)
|
||||
override val allowPaidBroadcast: Boolean = false,
|
||||
@SerialName(messageEffectIdField)
|
||||
override val effectId: EffectId? = null,
|
||||
@SerialName(suggestedPostParametersField)
|
||||
override val suggestedPostParameters: SuggestedPostParameters? = null,
|
||||
@SerialName(replyParametersField)
|
||||
override val replyParameters: ReplyParameters? = null,
|
||||
@SerialName(replyMarkupField)
|
||||
override val replyMarkup: KeyboardMarkup? = null
|
||||
) : SendContentMessageRequest<ChatContentMessage<RichMessageContent>>,
|
||||
ReplyingMarkupSendMessageRequest<ChatContentMessage<RichMessageContent>> {
|
||||
override fun method(): String = "sendRichMessage"
|
||||
override val resultDeserializer: DeserializationStrategy<ChatContentMessage<RichMessageContent>>
|
||||
get() = RichMessageContentMessageResultDeserializer
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package dev.inmo.tgbotapi.requests.send
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
|
||||
import dev.inmo.tgbotapi.types.ChatId
|
||||
import dev.inmo.tgbotapi.types.MessageThreadId
|
||||
import dev.inmo.tgbotapi.types.chatIdField
|
||||
import dev.inmo.tgbotapi.types.draftIdField
|
||||
import dev.inmo.tgbotapi.types.messageThreadIdField
|
||||
import dev.inmo.tgbotapi.types.richMessageField
|
||||
import dev.inmo.tgbotapi.types.rich.InputRichMessage
|
||||
import dev.inmo.tgbotapi.utils.serializers.UnitFromBooleanSerializer
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
|
||||
/**
|
||||
* Use this method to stream a partial rich message to a user while the message is being generated. The streamed draft is
|
||||
* ephemeral and acts as a temporary 30-second preview - once the output is finalized, [SendRichMessage] must be called
|
||||
* with the complete message to persist it in the user's chat.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#sendrichmessagedraft">sendRichMessageDraft</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class SendRichMessageDraft(
|
||||
@SerialName(chatIdField)
|
||||
val chatId: ChatId,
|
||||
/**
|
||||
* Unique identifier of the message draft; must be non-zero. Changes to drafts with the same identifier are animated.
|
||||
*/
|
||||
@SerialName(draftIdField)
|
||||
val draftId: Long,
|
||||
@SerialName(richMessageField)
|
||||
val richMessage: InputRichMessage,
|
||||
@SerialName(messageThreadIdField)
|
||||
val threadId: MessageThreadId? = chatId.threadId
|
||||
) : SimpleRequest<Unit> {
|
||||
init {
|
||||
require(draftId != 0L) {
|
||||
"draftId of SendRichMessageDraft must be non-zero"
|
||||
}
|
||||
}
|
||||
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
|
||||
override val resultDeserializer: DeserializationStrategy<Unit>
|
||||
get() = UnitFromBooleanSerializer
|
||||
|
||||
override fun method(): String = "sendRichMessageDraft"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
/**
|
||||
* Identifier of a join request query.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#chatjoinrequest">ChatJoinRequest.query_id</a>
|
||||
*/
|
||||
@Serializable
|
||||
@JvmInline
|
||||
value class ChatJoinRequestQueryId(
|
||||
val string: String
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return string
|
||||
}
|
||||
}
|
||||
@@ -463,6 +463,7 @@ const val inputMessageContentField = "input_message_content"
|
||||
const val hideUrlField = "hide_url"
|
||||
|
||||
const val botCommandField = "command"
|
||||
const val botCommandFullField = "bot_command"
|
||||
const val botCommandsField = "commands"
|
||||
const val scopeField = "scope"
|
||||
|
||||
@@ -556,6 +557,7 @@ const val stickerField = "sticker"
|
||||
const val oldStickerField = "old_sticker"
|
||||
const val keywordsField = "keywords"
|
||||
const val urlField = "url"
|
||||
const val linkField = "link"
|
||||
const val addressField = "address"
|
||||
const val actionField = "action"
|
||||
const val positionField = "position"
|
||||
@@ -567,6 +569,45 @@ const val payloadField = "payload"
|
||||
const val vcardField = "vcard"
|
||||
const val resultsField = "results"
|
||||
const val resultField = "result"
|
||||
const val guardBotField = "guard_bot"
|
||||
const val supportsJoinRequestQueriesField = "supports_join_request_queries"
|
||||
const val queryIdField = "query_id"
|
||||
const val chatJoinRequestQueryIdField = "chat_join_request_query_id"
|
||||
const val webAppUrlField = "web_app_url"
|
||||
const val richMessageField = "rich_message"
|
||||
const val isRtlField = "is_rtl"
|
||||
const val skipEntityDetectionField = "skip_entity_detection"
|
||||
const val markdownField = "markdown"
|
||||
const val htmlField = "html"
|
||||
const val unixTimeField = "unix_time"
|
||||
const val dateTimeFormatField = "date_time_format"
|
||||
const val alternativeTextField = "alternative_text"
|
||||
const val expressionField = "expression"
|
||||
const val emailAddressField = "email_address"
|
||||
const val hashtagField = "hashtag"
|
||||
const val cashtagField = "cashtag"
|
||||
const val bankCardNumberField = "bank_card_number"
|
||||
const val anchorNameField = "anchor_name"
|
||||
const val referenceNameField = "reference_name"
|
||||
const val blocksField = "blocks"
|
||||
const val itemsField = "items"
|
||||
const val summaryField = "summary"
|
||||
const val sizeField = "size"
|
||||
const val languageField = "language"
|
||||
const val creditField = "credit"
|
||||
const val cellsField = "cells"
|
||||
const val isHeaderField = "is_header"
|
||||
const val colspanField = "colspan"
|
||||
const val rowspanField = "rowspan"
|
||||
const val alignField = "align"
|
||||
const val valignField = "valign"
|
||||
const val zoomField = "zoom"
|
||||
const val voiceNoteField = "voice_note"
|
||||
const val hasCheckboxField = "has_checkbox"
|
||||
const val isCheckedField = "is_checked"
|
||||
const val isOpenField = "is_open"
|
||||
const val isBorderedField = "is_bordered"
|
||||
const val isStripedField = "is_striped"
|
||||
const val certificateField = "certificate"
|
||||
const val questionField = "question"
|
||||
const val questionEntitiesField = "question_entities"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent
|
||||
|
||||
import dev.inmo.tgbotapi.types.richMessageField
|
||||
import dev.inmo.tgbotapi.types.rich.InputRichMessage
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents the content of a rich message to be sent as the result of an inline query.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#inputrichmessagecontent">InputRichMessageContent</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class InputRichMessageContent(
|
||||
@SerialName(richMessageField)
|
||||
val richMessage: InputRichMessage
|
||||
) : InputMessageContent
|
||||
@@ -22,6 +22,7 @@ object InputMessageContentSerializer : KSerializer<InputMessageContent> {
|
||||
is InputTextMessageContent -> InputTextMessageContent.serializer().serialize(encoder, value)
|
||||
is InputVenueMessageContent -> InputVenueMessageContent.serializer().serialize(encoder, value)
|
||||
is InputInvoiceMessageContent -> InputInvoiceMessageContent.serializer().serialize(encoder, value)
|
||||
is InputRichMessageContent -> InputRichMessageContent.serializer().serialize(encoder, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.inmo.tgbotapi.types
|
||||
|
||||
import dev.inmo.tgbotapi.types.media.PollMedia
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents an HTTP link.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#link">Link</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class Link(
|
||||
@SerialName(urlField)
|
||||
val url: String
|
||||
) : PollMedia
|
||||
@@ -24,7 +24,9 @@ data class ChatJoinRequest(
|
||||
@SerialName(inviteLinkField)
|
||||
val inviteLink: ChatInviteLink? = null,
|
||||
@SerialName(bioField)
|
||||
val bio: String? = null
|
||||
val bio: String? = null,
|
||||
@SerialName(queryIdField)
|
||||
val queryId: ChatJoinRequestQueryId? = null
|
||||
) : FromUser {
|
||||
@Suppress("unused")
|
||||
val dateTime: DateTime
|
||||
|
||||
@@ -69,7 +69,9 @@ data class ExtendedChannelChatImpl(
|
||||
@SerialName(maxReactionCountField)
|
||||
override val maxReactionsCount: Int = 3,
|
||||
@SerialName(uniqueGiftColorsField)
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null,
|
||||
@SerialName(guardBotField)
|
||||
override val guardBot: User? = null
|
||||
) : ExtendedChannelChat
|
||||
|
||||
@Serializable
|
||||
@@ -116,7 +118,9 @@ data class ExtendedGroupChatImpl(
|
||||
@SerialName(paidMessageStarCountField)
|
||||
override val paidMessageStarCount: Int? = null,
|
||||
@SerialName(uniqueGiftColorsField)
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null,
|
||||
@SerialName(guardBotField)
|
||||
override val guardBot: User? = null
|
||||
) : ExtendedGroupChat
|
||||
|
||||
@Serializable
|
||||
@@ -316,7 +320,9 @@ data class ExtendedSupergroupChatImpl(
|
||||
@SerialName(paidMessageStarCountField)
|
||||
override val paidMessageStarCount: Int? = null,
|
||||
@SerialName(uniqueGiftColorsField)
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null,
|
||||
@SerialName(guardBotField)
|
||||
override val guardBot: User? = null
|
||||
) : ExtendedSupergroupChat
|
||||
|
||||
@Serializable
|
||||
@@ -390,7 +396,9 @@ data class ExtendedForumChatImpl(
|
||||
@SerialName(paidMessageStarCountField)
|
||||
override val paidMessageStarCount: Int? = null,
|
||||
@SerialName(uniqueGiftColorsField)
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null,
|
||||
@SerialName(guardBotField)
|
||||
override val guardBot: User? = null
|
||||
) : ExtendedForumChat
|
||||
|
||||
@Serializable
|
||||
@@ -467,7 +475,9 @@ data class ExtendedChannelDirectMessagesChatImpl(
|
||||
@SerialName(paidMessageStarCountField)
|
||||
override val paidMessageStarCount: Int? = null,
|
||||
@SerialName(uniqueGiftColorsField)
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null
|
||||
override val uniqueGiftColors: UniqueGiftColors? = null,
|
||||
@SerialName(guardBotField)
|
||||
override val guardBot: User? = null
|
||||
) : ExtendedChannelDirectMessagesChat {
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@SerialName(isDirectMessagesField)
|
||||
@@ -495,6 +505,8 @@ data class ExtendedBot(
|
||||
val supportsInlineQueries: Boolean = false,
|
||||
@SerialName(supportsGuestQueriesField)
|
||||
val supportsGuestQueries: Boolean = false,
|
||||
@SerialName(supportsJoinRequestQueriesField)
|
||||
val supportsJoinRequestQueries: Boolean = false,
|
||||
@SerialName(canConnectToBusinessField)
|
||||
val canConnectToBusiness: Boolean = false,
|
||||
@SerialName(photoField)
|
||||
|
||||
@@ -27,6 +27,14 @@ sealed interface ExtendedChat : Chat {
|
||||
|
||||
val uniqueGiftColors: UniqueGiftColors?
|
||||
|
||||
/**
|
||||
* The bot that processes join request queries in the chat. The field is only available to chat administrators.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#chatfullinfo">ChatFullInfo.guard_bot</a>
|
||||
*/
|
||||
val guardBot: User?
|
||||
get() = null
|
||||
|
||||
@Deprecated(
|
||||
message = "Telegram Bot API v9.0 introduced the new field, `acceptedGiftTypes`, to allow granular" +
|
||||
" control over which types of gifts user, bot, or chat can accept.",
|
||||
|
||||
@@ -27,6 +27,7 @@ object InputPollOptionMediaSerializer : KSerializer<InputPollOptionMedia> {
|
||||
override fun serialize(encoder: Encoder, value: InputPollOptionMedia) {
|
||||
when (value) {
|
||||
is TelegramMediaAnimation -> TelegramMediaAnimation.serializer().serialize(encoder, value)
|
||||
is TelegramMediaLink -> TelegramMediaLink.serializer().serialize(encoder, value)
|
||||
is TelegramMediaLivePhoto -> TelegramMediaLivePhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaLocation -> TelegramMediaLocation.serializer().serialize(encoder, value)
|
||||
is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value)
|
||||
|
||||
@@ -10,6 +10,8 @@ import dev.inmo.tgbotapi.types.files.LivePhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.PhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.Sticker
|
||||
import dev.inmo.tgbotapi.types.files.VideoFile
|
||||
import dev.inmo.tgbotapi.types.Link
|
||||
import dev.inmo.tgbotapi.types.linkField
|
||||
import dev.inmo.tgbotapi.types.livePhotoField
|
||||
import dev.inmo.tgbotapi.types.location.StaticLocation
|
||||
import dev.inmo.tgbotapi.types.locationField
|
||||
@@ -36,6 +38,8 @@ interface PollMedia : BaseTelegramMediaFile {
|
||||
val audio: AudioFile? = null,
|
||||
@SerialName(documentField)
|
||||
val document: DocumentFile? = null,
|
||||
@SerialName(linkField)
|
||||
val link: Link? = null,
|
||||
@SerialName(livePhotoField)
|
||||
val livePhoto: LivePhotoFile? = null,
|
||||
@SerialName(photoField)
|
||||
@@ -61,6 +65,7 @@ interface PollMedia : BaseTelegramMediaFile {
|
||||
surrogate.animation != null -> surrogate.animation
|
||||
surrogate.audio != null -> surrogate.audio
|
||||
surrogate.document != null -> surrogate.document
|
||||
surrogate.link != null -> surrogate.link
|
||||
surrogate.livePhoto != null -> surrogate.livePhoto
|
||||
surrogate.photo != null -> surrogate.photo
|
||||
surrogate.sticker != null -> surrogate.sticker
|
||||
@@ -76,6 +81,7 @@ interface PollMedia : BaseTelegramMediaFile {
|
||||
animation = value as? AnimationFile,
|
||||
audio = value as? AudioFile,
|
||||
document = value as? DocumentFile,
|
||||
link = value as? Link,
|
||||
livePhoto = value as? LivePhotoFile,
|
||||
photo = value as? PhotoFile,
|
||||
sticker = value as? Sticker,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.inmo.tgbotapi.types.media
|
||||
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.types.urlField
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents an HTTP link to be sent. Can be used as [InputPollOptionMedia].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#inputmedialink">InputMediaLink</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class TelegramMediaLink(
|
||||
@SerialName(urlField)
|
||||
val url: String,
|
||||
) : InputPollOptionMedia {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
companion object {
|
||||
const val TYPE = "link"
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ import dev.inmo.tgbotapi.types.polls.Poll
|
||||
import dev.inmo.tgbotapi.types.polls.PollOptionPersistentId
|
||||
import dev.inmo.tgbotapi.types.request.ChatShared
|
||||
import dev.inmo.tgbotapi.types.request.UsersShared
|
||||
import dev.inmo.tgbotapi.types.rich.RichTextInfo
|
||||
import dev.inmo.tgbotapi.types.stories.Story
|
||||
import dev.inmo.tgbotapi.types.venue.Venue
|
||||
import dev.inmo.tgbotapi.utils.isFakeTelegramUser
|
||||
@@ -92,6 +93,7 @@ internal data class RawMessage(
|
||||
private val caption_entities: RawMessageEntities? = null,
|
||||
private val has_media_spoiler: Boolean? = null,
|
||||
private val story: Story? = null,
|
||||
private val rich_message: RichTextInfo? = null,
|
||||
private val audio: AudioFile? = null,
|
||||
private val document: DocumentFile? = null,
|
||||
private val paid_media: PaidMediaInfo? = null,
|
||||
@@ -230,6 +232,11 @@ internal data class RawMessage(
|
||||
} ?: emptyList()
|
||||
|
||||
when {
|
||||
rich_message != null -> RichMessageContent(
|
||||
chat,
|
||||
messageId,
|
||||
rich_message
|
||||
)
|
||||
story != null -> StoryContent(
|
||||
chat,
|
||||
messageId,
|
||||
|
||||
@@ -55,6 +55,7 @@ sealed interface MessageContent: ResendableContent {
|
||||
subclass(StoryContent::class)
|
||||
subclass(GiveawayPublicResultsContent::class)
|
||||
subclass(GiveawayContent::class)
|
||||
subclass(RichMessageContent::class)
|
||||
|
||||
additionalBuilder()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package dev.inmo.tgbotapi.types.message.content
|
||||
|
||||
import dev.inmo.tgbotapi.requests.ForwardMessage
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.requests.send.CopyMessage
|
||||
import dev.inmo.tgbotapi.requests.send.SendRichMessage
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.chat.Chat
|
||||
import dev.inmo.tgbotapi.types.message.SuggestedPostParameters
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatContentMessage
|
||||
import dev.inmo.tgbotapi.types.rich.InputRichMessageMarkdown
|
||||
import dev.inmo.tgbotapi.types.rich.RichBlock
|
||||
import dev.inmo.tgbotapi.types.rich.RichBlockAudio
|
||||
import dev.inmo.tgbotapi.types.rich.RichBlockMedia
|
||||
import dev.inmo.tgbotapi.types.rich.RichBlockPhoto
|
||||
import dev.inmo.tgbotapi.types.rich.RichBlockVideo
|
||||
import dev.inmo.tgbotapi.types.rich.RichTextInfo
|
||||
import dev.inmo.tgbotapi.types.rich.markdown
|
||||
import dev.inmo.tgbotapi.types.rich.search
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class RichMessageContent(
|
||||
private val chat: Chat,
|
||||
private val messageId: MessageId,
|
||||
val richMessage: RichTextInfo
|
||||
) : MessageContent {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
messageThreadId: MessageThreadId?,
|
||||
directMessageThreadId: DirectMessageThreadId?,
|
||||
businessConnectionId: BusinessConnectionId?,
|
||||
disableNotification: Boolean,
|
||||
protectContent: Boolean,
|
||||
allowPaidBroadcast: Boolean,
|
||||
effectId: EffectId?,
|
||||
suggestedPostParameters: SuggestedPostParameters?,
|
||||
replyParameters: ReplyParameters?,
|
||||
replyMarkup: KeyboardMarkup?
|
||||
): Request<ChatContentMessage<RichMessageContent>> {
|
||||
val isThereMedia = richMessage.blocks.any {
|
||||
it.search {
|
||||
this is RichBlockMedia
|
||||
} != null
|
||||
}
|
||||
return if (isThereMedia) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
ForwardMessage(
|
||||
chat.id,
|
||||
toChatId = chatId,
|
||||
messageId = messageId,
|
||||
threadId = messageThreadId,
|
||||
directMessageThreadId = directMessageThreadId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
effectId = effectId,
|
||||
suggestedPostParameters = suggestedPostParameters,
|
||||
) as Request<ChatContentMessage<RichMessageContent>>
|
||||
} else {
|
||||
SendRichMessage(
|
||||
chatId = chatId,
|
||||
richMessage = InputRichMessageMarkdown(richMessage.markdown, isRtl = richMessage.isRtl),
|
||||
threadId = messageThreadId,
|
||||
directMessageThreadId = directMessageThreadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowPaidBroadcast = allowPaidBroadcast,
|
||||
effectId = effectId,
|
||||
suggestedPostParameters = suggestedPostParameters,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ typealias PollMessage = ChatContentMessage<PollContent>
|
||||
typealias TextMessage = ChatContentMessage<TextContent>
|
||||
typealias StoryMessage = ChatContentMessage<StoryContent>
|
||||
|
||||
typealias RichMessageContentMessage = ChatContentMessage<RichMessageContent>
|
||||
|
||||
typealias LocationMessage = ChatContentMessage<LocationContent>
|
||||
typealias LiveLocationMessage = ChatContentMessage<LiveLocationContent>
|
||||
typealias StaticLocationMessage = ChatContentMessage<StaticLocationContent>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.htmlField
|
||||
import dev.inmo.tgbotapi.types.isRtlField
|
||||
import dev.inmo.tgbotapi.types.markdownField
|
||||
import dev.inmo.tgbotapi.types.skipEntityDetectionField
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Describes a rich message to be sent. Exactly one of the fields [html] or [markdown] must be used. Use the
|
||||
* [InputRichMessageHTML] and [InputRichMessageMarkdown] factories to build an instance.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#inputrichmessage">InputRichMessage</a>
|
||||
*/
|
||||
@ConsistentCopyVisibility
|
||||
@Serializable
|
||||
data class InputRichMessage internal constructor(
|
||||
@SerialName(htmlField)
|
||||
val html: String? = null,
|
||||
@SerialName(markdownField)
|
||||
val markdown: String? = null,
|
||||
@SerialName(isRtlField)
|
||||
val isRtl: Boolean? = null,
|
||||
@SerialName(skipEntityDetectionField)
|
||||
val skipEntityDetection: Boolean? = null
|
||||
) {
|
||||
init {
|
||||
require((html == null) != (markdown == null)) {
|
||||
"Exactly one of the fields html or markdown must be used in InputRichMessage"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an [InputRichMessage] with the content described using HTML formatting.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#inputrichmessage">InputRichMessage</a>
|
||||
*/
|
||||
fun InputRichMessageHTML(
|
||||
html: String,
|
||||
isRtl: Boolean? = null,
|
||||
skipEntityDetection: Boolean? = null
|
||||
): InputRichMessage = InputRichMessage(
|
||||
html = html,
|
||||
markdown = null,
|
||||
isRtl = isRtl,
|
||||
skipEntityDetection = skipEntityDetection
|
||||
)
|
||||
|
||||
/**
|
||||
* Creates an [InputRichMessage] with the content described using Markdown formatting.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#inputrichmessage">InputRichMessage</a>
|
||||
*/
|
||||
fun InputRichMessageMarkdown(
|
||||
markdown: String,
|
||||
isRtl: Boolean? = null,
|
||||
skipEntityDetection: Boolean? = null
|
||||
): InputRichMessage = InputRichMessage(
|
||||
html = null,
|
||||
markdown = markdown,
|
||||
isRtl = isRtl,
|
||||
skipEntityDetection = skipEntityDetection
|
||||
)
|
||||
@@ -0,0 +1,95 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonContentPolymorphicSerializer
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
|
||||
/**
|
||||
* Represents a block in a rich formatted message.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblock">RichBlock</a>
|
||||
*/
|
||||
@Serializable(RichBlockSerializer::class)
|
||||
@ClassCastsIncluded
|
||||
sealed interface RichBlock {
|
||||
val type: String
|
||||
|
||||
/**
|
||||
* [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style) source of this single [RichBlock].
|
||||
*/
|
||||
val markdown: String
|
||||
|
||||
/**
|
||||
* [Rich HTML style](https://core.telegram.org/bots/api#rich-html-style) source of this single [RichBlock].
|
||||
*/
|
||||
val html: String
|
||||
}
|
||||
|
||||
@Serializable(RichBlockSerializer::class)
|
||||
sealed interface RichBlockMedia : RichBlock {
|
||||
val media: TelegramMediaFile
|
||||
val caption: RichBlockCaption?
|
||||
}
|
||||
|
||||
/**
|
||||
* The nested [RichBlock]s directly contained by this block, or an empty list for leaf blocks. Container blocks
|
||||
* ([RichBlockList] via its [RichBlockListItem.blocks], [RichBlockBlockQuotation], [RichBlockCollage],
|
||||
* [RichBlockSlideshow] and [RichBlockDetails]) expose their children here.
|
||||
*/
|
||||
val RichBlock.subBlocks: List<RichBlock>
|
||||
get() = when (this) {
|
||||
is RichBlockList -> items.flatMap { it.blocks }
|
||||
is RichBlockBlockQuotation -> blocks
|
||||
is RichBlockCollage -> blocks
|
||||
is RichBlockSlideshow -> blocks
|
||||
is RichBlockDetails -> blocks
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks this [RichBlock] and all of its [subBlocks] recursively (depth-first, this block first) and returns the first
|
||||
* block for which [block] returns `true`, or `null` if none matches.
|
||||
*/
|
||||
fun RichBlock.search(block: RichBlock.() -> Boolean): RichBlock? {
|
||||
if (block()) return this
|
||||
for (child in subBlocks) {
|
||||
child.search(block)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
object RichBlockSerializer : JsonContentPolymorphicSerializer<RichBlock>(RichBlock::class) {
|
||||
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<RichBlock> {
|
||||
return when (val type = element.jsonObject[typeField]?.jsonPrimitive?.content) {
|
||||
RichBlockParagraph.TYPE -> RichBlockParagraph.serializer()
|
||||
RichBlockSectionHeading.TYPE -> RichBlockSectionHeading.serializer()
|
||||
RichBlockPreformatted.TYPE -> RichBlockPreformatted.serializer()
|
||||
RichBlockFooter.TYPE -> RichBlockFooter.serializer()
|
||||
RichBlockDivider.TYPE -> RichBlockDivider.serializer()
|
||||
RichBlockMathematicalExpression.TYPE -> RichBlockMathematicalExpression.serializer()
|
||||
RichBlockAnchor.TYPE -> RichBlockAnchor.serializer()
|
||||
RichBlockList.TYPE -> RichBlockList.serializer()
|
||||
RichBlockBlockQuotation.TYPE -> RichBlockBlockQuotation.serializer()
|
||||
RichBlockPullQuotation.TYPE -> RichBlockPullQuotation.serializer()
|
||||
RichBlockCollage.TYPE -> RichBlockCollage.serializer()
|
||||
RichBlockSlideshow.TYPE -> RichBlockSlideshow.serializer()
|
||||
RichBlockTable.TYPE -> RichBlockTable.serializer()
|
||||
RichBlockDetails.TYPE -> RichBlockDetails.serializer()
|
||||
RichBlockMap.TYPE -> RichBlockMap.serializer()
|
||||
RichBlockAnimation.TYPE -> RichBlockAnimation.serializer()
|
||||
RichBlockAudio.TYPE -> RichBlockAudio.serializer()
|
||||
RichBlockPhoto.TYPE -> RichBlockPhoto.serializer()
|
||||
RichBlockVideo.TYPE -> RichBlockVideo.serializer()
|
||||
RichBlockVoiceNote.TYPE -> RichBlockVoiceNote.serializer()
|
||||
RichBlockThinking.TYPE -> RichBlockThinking.serializer()
|
||||
else -> error("Unknown RichBlock type: $type")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
/**
|
||||
* Builds the [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style) source string for this list
|
||||
* of [RichBlock]s. The resulting string may be passed to [InputRichMessageMarkdown].
|
||||
*
|
||||
* Media blocks ([RichBlockPhoto], [RichBlockVideo], [RichBlockAudio], [RichBlockVoiceNote] and [RichBlockAnimation]) are
|
||||
* rendered using the Telegram file_id as the media source. Telegram only accepts HTTP(S) URLs for rich media, so for
|
||||
* those blocks the output is a faithful structural representation rather than a directly sendable message.
|
||||
*/
|
||||
fun List<RichBlock>.toRichMarkdown(): String = joinToString(separator = "\n\n") { it.markdown }
|
||||
|
||||
/**
|
||||
* Builds the [Rich HTML style](https://core.telegram.org/bots/api#rich-html-style) source string for this list of
|
||||
* [RichBlock]s. The resulting string may be passed to [InputRichMessageHTML]. See [toRichMarkdown] for the media note.
|
||||
*/
|
||||
fun List<RichBlock>.toRichHtml(): String = joinToString(separator = "\n") { it.html }
|
||||
|
||||
/**
|
||||
* [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style) source of all the [RichTextInfo.blocks].
|
||||
*/
|
||||
val RichTextInfo.markdown: String
|
||||
get() = blocks.toRichMarkdown()
|
||||
|
||||
/**
|
||||
* [Rich HTML style](https://core.telegram.org/bots/api#rich-html-style) source of all the [RichTextInfo.blocks].
|
||||
*/
|
||||
val RichTextInfo.html: String
|
||||
get() = blocks.toRichHtml()
|
||||
|
||||
internal fun creditCiteMarkdown(credit: RichText?): String = credit?.let { "<cite>${it.markdown}</cite>" } ?: ""
|
||||
|
||||
internal fun creditCiteHtml(credit: RichText?): String = credit?.let { "<cite>${it.html}</cite>" } ?: ""
|
||||
|
||||
internal fun richMediaContainerMarkdown(tag: String, blocks: List<RichBlock>, caption: RichBlockCaption?): String {
|
||||
val media = blocks.joinToString(separator = "\n") { it.markdown }
|
||||
val captionPart = caption?.let { "\n<figcaption>${it.text.markdown}${creditCiteMarkdown(it.credit)}</figcaption>" } ?: ""
|
||||
return "<$tag>\n\n$media$captionPart\n\n</$tag>"
|
||||
}
|
||||
|
||||
internal fun richMediaContainerHtml(tag: String, blocks: List<RichBlock>, caption: RichBlockCaption?): String {
|
||||
val media = blocks.joinToString(separator = "") { it.html }
|
||||
val captionPart = caption?.let { "<figcaption>${it.text.html}${creditCiteHtml(it.credit)}</figcaption>" } ?: ""
|
||||
return "<$tag>$media$captionPart</$tag>"
|
||||
}
|
||||
|
||||
internal fun richMediaMarkdown(source: String, caption: RichBlockCaption?): String =
|
||||
caption?.let { "" } ?: ""
|
||||
|
||||
internal fun richMediaHtml(tag: String, source: String, spoiler: Boolean, selfClosing: Boolean, caption: RichBlockCaption?): String {
|
||||
val spoilerAttribute = if (spoiler) " tg-spoiler" else ""
|
||||
val element = if (selfClosing) "<$tag src=\"$source\"$spoilerAttribute/>" else "<$tag src=\"$source\"$spoilerAttribute></$tag>"
|
||||
return caption?.let { "<figure>$element<figcaption>${it.text.html}${creditCiteHtml(it.credit)}</figcaption></figure>" } ?: element
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.alignField
|
||||
import dev.inmo.tgbotapi.types.blocksField
|
||||
import dev.inmo.tgbotapi.types.colspanField
|
||||
import dev.inmo.tgbotapi.types.creditField
|
||||
import dev.inmo.tgbotapi.types.hasCheckboxField
|
||||
import dev.inmo.tgbotapi.types.isCheckedField
|
||||
import dev.inmo.tgbotapi.types.isHeaderField
|
||||
import dev.inmo.tgbotapi.types.labelField
|
||||
import dev.inmo.tgbotapi.types.rowspanField
|
||||
import dev.inmo.tgbotapi.types.textField
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.types.valignField
|
||||
import dev.inmo.tgbotapi.types.valueField
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Caption of a rich formatted block.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockcaption">RichBlockCaption</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockCaption(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(creditField)
|
||||
val credit: RichText? = null
|
||||
)
|
||||
|
||||
/**
|
||||
* A cell in a [RichBlockTable].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblocktablecell">RichBlockTableCell</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockTableCell(
|
||||
@SerialName(textField)
|
||||
val text: RichText? = null,
|
||||
@SerialName(isHeaderField)
|
||||
val isHeader: Boolean? = null,
|
||||
@SerialName(colspanField)
|
||||
val colspan: Int? = null,
|
||||
@SerialName(rowspanField)
|
||||
val rowspan: Int? = null,
|
||||
@SerialName(alignField)
|
||||
val align: String,
|
||||
@SerialName(valignField)
|
||||
val valign: String
|
||||
)
|
||||
|
||||
/**
|
||||
* An item of a [RichBlockList].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblocklistitem">RichBlockListItem</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockListItem(
|
||||
@SerialName(labelField)
|
||||
val label: String,
|
||||
@SerialName(blocksField)
|
||||
val blocks: List<RichBlock>,
|
||||
@SerialName(hasCheckboxField)
|
||||
val hasCheckbox: Boolean? = null,
|
||||
@SerialName(isCheckedField)
|
||||
val isChecked: Boolean? = null,
|
||||
@SerialName(valueField)
|
||||
val value: Int? = null,
|
||||
/**
|
||||
* For ordered lists, the type of the item label; must be one of "a", "A", "i", "I" or "1".
|
||||
*/
|
||||
@SerialName(typeField)
|
||||
val labelType: String? = null
|
||||
)
|
||||
@@ -0,0 +1,708 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.animationField
|
||||
import dev.inmo.tgbotapi.types.audioField
|
||||
import dev.inmo.tgbotapi.types.blocksField
|
||||
import dev.inmo.tgbotapi.types.captionField
|
||||
import dev.inmo.tgbotapi.types.cellsField
|
||||
import dev.inmo.tgbotapi.types.creditField
|
||||
import dev.inmo.tgbotapi.types.expressionField
|
||||
import dev.inmo.tgbotapi.types.files.AnimationFile
|
||||
import dev.inmo.tgbotapi.types.files.AudioFile
|
||||
import dev.inmo.tgbotapi.types.files.PhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||
import dev.inmo.tgbotapi.types.files.VideoFile
|
||||
import dev.inmo.tgbotapi.types.files.VoiceFile
|
||||
import dev.inmo.tgbotapi.types.hasSpoilerField
|
||||
import dev.inmo.tgbotapi.types.heightField
|
||||
import dev.inmo.tgbotapi.types.isBorderedField
|
||||
import dev.inmo.tgbotapi.types.isOpenField
|
||||
import dev.inmo.tgbotapi.types.isStripedField
|
||||
import dev.inmo.tgbotapi.types.itemsField
|
||||
import dev.inmo.tgbotapi.types.languageField
|
||||
import dev.inmo.tgbotapi.types.location.StaticLocation
|
||||
import dev.inmo.tgbotapi.types.locationField
|
||||
import dev.inmo.tgbotapi.types.nameField
|
||||
import dev.inmo.tgbotapi.types.photoField
|
||||
import dev.inmo.tgbotapi.types.sizeField
|
||||
import dev.inmo.tgbotapi.types.summaryField
|
||||
import dev.inmo.tgbotapi.types.textField
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.types.videoField
|
||||
import dev.inmo.tgbotapi.types.voiceNoteField
|
||||
import dev.inmo.tgbotapi.types.widthField
|
||||
import dev.inmo.tgbotapi.types.zoomField
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A text paragraph.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockparagraph">RichBlockParagraph</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockParagraph(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "paragraph"
|
||||
fun markdown(text: RichText): String = text.markdown
|
||||
fun html(text: RichText): String = "<p>${text.html}</p>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A section heading.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblocksectionheading">RichBlockSectionHeading</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockSectionHeading(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
/**
|
||||
* Relative size of the text font; 1-6, 1 is the largest, 6 is the smallest.
|
||||
*/
|
||||
@SerialName(sizeField)
|
||||
val level: Int
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(text, level)
|
||||
override val html: String = html(text, level)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "heading"
|
||||
fun markdown(text: RichText, size: Int): String = "#".repeat(size) + " " + text.markdown
|
||||
fun html(text: RichText, size: Int): String = "<h$size>${text.html}</h$size>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A preformatted text block.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockpreformatted">RichBlockPreformatted</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockPreformatted(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(languageField)
|
||||
val language: String? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(text, language)
|
||||
override val html: String = html(text, language)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "pre"
|
||||
fun markdown(text: RichText, language: String?): String = "```" + (language ?: "") + "\n" + text.rawText + "\n```"
|
||||
fun html(text: RichText, language: String?): String =
|
||||
language?.let { "<pre><code class=\"language-$it\">${text.html}</code></pre>" } ?: "<pre>${text.html}</pre>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A footer.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockfooter">RichBlockFooter</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockFooter(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "footer"
|
||||
fun markdown(text: RichText): String = "<footer>${text.markdown}</footer>"
|
||||
fun html(text: RichText): String = "<footer>${text.html}</footer>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A divider.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockdivider">RichBlockDivider</a>
|
||||
*/
|
||||
@Serializable
|
||||
class RichBlockDivider : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown()
|
||||
override val html: String = html()
|
||||
|
||||
override fun equals(other: Any?): Boolean = other is RichBlockDivider
|
||||
|
||||
override fun hashCode(): Int = TYPE.hashCode()
|
||||
|
||||
override fun toString(): String = "RichBlockDivider"
|
||||
|
||||
companion object {
|
||||
const val TYPE = "divider"
|
||||
fun markdown(): String = "---"
|
||||
fun html(): String = "<hr/>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with a mathematical expression in LaTeX format.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockmathematicalexpression">RichBlockMathematicalExpression</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockMathematicalExpression(
|
||||
@SerialName(expressionField)
|
||||
val expression: String
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(expression)
|
||||
override val html: String = html(expression)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "mathematical_expression"
|
||||
fun markdown(expression: String): String = "\$\$" + expression + "\$\$"
|
||||
fun html(expression: String): String = "<tg-math-block>$expression</tg-math-block>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with an anchor.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockanchor">RichBlockAnchor</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockAnchor(
|
||||
@SerialName(nameField)
|
||||
val name: String
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(name)
|
||||
override val html: String = html(name)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "anchor"
|
||||
fun markdown(name: String): String = "<a name=\"$name\"></a>"
|
||||
fun html(name: String): String = "<a name=\"$name\"></a>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of blocks.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblocklist">RichBlockList</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockList(
|
||||
@SerialName(itemsField)
|
||||
val items: List<RichBlockListItem>
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(items)
|
||||
override val html: String = html(items)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "list"
|
||||
fun markdown(items: List<RichBlockListItem>): String =
|
||||
items.mapIndexed { index, item ->
|
||||
val marker = when {
|
||||
item.hasCheckbox == true -> if (item.isChecked == true) "- [x] " else "- [ ] "
|
||||
item.labelType != null -> "${item.value ?: (index + 1)}. "
|
||||
else -> "- "
|
||||
}
|
||||
item.blocks.toRichMarkdown().lineSequence().mapIndexed { lineIndex, line ->
|
||||
if (lineIndex == 0) "$marker$line" else " $line"
|
||||
}.joinToString(separator = "\n")
|
||||
}.joinToString(separator = "\n")
|
||||
|
||||
fun html(items: List<RichBlockListItem>): String {
|
||||
val ordered = items.any { it.labelType != null }
|
||||
val tag = if (ordered) "ol" else "ul"
|
||||
val renderedItems = items.joinToString(separator = "") { item ->
|
||||
val attributes = buildString {
|
||||
item.value?.let { append(" value=\"$it\"") }
|
||||
item.labelType?.let { append(" type=\"$it\"") }
|
||||
}
|
||||
val checkbox = if (item.hasCheckbox == true) {
|
||||
"<input type=\"checkbox\"${if (item.isChecked == true) " checked" else ""}>"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
"<li$attributes>$checkbox${item.blocks.toRichHtml()}</li>"
|
||||
}
|
||||
return "<$tag>$renderedItems</$tag>"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block quotation.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockblockquotation">RichBlockBlockQuotation</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockBlockQuotation(
|
||||
@SerialName(blocksField)
|
||||
val blocks: List<RichBlock>,
|
||||
@SerialName(creditField)
|
||||
val credit: RichText? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(blocks, credit)
|
||||
override val html: String = html(blocks, credit)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "blockquote"
|
||||
fun markdown(blocks: List<RichBlock>, credit: RichText?): String {
|
||||
val quoted = blocks.toRichMarkdown().lineSequence().joinToString(separator = "\n") { line ->
|
||||
if (line.isEmpty()) ">" else "> $line"
|
||||
}
|
||||
return quoted + (credit?.let { "\n> ${creditCiteMarkdown(it)}" } ?: "")
|
||||
}
|
||||
|
||||
fun html(blocks: List<RichBlock>, credit: RichText?): String =
|
||||
"<blockquote>${blocks.toRichHtml()}${creditCiteHtml(credit)}</blockquote>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A quotation with centered text.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockpullquotation">RichBlockPullQuotation</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockPullQuotation(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(creditField)
|
||||
val credit: RichText? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(text, credit)
|
||||
override val html: String = html(text, credit)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "pullquote"
|
||||
fun markdown(text: RichText, credit: RichText?): String = "<aside>${text.markdown}${creditCiteMarkdown(credit)}</aside>"
|
||||
fun html(text: RichText, credit: RichText?): String = "<aside>${text.html}${creditCiteHtml(credit)}</aside>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A collage.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockcollage">RichBlockCollage</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockCollage(
|
||||
@SerialName(blocksField)
|
||||
val blocks: List<RichBlock>,
|
||||
@SerialName(captionField)
|
||||
val caption: RichBlockCaption? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(blocks, caption)
|
||||
override val html: String = html(blocks, caption)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "collage"
|
||||
fun markdown(blocks: List<RichBlock>, caption: RichBlockCaption?): String =
|
||||
richMediaContainerMarkdown("tg-collage", blocks, caption)
|
||||
fun html(blocks: List<RichBlock>, caption: RichBlockCaption?): String =
|
||||
richMediaContainerHtml("tg-collage", blocks, caption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A slideshow.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockslideshow">RichBlockSlideshow</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockSlideshow(
|
||||
@SerialName(blocksField)
|
||||
val blocks: List<RichBlock>,
|
||||
@SerialName(captionField)
|
||||
val caption: RichBlockCaption? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(blocks, caption)
|
||||
override val html: String = html(blocks, caption)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "slideshow"
|
||||
fun markdown(blocks: List<RichBlock>, caption: RichBlockCaption?): String =
|
||||
richMediaContainerMarkdown("tg-slideshow", blocks, caption)
|
||||
fun html(blocks: List<RichBlock>, caption: RichBlockCaption?): String =
|
||||
richMediaContainerHtml("tg-slideshow", blocks, caption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A table.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblocktable">RichBlockTable</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockTable(
|
||||
@SerialName(cellsField)
|
||||
val cells: List<List<RichBlockTableCell>>,
|
||||
@SerialName(isBorderedField)
|
||||
val isBordered: Boolean? = null,
|
||||
@SerialName(isStripedField)
|
||||
val isStriped: Boolean? = null,
|
||||
@SerialName(captionField)
|
||||
val caption: RichText? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(cells)
|
||||
override val html: String = html(cells, isBordered, isStriped, caption)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "table"
|
||||
fun markdown(cells: List<List<RichBlockTableCell>>): String {
|
||||
if (cells.isEmpty()) return ""
|
||||
fun renderRow(row: List<RichBlockTableCell>): String =
|
||||
row.joinToString(separator = " | ", prefix = "| ", postfix = " |") { it.text?.markdown ?: "" }
|
||||
fun alignment(cell: RichBlockTableCell): String = when (cell.align) {
|
||||
"left" -> ":---"
|
||||
"center" -> ":--:"
|
||||
"right" -> "---:"
|
||||
else -> "---"
|
||||
}
|
||||
val header = cells.first()
|
||||
val lines = mutableListOf(
|
||||
renderRow(header),
|
||||
header.joinToString(separator = " | ", prefix = "| ", postfix = " |") { alignment(it) }
|
||||
)
|
||||
cells.drop(1).forEach { lines.add(renderRow(it)) }
|
||||
return lines.joinToString(separator = "\n")
|
||||
}
|
||||
|
||||
fun html(cells: List<List<RichBlockTableCell>>, isBordered: Boolean?, isStriped: Boolean?, caption: RichText?): String {
|
||||
val attributes = buildString {
|
||||
if (isBordered == true) append(" bordered")
|
||||
if (isStriped == true) append(" striped")
|
||||
}
|
||||
val captionPart = caption?.let { "<caption>${it.html}</caption>" } ?: ""
|
||||
val rows = cells.joinToString(separator = "") { row ->
|
||||
val renderedCells = row.joinToString(separator = "") { cell ->
|
||||
val tag = if (cell.isHeader == true) "th" else "td"
|
||||
val cellAttributes = buildString {
|
||||
cell.colspan?.let { append(" colspan=\"$it\"") }
|
||||
cell.rowspan?.let { append(" rowspan=\"$it\"") }
|
||||
append(" align=\"${cell.align}\"")
|
||||
append(" valign=\"${cell.valign}\"")
|
||||
}
|
||||
"<$tag$cellAttributes>${cell.text?.html ?: ""}</$tag>"
|
||||
}
|
||||
"<tr>$renderedCells</tr>"
|
||||
}
|
||||
return "<table$attributes>$captionPart$rows</table>"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expandable block for details disclosure.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockdetails">RichBlockDetails</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockDetails(
|
||||
@SerialName(summaryField)
|
||||
val summary: RichText,
|
||||
@SerialName(blocksField)
|
||||
val blocks: List<RichBlock>,
|
||||
@SerialName(isOpenField)
|
||||
val isOpen: Boolean? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(summary, blocks, isOpen)
|
||||
override val html: String = html(summary, blocks, isOpen)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "details"
|
||||
fun markdown(summary: RichText, blocks: List<RichBlock>, isOpen: Boolean?): String {
|
||||
val open = if (isOpen == true) " open" else ""
|
||||
return "<details$open><summary>${summary.markdown}</summary>\n\n${blocks.toRichMarkdown()}\n\n</details>"
|
||||
}
|
||||
|
||||
fun html(summary: RichText, blocks: List<RichBlock>, isOpen: Boolean?): String {
|
||||
val open = if (isOpen == true) " open" else ""
|
||||
return "<details$open><summary>${summary.html}</summary>${blocks.toRichHtml()}</details>"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with a map.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockmap">RichBlockMap</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockMap(
|
||||
@SerialName(locationField)
|
||||
val location: StaticLocation,
|
||||
/**
|
||||
* Map zoom level; 13-20.
|
||||
*/
|
||||
@SerialName(zoomField)
|
||||
val zoom: Int,
|
||||
@SerialName(widthField)
|
||||
val width: Int,
|
||||
@SerialName(heightField)
|
||||
val height: Int,
|
||||
@SerialName(captionField)
|
||||
val caption: RichBlockCaption? = null
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(location, zoom, caption)
|
||||
override val html: String = html(location, zoom, caption)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "map"
|
||||
fun markdown(location: StaticLocation, zoom: Int, caption: RichBlockCaption?): String {
|
||||
val element = "<tg-map lat=\"${location.latitude}\" long=\"${location.longitude}\" zoom=\"$zoom\"/>"
|
||||
return caption?.let { "<figure>$element<figcaption>${it.text.markdown}${creditCiteMarkdown(it.credit)}</figcaption></figure>" } ?: element
|
||||
}
|
||||
|
||||
fun html(location: StaticLocation, zoom: Int, caption: RichBlockCaption?): String {
|
||||
val element = "<tg-map lat=\"${location.latitude}\" long=\"${location.longitude}\" zoom=\"$zoom\"/>"
|
||||
return caption?.let { "<figure>$element<figcaption>${it.text.html}${creditCiteHtml(it.credit)}</figcaption></figure>" } ?: element
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with an animation.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockanimation">RichBlockAnimation</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockAnimation(
|
||||
@SerialName(animationField)
|
||||
val animation: AnimationFile,
|
||||
@SerialName(hasSpoilerField)
|
||||
val hasSpoiler: Boolean? = null,
|
||||
@SerialName(captionField)
|
||||
override val caption: RichBlockCaption? = null
|
||||
) : RichBlockMedia {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(animation, caption)
|
||||
override val html: String = html(animation, hasSpoiler, caption)
|
||||
|
||||
override val media: TelegramMediaFile
|
||||
get() = animation
|
||||
|
||||
companion object {
|
||||
const val TYPE = "animation"
|
||||
fun markdown(animation: AnimationFile, caption: RichBlockCaption?): String =
|
||||
richMediaMarkdown(animation.fileId.fileId, caption)
|
||||
fun html(animation: AnimationFile, hasSpoiler: Boolean?, caption: RichBlockCaption?): String =
|
||||
richMediaHtml("video", animation.fileId.fileId, hasSpoiler == true, selfClosing = false, caption = caption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with a music file.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockaudio">RichBlockAudio</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockAudio(
|
||||
@SerialName(audioField)
|
||||
val audio: AudioFile,
|
||||
@SerialName(captionField)
|
||||
override val caption: RichBlockCaption? = null
|
||||
) : RichBlockMedia {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(audio, caption)
|
||||
override val html: String = html(audio, caption)
|
||||
override val media: TelegramMediaFile
|
||||
get() = audio
|
||||
|
||||
companion object {
|
||||
const val TYPE = "audio"
|
||||
fun markdown(audio: AudioFile, caption: RichBlockCaption?): String =
|
||||
richMediaMarkdown(audio.fileId.fileId, caption)
|
||||
fun html(audio: AudioFile, caption: RichBlockCaption?): String =
|
||||
richMediaHtml("audio", audio.fileId.fileId, spoiler = false, selfClosing = false, caption = caption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with a photo.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockphoto">RichBlockPhoto</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockPhoto(
|
||||
@SerialName(photoField)
|
||||
val photo: PhotoFile,
|
||||
@SerialName(hasSpoilerField)
|
||||
val hasSpoiler: Boolean? = null,
|
||||
@SerialName(captionField)
|
||||
override val caption: RichBlockCaption? = null
|
||||
) : RichBlockMedia {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(photo, caption)
|
||||
override val html: String = html(photo, hasSpoiler, caption)
|
||||
override val media: TelegramMediaFile
|
||||
get() = photo
|
||||
|
||||
companion object {
|
||||
const val TYPE = "photo"
|
||||
fun markdown(photo: PhotoFile, caption: RichBlockCaption?): String =
|
||||
richMediaMarkdown(photo.fileId.fileId, caption)
|
||||
fun html(photo: PhotoFile, hasSpoiler: Boolean?, caption: RichBlockCaption?): String =
|
||||
richMediaHtml("img", photo.fileId.fileId, hasSpoiler == true, selfClosing = true, caption = caption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with a video.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockvideo">RichBlockVideo</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockVideo(
|
||||
@SerialName(videoField)
|
||||
val video: VideoFile,
|
||||
@SerialName(hasSpoilerField)
|
||||
val hasSpoiler: Boolean? = null,
|
||||
@SerialName(captionField)
|
||||
override val caption: RichBlockCaption? = null
|
||||
) : RichBlockMedia {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(video, caption)
|
||||
override val html: String = html(video, hasSpoiler, caption)
|
||||
override val media: TelegramMediaFile
|
||||
get() = video
|
||||
|
||||
companion object {
|
||||
const val TYPE = "video"
|
||||
fun markdown(video: VideoFile, caption: RichBlockCaption?): String =
|
||||
richMediaMarkdown(video.fileId.fileId, caption)
|
||||
fun html(video: VideoFile, hasSpoiler: Boolean?, caption: RichBlockCaption?): String =
|
||||
richMediaHtml("video", video.fileId.fileId, hasSpoiler == true, selfClosing = false, caption = caption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with a voice note.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockvoicenote">RichBlockVoiceNote</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockVoiceNote(
|
||||
@SerialName(voiceNoteField)
|
||||
val voiceNote: VoiceFile,
|
||||
@SerialName(captionField)
|
||||
override val caption: RichBlockCaption? = null
|
||||
) : RichBlockMedia {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(voiceNote, caption)
|
||||
override val html: String = html(voiceNote, caption)
|
||||
override val media: TelegramMediaFile
|
||||
get() = voiceNote
|
||||
|
||||
companion object {
|
||||
const val TYPE = "voice_note"
|
||||
fun markdown(voiceNote: VoiceFile, caption: RichBlockCaption?): String =
|
||||
richMediaMarkdown(voiceNote.fileId.fileId, caption)
|
||||
fun html(voiceNote: VoiceFile, caption: RichBlockCaption?): String =
|
||||
richMediaHtml("audio", voiceNote.fileId.fileId, spoiler = false, selfClosing = false, caption = caption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A block with a "Thinking…" placeholder. May be used only in sendRichMessageDraft.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richblockthinking">RichBlockThinking</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichBlockThinking(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichBlock {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "thinking"
|
||||
fun markdown(text: RichText): String = "<tg-thinking>${text.markdown}</tg-thinking>"
|
||||
fun html(text: RichText): String = "<tg-thinking>${text.html}</tg-thinking>"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.utils.extensions.toHtml
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
/**
|
||||
* Represents a rich formatted text. It can be either a plain text ([RichTextPlain]), a group of rich texts
|
||||
* ([RichTextGroup]) or any of [RichTextEntity] subtypes.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtext">RichText</a>
|
||||
*/
|
||||
@Serializable(RichTextSerializer::class)
|
||||
@ClassCastsIncluded
|
||||
sealed interface RichText {
|
||||
/**
|
||||
* Plain (unformatted) text of this [RichText]. For [RichTextEntity]s without an inner [RichText] it falls back to
|
||||
* the most meaningful textual representation: alternative text for custom emojis, the expression for mathematical
|
||||
* expressions and an empty string for anchors.
|
||||
*/
|
||||
val rawText: String
|
||||
|
||||
/**
|
||||
* [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style) representation of this [RichText].
|
||||
*/
|
||||
val markdown: String
|
||||
|
||||
/**
|
||||
* [Rich HTML style](https://core.telegram.org/bots/api#rich-html-style) representation of this [RichText].
|
||||
*/
|
||||
val html: String
|
||||
}
|
||||
|
||||
/**
|
||||
* A plain (non-formatted) part of a [RichText]. Serialized as a bare JSON string.
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextPlain(
|
||||
val text: String
|
||||
) : RichText {
|
||||
override val rawText: String = text
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
fun markdown(text: String): String = text.escapeRichMarkdown()
|
||||
fun html(text: String): String = text.toHtml()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A group of [RichText]s. Serialized as a JSON array.
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextGroup(
|
||||
val parts: List<RichText>
|
||||
) : RichText {
|
||||
override val rawText: String = parts.joinToString(separator = "") { it.rawText }
|
||||
override val markdown: String = markdown(parts)
|
||||
override val html: String = html(parts)
|
||||
|
||||
companion object {
|
||||
fun markdown(parts: List<RichText>): String = parts.joinToString(separator = "") { it.markdown }
|
||||
fun html(parts: List<RichText>): String = parts.joinToString(separator = "") { it.html }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Any typed (formatted) part of a [RichText]. Serialized as a JSON object with the [type] discriminator.
|
||||
*/
|
||||
@Serializable(RichTextEntitySerializer::class)
|
||||
sealed interface RichTextEntity : RichText {
|
||||
val type: String
|
||||
|
||||
override val markdown: String
|
||||
override val html: String
|
||||
}
|
||||
|
||||
object RichTextSerializer : KSerializer<RichText> {
|
||||
override val descriptor: SerialDescriptor = JsonElement.serializer().descriptor
|
||||
|
||||
private fun fromJson(json: Json, element: JsonElement): RichText = when (element) {
|
||||
is JsonArray -> RichTextGroup(element.map { fromJson(json, it) })
|
||||
is JsonObject -> json.decodeFromJsonElement(RichTextEntitySerializer, element)
|
||||
is JsonPrimitive -> RichTextPlain(element.content)
|
||||
}
|
||||
|
||||
private fun toJson(json: Json, value: RichText): JsonElement = when (value) {
|
||||
is RichTextPlain -> JsonPrimitive(value.text)
|
||||
is RichTextGroup -> JsonArray(value.parts.map { toJson(json, it) })
|
||||
is RichTextEntity -> json.encodeToJsonElement(RichTextEntitySerializer, value)
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): RichText {
|
||||
val input = decoder as JsonDecoder
|
||||
return fromJson(input.json, input.decodeJsonElement())
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: RichText) {
|
||||
val output = encoder as JsonEncoder
|
||||
output.encodeJsonElement(toJson(output.json, value))
|
||||
}
|
||||
}
|
||||
|
||||
object RichTextEntitySerializer : JsonContentPolymorphicSerializer<RichTextEntity>(RichTextEntity::class) {
|
||||
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<RichTextEntity> {
|
||||
return when (val type = element.jsonObject[typeField]?.jsonPrimitive?.content) {
|
||||
RichTextBold.TYPE -> RichTextBold.serializer()
|
||||
RichTextItalic.TYPE -> RichTextItalic.serializer()
|
||||
RichTextUnderline.TYPE -> RichTextUnderline.serializer()
|
||||
RichTextStrikethrough.TYPE -> RichTextStrikethrough.serializer()
|
||||
RichTextSpoiler.TYPE -> RichTextSpoiler.serializer()
|
||||
RichTextDateTime.TYPE -> RichTextDateTime.serializer()
|
||||
RichTextTextMention.TYPE -> RichTextTextMention.serializer()
|
||||
RichTextSubscript.TYPE -> RichTextSubscript.serializer()
|
||||
RichTextSuperscript.TYPE -> RichTextSuperscript.serializer()
|
||||
RichTextMarked.TYPE -> RichTextMarked.serializer()
|
||||
RichTextCode.TYPE -> RichTextCode.serializer()
|
||||
RichTextCustomEmoji.TYPE -> RichTextCustomEmoji.serializer()
|
||||
RichTextMathematicalExpression.TYPE -> RichTextMathematicalExpression.serializer()
|
||||
RichTextUrl.TYPE -> RichTextUrl.serializer()
|
||||
RichTextEmailAddress.TYPE -> RichTextEmailAddress.serializer()
|
||||
RichTextPhoneNumber.TYPE -> RichTextPhoneNumber.serializer()
|
||||
RichTextBankCardNumber.TYPE -> RichTextBankCardNumber.serializer()
|
||||
RichTextMention.TYPE -> RichTextMention.serializer()
|
||||
RichTextHashtag.TYPE -> RichTextHashtag.serializer()
|
||||
RichTextCashtag.TYPE -> RichTextCashtag.serializer()
|
||||
RichTextBotCommand.TYPE -> RichTextBotCommand.serializer()
|
||||
RichTextAnchor.TYPE -> RichTextAnchor.serializer()
|
||||
RichTextAnchorLink.TYPE -> RichTextAnchorLink.serializer()
|
||||
RichTextReference.TYPE -> RichTextReference.serializer()
|
||||
RichTextReferenceLink.TYPE -> RichTextReferenceLink.serializer()
|
||||
else -> error("Unknown RichTextEntity type: $type")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.CustomEmojiId
|
||||
import dev.inmo.tgbotapi.types.TelegramDate
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
|
||||
/**
|
||||
* [DslMarker] for the rich message builders, so the inner [RichTextBuilder], [RichBlocksBuilder] and
|
||||
* [RichBlockListBuilder] scopes do not leak their receivers into each other.
|
||||
*/
|
||||
@DslMarker
|
||||
annotation class RichTextDsl
|
||||
|
||||
/**
|
||||
* Builder of a single [RichText]. Each call appends a part; [build] returns a [RichTextPlain]/[RichTextEntity] when there
|
||||
* is exactly one part, a [RichTextGroup] otherwise.
|
||||
*/
|
||||
@RichTextDsl
|
||||
class RichTextBuilder {
|
||||
private val parts = mutableListOf<RichText>()
|
||||
|
||||
/** Appends an already built [RichText]. */
|
||||
fun add(richText: RichText) {
|
||||
parts.add(richText)
|
||||
}
|
||||
|
||||
/** Appends an already built [RichText]. */
|
||||
operator fun RichText.unaryPlus() = add(this)
|
||||
|
||||
/** Plain, non-formatted text. */
|
||||
fun plain(text: String) = add(RichTextPlain(text))
|
||||
|
||||
fun bold(text: String) = add(RichTextBold(RichTextPlain(text)))
|
||||
fun bold(block: RichTextBuilder.() -> Unit) = add(RichTextBold(buildRichText(block)))
|
||||
|
||||
fun italic(text: String) = add(RichTextItalic(RichTextPlain(text)))
|
||||
fun italic(block: RichTextBuilder.() -> Unit) = add(RichTextItalic(buildRichText(block)))
|
||||
|
||||
fun underline(text: String) = add(RichTextUnderline(RichTextPlain(text)))
|
||||
fun underline(block: RichTextBuilder.() -> Unit) = add(RichTextUnderline(buildRichText(block)))
|
||||
|
||||
fun strikethrough(text: String) = add(RichTextStrikethrough(RichTextPlain(text)))
|
||||
fun strikethrough(block: RichTextBuilder.() -> Unit) = add(RichTextStrikethrough(buildRichText(block)))
|
||||
|
||||
fun spoiler(text: String) = add(RichTextSpoiler(RichTextPlain(text)))
|
||||
fun spoiler(block: RichTextBuilder.() -> Unit) = add(RichTextSpoiler(buildRichText(block)))
|
||||
|
||||
fun subscript(text: String) = add(RichTextSubscript(RichTextPlain(text)))
|
||||
fun subscript(block: RichTextBuilder.() -> Unit) = add(RichTextSubscript(buildRichText(block)))
|
||||
|
||||
fun superscript(text: String) = add(RichTextSuperscript(RichTextPlain(text)))
|
||||
fun superscript(block: RichTextBuilder.() -> Unit) = add(RichTextSuperscript(buildRichText(block)))
|
||||
|
||||
fun marked(text: String) = add(RichTextMarked(RichTextPlain(text)))
|
||||
fun marked(block: RichTextBuilder.() -> Unit) = add(RichTextMarked(buildRichText(block)))
|
||||
|
||||
fun code(text: String) = add(RichTextCode(RichTextPlain(text)))
|
||||
fun code(block: RichTextBuilder.() -> Unit) = add(RichTextCode(buildRichText(block)))
|
||||
|
||||
fun dateTime(text: String, unixTime: TelegramDate, dateTimeFormat: String) =
|
||||
add(RichTextDateTime(RichTextPlain(text), unixTime, dateTimeFormat))
|
||||
fun dateTime(unixTime: TelegramDate, dateTimeFormat: String, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichTextDateTime(buildRichText(block), unixTime, dateTimeFormat))
|
||||
|
||||
fun textMention(text: String, user: User) = add(RichTextTextMention(RichTextPlain(text), user))
|
||||
fun textMention(user: User, block: RichTextBuilder.() -> Unit) = add(RichTextTextMention(buildRichText(block), user))
|
||||
|
||||
fun customEmoji(customEmojiId: CustomEmojiId, alternativeText: String) =
|
||||
add(RichTextCustomEmoji(customEmojiId, alternativeText))
|
||||
|
||||
fun mathematicalExpression(expression: String) = add(RichTextMathematicalExpression(expression))
|
||||
|
||||
fun url(text: String, url: String) = add(RichTextUrl(RichTextPlain(text), url))
|
||||
fun url(url: String, block: RichTextBuilder.() -> Unit) = add(RichTextUrl(buildRichText(block), url))
|
||||
|
||||
fun email(text: String, emailAddress: String) = add(RichTextEmailAddress(RichTextPlain(text), emailAddress))
|
||||
fun email(emailAddress: String, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichTextEmailAddress(buildRichText(block), emailAddress))
|
||||
|
||||
fun phone(text: String, phoneNumber: String) = add(RichTextPhoneNumber(RichTextPlain(text), phoneNumber))
|
||||
fun phone(phoneNumber: String, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichTextPhoneNumber(buildRichText(block), phoneNumber))
|
||||
|
||||
fun bankCard(text: String, bankCardNumber: String) = add(RichTextBankCardNumber(RichTextPlain(text), bankCardNumber))
|
||||
fun bankCard(bankCardNumber: String, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichTextBankCardNumber(buildRichText(block), bankCardNumber))
|
||||
|
||||
fun mention(text: String, username: String) = add(RichTextMention(RichTextPlain(text), username))
|
||||
fun mention(username: String, block: RichTextBuilder.() -> Unit) = add(RichTextMention(buildRichText(block), username))
|
||||
|
||||
fun hashtag(text: String, hashtag: String) = add(RichTextHashtag(RichTextPlain(text), hashtag))
|
||||
fun hashtag(hashtag: String, block: RichTextBuilder.() -> Unit) = add(RichTextHashtag(buildRichText(block), hashtag))
|
||||
|
||||
fun cashtag(text: String, cashtag: String) = add(RichTextCashtag(RichTextPlain(text), cashtag))
|
||||
fun cashtag(cashtag: String, block: RichTextBuilder.() -> Unit) = add(RichTextCashtag(buildRichText(block), cashtag))
|
||||
|
||||
fun botCommand(text: String, botCommand: String) = add(RichTextBotCommand(RichTextPlain(text), botCommand))
|
||||
fun botCommand(botCommand: String, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichTextBotCommand(buildRichText(block), botCommand))
|
||||
|
||||
fun anchor(name: String) = add(RichTextAnchor(name))
|
||||
|
||||
fun anchorLink(text: String, anchorName: String) = add(RichTextAnchorLink(RichTextPlain(text), anchorName))
|
||||
fun anchorLink(anchorName: String, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichTextAnchorLink(buildRichText(block), anchorName))
|
||||
|
||||
fun reference(text: String, name: String) = add(RichTextReference(RichTextPlain(text), name))
|
||||
fun reference(name: String, block: RichTextBuilder.() -> Unit) = add(RichTextReference(buildRichText(block), name))
|
||||
|
||||
fun referenceLink(text: String, referenceName: String) =
|
||||
add(RichTextReferenceLink(RichTextPlain(text), referenceName))
|
||||
fun referenceLink(referenceName: String, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichTextReferenceLink(buildRichText(block), referenceName))
|
||||
|
||||
fun build(): RichText = when (parts.size) {
|
||||
0 -> RichTextGroup(emptyList())
|
||||
1 -> parts.single()
|
||||
else -> RichTextGroup(parts.toList())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder of [RichBlockListItem]s used inside [RichBlocksBuilder.list].
|
||||
*/
|
||||
@RichTextDsl
|
||||
class RichBlockListBuilder {
|
||||
private val items = mutableListOf<RichBlockListItem>()
|
||||
|
||||
fun item(
|
||||
label: String,
|
||||
hasCheckbox: Boolean? = null,
|
||||
isChecked: Boolean? = null,
|
||||
value: Int? = null,
|
||||
labelType: String? = null,
|
||||
block: RichBlocksBuilder.() -> Unit
|
||||
) {
|
||||
items.add(RichBlockListItem(label, buildRichBlocks(block), hasCheckbox, isChecked, value, labelType))
|
||||
}
|
||||
|
||||
fun item(label: String, text: String) {
|
||||
items.add(RichBlockListItem(label, listOf(RichBlockParagraph(RichTextPlain(text)))))
|
||||
}
|
||||
|
||||
fun build(): List<RichBlockListItem> = items.toList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder of a [List] of [RichBlock]s - the root of the rich message DSL. Text-bearing and container blocks have their
|
||||
* own DSL functions; file/cell-heavy blocks (media, collage, slideshow, table, map) can be appended with [add] / unary
|
||||
* plus.
|
||||
*/
|
||||
@RichTextDsl
|
||||
class RichBlocksBuilder {
|
||||
private val blocks = mutableListOf<RichBlock>()
|
||||
|
||||
/** Appends an already built [RichBlock]. */
|
||||
fun add(block: RichBlock) {
|
||||
blocks.add(block)
|
||||
}
|
||||
|
||||
/** Appends an already built [RichBlock]. */
|
||||
operator fun RichBlock.unaryPlus() = add(this)
|
||||
|
||||
fun paragraph(text: String) = add(RichBlockParagraph(RichTextPlain(text)))
|
||||
fun paragraph(block: RichTextBuilder.() -> Unit) = add(RichBlockParagraph(buildRichText(block)))
|
||||
|
||||
fun heading(text: String, level: Int) = add(RichBlockSectionHeading(RichTextPlain(text), level))
|
||||
fun heading(level: Int, block: RichTextBuilder.() -> Unit) = add(RichBlockSectionHeading(buildRichText(block), level))
|
||||
|
||||
fun preformatted(text: String, language: String? = null) = add(RichBlockPreformatted(RichTextPlain(text), language))
|
||||
|
||||
fun footer(text: String) = add(RichBlockFooter(RichTextPlain(text)))
|
||||
fun footer(block: RichTextBuilder.() -> Unit) = add(RichBlockFooter(buildRichText(block)))
|
||||
|
||||
fun divider() = add(RichBlockDivider())
|
||||
|
||||
fun mathematicalExpression(expression: String) = add(RichBlockMathematicalExpression(expression))
|
||||
|
||||
fun anchor(name: String) = add(RichBlockAnchor(name))
|
||||
|
||||
fun thinking(text: String) = add(RichBlockThinking(RichTextPlain(text)))
|
||||
fun thinking(block: RichTextBuilder.() -> Unit) = add(RichBlockThinking(buildRichText(block)))
|
||||
|
||||
fun list(block: RichBlockListBuilder.() -> Unit) = add(RichBlockList(RichBlockListBuilder().apply(block).build()))
|
||||
|
||||
fun blockQuotation(credit: RichText? = null, block: RichBlocksBuilder.() -> Unit) =
|
||||
add(RichBlockBlockQuotation(buildRichBlocks(block), credit))
|
||||
|
||||
fun pullQuotation(credit: RichText? = null, block: RichTextBuilder.() -> Unit) =
|
||||
add(RichBlockPullQuotation(buildRichText(block), credit))
|
||||
|
||||
fun details(summary: RichText, isOpen: Boolean? = null, block: RichBlocksBuilder.() -> Unit) =
|
||||
add(RichBlockDetails(summary, buildRichBlocks(block), isOpen))
|
||||
|
||||
fun details(summary: String, isOpen: Boolean? = null, block: RichBlocksBuilder.() -> Unit) =
|
||||
details(RichTextPlain(summary), isOpen, block)
|
||||
|
||||
fun build(): List<RichBlock> = blocks.toList()
|
||||
}
|
||||
|
||||
/** Builds a [RichText] using the [RichTextBuilder] DSL. */
|
||||
fun buildRichText(block: RichTextBuilder.() -> Unit): RichText = RichTextBuilder().apply(block).build()
|
||||
|
||||
/** Builds a [List] of [RichBlock]s using the [RichBlocksBuilder] DSL. */
|
||||
fun buildRichBlocks(block: RichBlocksBuilder.() -> Unit): List<RichBlock> = RichBlocksBuilder().apply(block).build()
|
||||
|
||||
/** Builds a [RichTextInfo] using the [RichBlocksBuilder] DSL. */
|
||||
fun buildRichTextInfo(isRtl: Boolean? = null, block: RichBlocksBuilder.() -> Unit): RichTextInfo =
|
||||
RichTextInfo(buildRichBlocks(block), isRtl)
|
||||
@@ -0,0 +1,690 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.CustomEmojiId
|
||||
import dev.inmo.tgbotapi.types.alternativeTextField
|
||||
import dev.inmo.tgbotapi.types.anchorNameField
|
||||
import dev.inmo.tgbotapi.types.bankCardNumberField
|
||||
import dev.inmo.tgbotapi.types.botCommandFullField
|
||||
import dev.inmo.tgbotapi.types.cashtagField
|
||||
import dev.inmo.tgbotapi.types.chat.User
|
||||
import dev.inmo.tgbotapi.types.customEmojiIdField
|
||||
import dev.inmo.tgbotapi.types.dateTimeFormatField
|
||||
import dev.inmo.tgbotapi.types.emailAddressField
|
||||
import dev.inmo.tgbotapi.types.expressionField
|
||||
import dev.inmo.tgbotapi.types.hashtagField
|
||||
import dev.inmo.tgbotapi.types.internalUserLinkBeginning
|
||||
import dev.inmo.tgbotapi.types.nameField
|
||||
import dev.inmo.tgbotapi.types.phoneNumberField
|
||||
import dev.inmo.tgbotapi.types.referenceNameField
|
||||
import dev.inmo.tgbotapi.types.TelegramDate
|
||||
import dev.inmo.tgbotapi.types.textField
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.types.unixTimeField
|
||||
import dev.inmo.tgbotapi.types.urlField
|
||||
import dev.inmo.tgbotapi.types.userField
|
||||
import dev.inmo.tgbotapi.types.usernameField
|
||||
import dev.inmo.tgbotapi.utils.extensions.toHtml
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A bold [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextbold">RichTextBold</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextBold(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "bold"
|
||||
fun markdown(text: RichText): String = "**${text.markdown}**"
|
||||
fun html(text: RichText): String = "<b>${text.html}</b>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An italicized [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextitalic">RichTextItalic</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextItalic(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "italic"
|
||||
fun markdown(text: RichText): String = "*${text.markdown}*"
|
||||
fun html(text: RichText): String = "<i>${text.html}</i>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An underlined [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextunderline">RichTextUnderline</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextUnderline(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "underline"
|
||||
fun markdown(text: RichText): String = "<u>${text.markdown}</u>"
|
||||
fun html(text: RichText): String = "<u>${text.html}</u>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A strikethrough [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextstrikethrough">RichTextStrikethrough</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextStrikethrough(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "strikethrough"
|
||||
fun markdown(text: RichText): String = "~~${text.markdown}~~"
|
||||
fun html(text: RichText): String = "<s>${text.html}</s>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A [RichTextEntity] covered by a spoiler.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextspoiler">RichTextSpoiler</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextSpoiler(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "spoiler"
|
||||
fun markdown(text: RichText): String = "||${text.markdown}||"
|
||||
fun html(text: RichText): String = "<tg-spoiler>${text.html}</tg-spoiler>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A subscript [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextsubscript">RichTextSubscript</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextSubscript(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "subscript"
|
||||
fun markdown(text: RichText): String = "<sub>${text.markdown}</sub>"
|
||||
fun html(text: RichText): String = "<sub>${text.html}</sub>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A superscript [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextsuperscript">RichTextSuperscript</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextSuperscript(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "superscript"
|
||||
fun markdown(text: RichText): String = "<sup>${text.markdown}</sup>"
|
||||
fun html(text: RichText): String = "<sup>${text.html}</sup>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A marked [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextmarked">RichTextMarked</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextMarked(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "marked"
|
||||
fun markdown(text: RichText): String = "==${text.markdown}=="
|
||||
fun html(text: RichText): String = "<mark>${text.html}</mark>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A monowidth [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextcode">RichTextCode</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextCode(
|
||||
@SerialName(textField)
|
||||
val text: RichText
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "code"
|
||||
fun markdown(text: RichText): String = "`${text.rawText}`"
|
||||
fun html(text: RichText): String = "<code>${text.html}</code>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A formatted date and time [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextdatetime">RichTextDateTime</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextDateTime(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(unixTimeField)
|
||||
val unixTime: TelegramDate,
|
||||
@SerialName(dateTimeFormatField)
|
||||
val dateTimeFormat: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, unixTime, dateTimeFormat)
|
||||
override val html: String = html(text, unixTime, dateTimeFormat)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "date_time"
|
||||
fun markdown(text: RichText, unixTime: TelegramDate, dateTimeFormat: String): String =
|
||||
""
|
||||
fun html(text: RichText, unixTime: TelegramDate, dateTimeFormat: String): String =
|
||||
"<tg-time unix=\"${unixTime.date}\" format=\"$dateTimeFormat\">${text.html}</tg-time>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A mention of a Telegram user by their identifier.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtexttextmention">RichTextTextMention</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextTextMention(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(userField)
|
||||
val user: User
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, user)
|
||||
override val html: String = html(text, user)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "text_mention"
|
||||
fun markdown(text: RichText, user: User): String =
|
||||
"[${text.markdown}]($internalUserLinkBeginning${user.id.chatId.long})"
|
||||
fun html(text: RichText, user: User): String =
|
||||
"<a href=\"$internalUserLinkBeginning${user.id.chatId.long}\">${text.html}</a>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom emoji [RichTextEntity].
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextcustomemoji">RichTextCustomEmoji</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextCustomEmoji(
|
||||
@SerialName(customEmojiIdField)
|
||||
val customEmojiId: CustomEmojiId,
|
||||
@SerialName(alternativeTextField)
|
||||
val alternativeText: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = alternativeText
|
||||
override val markdown: String = markdown(customEmojiId, alternativeText)
|
||||
override val html: String = html(customEmojiId, alternativeText)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "custom_emoji"
|
||||
fun markdown(customEmojiId: CustomEmojiId, alternativeText: String): String =
|
||||
""
|
||||
fun html(customEmojiId: CustomEmojiId, alternativeText: String): String =
|
||||
"<tg-emoji emoji-id=\"${customEmojiId.string}\">${alternativeText.toHtml()}</tg-emoji>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A mathematical expression in LaTeX format.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextmathematicalexpression">RichTextMathematicalExpression</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextMathematicalExpression(
|
||||
@SerialName(expressionField)
|
||||
val expression: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = expression
|
||||
override val markdown: String = markdown(expression)
|
||||
override val html: String = html(expression)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "mathematical_expression"
|
||||
fun markdown(expression: String): String = "\$$expression\$"
|
||||
fun html(expression: String): String = "<tg-math>$expression</tg-math>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A [RichTextEntity] with a link.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtexturl">RichTextUrl</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextUrl(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(urlField)
|
||||
val url: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, url)
|
||||
override val html: String = html(text, url)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "url"
|
||||
fun markdown(text: RichText, url: String): String = "[${text.markdown}]($url)"
|
||||
fun html(text: RichText, url: String): String = "<a href=\"$url\">${text.html}</a>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A [RichTextEntity] with an email address.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextemailaddress">RichTextEmailAddress</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextEmailAddress(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(emailAddressField)
|
||||
val emailAddress: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, emailAddress)
|
||||
override val html: String = html(text, emailAddress)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "email_address"
|
||||
fun markdown(text: RichText, emailAddress: String): String = "[${text.markdown}](mailto:$emailAddress)"
|
||||
fun html(text: RichText, emailAddress: String): String = "<a href=\"mailto:$emailAddress\">${text.html}</a>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A [RichTextEntity] with a phone number.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextphonenumber">RichTextPhoneNumber</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextPhoneNumber(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(phoneNumberField)
|
||||
val phoneNumber: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, phoneNumber)
|
||||
override val html: String = html(text, phoneNumber)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "phone_number"
|
||||
fun markdown(text: RichText, phoneNumber: String): String = "[${text.markdown}](tel:$phoneNumber)"
|
||||
fun html(text: RichText, phoneNumber: String): String = "<a href=\"tel:$phoneNumber\">${text.html}</a>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A [RichTextEntity] with a bank card number.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextbankcardnumber">RichTextBankCardNumber</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextBankCardNumber(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(bankCardNumberField)
|
||||
val bankCardNumber: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "bank_card_number"
|
||||
fun markdown(text: RichText): String = text.markdown
|
||||
fun html(text: RichText): String = text.html
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A mention by a username.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextmention">RichTextMention</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextMention(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(usernameField)
|
||||
val username: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "mention"
|
||||
fun markdown(text: RichText): String = text.markdown
|
||||
fun html(text: RichText): String = text.html
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A hashtag.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtexthashtag">RichTextHashtag</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextHashtag(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(hashtagField)
|
||||
val hashtag: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "hashtag"
|
||||
fun markdown(text: RichText): String = text.markdown
|
||||
fun html(text: RichText): String = text.html
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cashtag.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextcashtag">RichTextCashtag</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextCashtag(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(cashtagField)
|
||||
val cashtag: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "cashtag"
|
||||
fun markdown(text: RichText): String = text.markdown
|
||||
fun html(text: RichText): String = text.html
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bot command.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextbotcommand">RichTextBotCommand</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextBotCommand(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(botCommandFullField)
|
||||
val botCommand: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text)
|
||||
override val html: String = html(text)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "bot_command"
|
||||
fun markdown(text: RichText): String = text.markdown
|
||||
fun html(text: RichText): String = text.html
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An anchor.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextanchor">RichTextAnchor</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextAnchor(
|
||||
@SerialName(nameField)
|
||||
val name: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = ""
|
||||
override val markdown: String = markdown(name)
|
||||
override val html: String = html(name)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "anchor"
|
||||
fun markdown(name: String): String = "<a name=\"$name\"></a>"
|
||||
fun html(name: String): String = "<a name=\"$name\"></a>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to an anchor.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextanchorlink">RichTextAnchorLink</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextAnchorLink(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(anchorNameField)
|
||||
val anchorName: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, anchorName)
|
||||
override val html: String = html(text, anchorName)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "anchor_link"
|
||||
fun markdown(text: RichText, anchorName: String): String = "[${text.markdown}](#$anchorName)"
|
||||
fun html(text: RichText, anchorName: String): String = "<a href=\"#$anchorName\">${text.html}</a>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextreference">RichTextReference</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextReference(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(nameField)
|
||||
val name: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, name)
|
||||
override val html: String = html(text, name)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "reference"
|
||||
fun markdown(text: RichText, name: String): String = "<tg-reference name=\"$name\">${text.markdown}</tg-reference>"
|
||||
fun html(text: RichText, name: String): String = "<tg-reference name=\"$name\">${text.html}</tg-reference>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to a reference.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richtextreferencelink">RichTextReferenceLink</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextReferenceLink(
|
||||
@SerialName(textField)
|
||||
val text: RichText,
|
||||
@SerialName(referenceNameField)
|
||||
val referenceName: String
|
||||
) : RichTextEntity {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = TYPE
|
||||
|
||||
override val rawText: String = text.rawText
|
||||
override val markdown: String = markdown(text, referenceName)
|
||||
override val html: String = html(text, referenceName)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "reference_link"
|
||||
fun markdown(text: RichText, referenceName: String): String = "[${text.markdown}](#$referenceName)"
|
||||
fun html(text: RichText, referenceName: String): String = "<a href=\"#$referenceName\">${text.html}</a>"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
/**
|
||||
* Characters which have a special meaning in the
|
||||
* [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style) and must be escaped with a backslash
|
||||
* to be represented literally.
|
||||
*/
|
||||
private val richMarkdownSpecialCharacters = setOf(
|
||||
'\\', '`', '*', '_', '~', '|', '[', ']', '(', ')', '<', '>', '#', '=', '!', '$'
|
||||
)
|
||||
|
||||
/**
|
||||
* Escapes all the [richMarkdownSpecialCharacters] of the receiver with a backslash so that the resulting string is
|
||||
* represented literally in the [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style).
|
||||
*/
|
||||
fun String.escapeRichMarkdown(): String = buildString {
|
||||
for (character in this@escapeRichMarkdown) {
|
||||
if (character in richMarkdownSpecialCharacters) {
|
||||
append('\\')
|
||||
}
|
||||
append(character)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.blocksField
|
||||
import dev.inmo.tgbotapi.types.isRtlField
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Rich formatted message.
|
||||
*
|
||||
* @see <a href="https://core.telegram.org/bots/api#richmessage">RichMessage</a>
|
||||
*/
|
||||
@Serializable
|
||||
data class RichTextInfo(
|
||||
@SerialName(blocksField)
|
||||
val blocks: List<RichBlock>,
|
||||
@SerialName(isRtlField)
|
||||
val isRtl: Boolean? = null
|
||||
)
|
||||
@@ -0,0 +1,71 @@
|
||||
package dev.inmo.tgbotapi.types
|
||||
|
||||
import dev.inmo.tgbotapi.types.rich.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class RichMessageSerializationTest {
|
||||
private val json = Json { encodeDefaults = true }
|
||||
|
||||
@Test
|
||||
fun decodesRichMessageWithMixedRichText() {
|
||||
val source = """
|
||||
{
|
||||
"blocks": [
|
||||
{
|
||||
"type": "paragraph",
|
||||
"text": ["Hello ", {"type": "bold", "text": "world"}, "!"]
|
||||
},
|
||||
{"type": "heading", "text": "Title", "size": 1},
|
||||
{"type": "divider"},
|
||||
{"type": "list", "items": [
|
||||
{"label": "1", "blocks": [{"type": "paragraph", "text": "first"}]}
|
||||
]}
|
||||
],
|
||||
"is_rtl": false
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
val message = json.decodeFromString(RichTextInfo.serializer(), source)
|
||||
assertEquals(4, message.blocks.size)
|
||||
|
||||
val paragraph = message.blocks[0] as RichBlockParagraph
|
||||
val group = paragraph.text as RichTextGroup
|
||||
assertEquals(RichTextPlain("Hello "), group.parts[0])
|
||||
assertEquals(RichTextBold(RichTextPlain("world")), group.parts[1])
|
||||
assertEquals(RichTextPlain("!"), group.parts[2])
|
||||
|
||||
val heading = message.blocks[1] as RichBlockSectionHeading
|
||||
assertEquals(RichTextPlain("Title"), heading.text)
|
||||
assertEquals(1, heading.level)
|
||||
|
||||
assertTrue(message.blocks[2] is RichBlockDivider)
|
||||
|
||||
val list = message.blocks[3] as RichBlockList
|
||||
assertEquals("1", list.items[0].label)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun roundTripsRichMessage() {
|
||||
val message = RichTextInfo(
|
||||
blocks = listOf(
|
||||
RichBlockParagraph(
|
||||
RichTextGroup(
|
||||
listOf(
|
||||
RichTextPlain("a "),
|
||||
RichTextItalic(RichTextPlain("b")),
|
||||
RichTextUrl(RichTextPlain("link"), "https://example.org")
|
||||
)
|
||||
)
|
||||
),
|
||||
RichBlockDivider()
|
||||
)
|
||||
)
|
||||
|
||||
val encoded = json.encodeToString(RichTextInfo.serializer(), message)
|
||||
val decoded = json.decodeFromString(RichTextInfo.serializer(), encoded)
|
||||
assertEquals(message, decoded)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class RichBlockFormattingTest {
|
||||
@Test
|
||||
fun paragraph() {
|
||||
val block = RichBlockParagraph(RichTextPlain("Hello"))
|
||||
assertEquals("Hello", block.markdown)
|
||||
assertEquals("<p>Hello</p>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun heading() {
|
||||
val block = RichBlockSectionHeading(RichTextPlain("Title"), 2)
|
||||
assertEquals("## Title", block.markdown)
|
||||
assertEquals("<h2>Title</h2>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun divider() {
|
||||
val block = RichBlockDivider()
|
||||
assertEquals("---", block.markdown)
|
||||
assertEquals("<hr/>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun footer() {
|
||||
val block = RichBlockFooter(RichTextPlain("f"))
|
||||
assertEquals("<footer>f</footer>", block.markdown)
|
||||
assertEquals("<footer>f</footer>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun preformatted() {
|
||||
val withLanguage = RichBlockPreformatted(RichTextPlain("code"), "kotlin")
|
||||
assertEquals("```kotlin\ncode\n```", withLanguage.markdown)
|
||||
assertEquals("<pre><code class=\"language-kotlin\">code</code></pre>", withLanguage.html)
|
||||
|
||||
val withoutLanguage = RichBlockPreformatted(RichTextPlain("c"))
|
||||
assertEquals("```\nc\n```", withoutLanguage.markdown)
|
||||
assertEquals("<pre>c</pre>", withoutLanguage.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mathematicalExpression() {
|
||||
val block = RichBlockMathematicalExpression("E=mc^2")
|
||||
assertEquals("\$\$E=mc^2\$\$", block.markdown)
|
||||
assertEquals("<tg-math-block>E=mc^2</tg-math-block>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anchor() {
|
||||
val block = RichBlockAnchor("top")
|
||||
assertEquals("<a name=\"top\"></a>", block.markdown)
|
||||
assertEquals("<a name=\"top\"></a>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bulletList() {
|
||||
val block = RichBlockList(listOf(RichBlockListItem("-", listOf(RichBlockParagraph(RichTextPlain("one"))))))
|
||||
assertEquals("- one", block.markdown)
|
||||
assertEquals("<ul><li><p>one</p></li></ul>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun orderedList() {
|
||||
val block = RichBlockList(
|
||||
listOf(RichBlockListItem("1", listOf(RichBlockParagraph(RichTextPlain("one"))), labelType = "1"))
|
||||
)
|
||||
assertEquals("1. one", block.markdown)
|
||||
assertEquals("<ol><li type=\"1\"><p>one</p></li></ol>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskList() {
|
||||
val block = RichBlockList(
|
||||
listOf(
|
||||
RichBlockListItem(
|
||||
"x",
|
||||
listOf(RichBlockParagraph(RichTextPlain("done"))),
|
||||
hasCheckbox = true,
|
||||
isChecked = true
|
||||
)
|
||||
)
|
||||
)
|
||||
assertEquals("- [x] done", block.markdown)
|
||||
assertEquals("<ul><li><input type=\"checkbox\" checked><p>done</p></li></ul>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun blockQuotation() {
|
||||
val block = RichBlockBlockQuotation(listOf(RichBlockParagraph(RichTextPlain("q"))))
|
||||
assertEquals("> q", block.markdown)
|
||||
assertEquals("<blockquote><p>q</p></blockquote>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun details() {
|
||||
val block = RichBlockDetails(RichTextPlain("sum"), listOf(RichBlockParagraph(RichTextPlain("body"))), isOpen = true)
|
||||
assertEquals("<details open><summary>sum</summary>\n\nbody\n\n</details>", block.markdown)
|
||||
assertEquals("<details open><summary>sum</summary><p>body</p></details>", block.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun table() {
|
||||
val block = RichBlockTable(
|
||||
listOf(
|
||||
listOf(
|
||||
RichBlockTableCell(text = RichTextPlain("H1"), isHeader = true, align = "left", valign = "top"),
|
||||
RichBlockTableCell(text = RichTextPlain("H2"), isHeader = true, align = "center", valign = "top")
|
||||
),
|
||||
listOf(
|
||||
RichBlockTableCell(text = RichTextPlain("a"), align = "left", valign = "top"),
|
||||
RichBlockTableCell(text = RichTextPlain("b"), align = "center", valign = "top")
|
||||
)
|
||||
)
|
||||
)
|
||||
assertEquals("| H1 | H2 |\n| :--- | :--: |\n| a | b |", block.markdown)
|
||||
assertEquals(
|
||||
"<table><tr><th align=\"left\" valign=\"top\">H1</th><th align=\"center\" valign=\"top\">H2</th></tr>" +
|
||||
"<tr><td align=\"left\" valign=\"top\">a</td><td align=\"center\" valign=\"top\">b</td></tr></table>",
|
||||
block.html
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listOfBlocksJoinsBlocks() {
|
||||
val blocks = listOf(RichBlockParagraph(RichTextPlain("a")), RichBlockDivider())
|
||||
assertEquals("a\n\n---", blocks.toRichMarkdown())
|
||||
assertEquals("<p>a</p>\n<hr/>", blocks.toRichHtml())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun richTextInfoDelegatesToBlocks() {
|
||||
val info = RichTextInfo(listOf(RichBlockParagraph(RichTextPlain("p")), RichBlockDivider()))
|
||||
assertEquals("p\n\n---", info.markdown)
|
||||
assertEquals("<p>p</p>\n<hr/>", info.html)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class RichTextDslTest {
|
||||
@Test
|
||||
fun buildsRichTextGroup() {
|
||||
val richText = buildRichText {
|
||||
plain("a ")
|
||||
bold("b")
|
||||
italic {
|
||||
plain("c")
|
||||
bold("d")
|
||||
}
|
||||
}
|
||||
assertEquals(
|
||||
RichTextGroup(
|
||||
listOf(
|
||||
RichTextPlain("a "),
|
||||
RichTextBold(RichTextPlain("b")),
|
||||
RichTextItalic(RichTextGroup(listOf(RichTextPlain("c"), RichTextBold(RichTextPlain("d")))))
|
||||
)
|
||||
),
|
||||
richText
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun singlePartUnwraps() {
|
||||
assertEquals(RichTextBold(RichTextPlain("x")), buildRichText { bold("x") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rendersMarkdown() {
|
||||
assertEquals("a **b**", buildRichText { plain("a "); bold("b") }.markdown)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun buildsBlocks() {
|
||||
val blocks = buildRichBlocks {
|
||||
heading("Title", 1)
|
||||
paragraph {
|
||||
plain("Hello ")
|
||||
bold("world")
|
||||
}
|
||||
divider()
|
||||
list {
|
||||
item("1", "first")
|
||||
item("2", labelType = "1") { paragraph("second") }
|
||||
}
|
||||
blockQuotation {
|
||||
paragraph("quoted")
|
||||
}
|
||||
}
|
||||
assertEquals(5, blocks.size)
|
||||
assertEquals(RichBlockSectionHeading(RichTextPlain("Title"), 1), blocks[0])
|
||||
assertEquals(
|
||||
RichBlockParagraph(RichTextGroup(listOf(RichTextPlain("Hello "), RichTextBold(RichTextPlain("world"))))),
|
||||
blocks[1]
|
||||
)
|
||||
assertEquals(RichBlockDivider(), blocks[2])
|
||||
val list = blocks[3] as RichBlockList
|
||||
assertEquals(2, list.items.size)
|
||||
assertEquals(RichBlockListItem("1", listOf(RichBlockParagraph(RichTextPlain("first")))), list.items[0])
|
||||
assertEquals(RichBlockBlockQuotation(listOf(RichBlockParagraph(RichTextPlain("quoted")))), blocks[4])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun buildsRichTextInfo() {
|
||||
val info = buildRichTextInfo(isRtl = true) {
|
||||
paragraph("p")
|
||||
}
|
||||
assertEquals(RichTextInfo(listOf(RichBlockParagraph(RichTextPlain("p"))), true), info)
|
||||
assertEquals("p", info.markdown)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package dev.inmo.tgbotapi.types.rich
|
||||
|
||||
import dev.inmo.tgbotapi.types.ChatId
|
||||
import dev.inmo.tgbotapi.types.CustomEmojiId
|
||||
import dev.inmo.tgbotapi.types.RawChatId
|
||||
import dev.inmo.tgbotapi.types.TelegramDate
|
||||
import dev.inmo.tgbotapi.types.chat.CommonUser
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class RichTextFormattingTest {
|
||||
@Test
|
||||
fun bold() {
|
||||
val entity = RichTextBold(RichTextPlain("x"))
|
||||
assertEquals("**x**", entity.markdown)
|
||||
assertEquals("<b>x</b>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun italic() {
|
||||
val entity = RichTextItalic(RichTextPlain("x"))
|
||||
assertEquals("*x*", entity.markdown)
|
||||
assertEquals("<i>x</i>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun underline() {
|
||||
val entity = RichTextUnderline(RichTextPlain("x"))
|
||||
assertEquals("<u>x</u>", entity.markdown)
|
||||
assertEquals("<u>x</u>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun strikethrough() {
|
||||
val entity = RichTextStrikethrough(RichTextPlain("x"))
|
||||
assertEquals("~~x~~", entity.markdown)
|
||||
assertEquals("<s>x</s>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun spoiler() {
|
||||
val entity = RichTextSpoiler(RichTextPlain("x"))
|
||||
assertEquals("||x||", entity.markdown)
|
||||
assertEquals("<tg-spoiler>x</tg-spoiler>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subscript() {
|
||||
val entity = RichTextSubscript(RichTextPlain("x"))
|
||||
assertEquals("<sub>x</sub>", entity.markdown)
|
||||
assertEquals("<sub>x</sub>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun superscript() {
|
||||
val entity = RichTextSuperscript(RichTextPlain("x"))
|
||||
assertEquals("<sup>x</sup>", entity.markdown)
|
||||
assertEquals("<sup>x</sup>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun marked() {
|
||||
val entity = RichTextMarked(RichTextPlain("x"))
|
||||
assertEquals("==x==", entity.markdown)
|
||||
assertEquals("<mark>x</mark>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun code() {
|
||||
val entity = RichTextCode(RichTextPlain("x"))
|
||||
assertEquals("`x`", entity.markdown)
|
||||
assertEquals("<code>x</code>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dateTime() {
|
||||
val entity = RichTextDateTime(RichTextPlain("now"), TelegramDate(1647531900L), "wDT")
|
||||
assertEquals("", entity.markdown)
|
||||
assertEquals("<tg-time unix=\"1647531900\" format=\"wDT\">now</tg-time>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun textMention() {
|
||||
val entity = RichTextTextMention(RichTextPlain("John"), CommonUser(ChatId(RawChatId(12345L)), "John"))
|
||||
assertEquals("[John](tg://user?id=12345)", entity.markdown)
|
||||
assertEquals("<a href=\"tg://user?id=12345\">John</a>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun customEmoji() {
|
||||
val entity = RichTextCustomEmoji(CustomEmojiId("555"), "alt")
|
||||
assertEquals("", entity.markdown)
|
||||
assertEquals("<tg-emoji emoji-id=\"555\">alt</tg-emoji>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mathematicalExpression() {
|
||||
val entity = RichTextMathematicalExpression("x^2")
|
||||
assertEquals("\$x^2\$", entity.markdown)
|
||||
assertEquals("<tg-math>x^2</tg-math>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun url() {
|
||||
val entity = RichTextUrl(RichTextPlain("link"), "https://t.me/")
|
||||
assertEquals("[link](https://t.me/)", entity.markdown)
|
||||
assertEquals("<a href=\"https://t.me/\">link</a>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun emailAddress() {
|
||||
val entity = RichTextEmailAddress(RichTextPlain("mail"), "a@b.com")
|
||||
assertEquals("[mail](mailto:a@b.com)", entity.markdown)
|
||||
assertEquals("<a href=\"mailto:a@b.com\">mail</a>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun phoneNumber() {
|
||||
val entity = RichTextPhoneNumber(RichTextPlain("call"), "+123")
|
||||
assertEquals("[call](tel:+123)", entity.markdown)
|
||||
assertEquals("<a href=\"tel:+123\">call</a>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bankCardNumber() {
|
||||
val entity = RichTextBankCardNumber(RichTextPlain("4242 4242 4242 4242"), "4242424242424242")
|
||||
assertEquals("4242 4242 4242 4242", entity.markdown)
|
||||
assertEquals("4242 4242 4242 4242", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mention() {
|
||||
val entity = RichTextMention(RichTextPlain("@user"), "user")
|
||||
assertEquals("@user", entity.markdown)
|
||||
assertEquals("@user", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hashtag() {
|
||||
val entity = RichTextHashtag(RichTextPlain("#tag"), "tag")
|
||||
assertEquals("\\#tag", entity.markdown)
|
||||
assertEquals("#tag", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun cashtag() {
|
||||
val entity = RichTextCashtag(RichTextPlain("\$USD"), "USD")
|
||||
assertEquals("\\\$USD", entity.markdown)
|
||||
assertEquals("\$USD", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun botCommand() {
|
||||
val entity = RichTextBotCommand(RichTextPlain("/start"), "start")
|
||||
assertEquals("/start", entity.markdown)
|
||||
assertEquals("/start", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anchor() {
|
||||
val entity = RichTextAnchor("top")
|
||||
assertEquals("<a name=\"top\"></a>", entity.markdown)
|
||||
assertEquals("<a name=\"top\"></a>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anchorLink() {
|
||||
val entity = RichTextAnchorLink(RichTextPlain("go"), "top")
|
||||
assertEquals("[go](#top)", entity.markdown)
|
||||
assertEquals("<a href=\"#top\">go</a>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reference() {
|
||||
val entity = RichTextReference(RichTextPlain("ref"), "note1")
|
||||
assertEquals("<tg-reference name=\"note1\">ref</tg-reference>", entity.markdown)
|
||||
assertEquals("<tg-reference name=\"note1\">ref</tg-reference>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun referenceLink() {
|
||||
val entity = RichTextReferenceLink(RichTextPlain("see"), "note1")
|
||||
assertEquals("[see](#note1)", entity.markdown)
|
||||
assertEquals("<a href=\"#note1\">see</a>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nestedGroupRecursesIntoInnerEntities() {
|
||||
val entity = RichTextBold(
|
||||
RichTextGroup(
|
||||
listOf(
|
||||
RichTextPlain("a "),
|
||||
RichTextItalic(RichTextPlain("b"))
|
||||
)
|
||||
)
|
||||
)
|
||||
assertEquals("**a *b***", entity.markdown)
|
||||
assertEquals("<b>a <i>b</i></b>", entity.html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun plainMarkdownEscapesSpecialCharacters() {
|
||||
assertEquals("a\\*b\\_c", RichTextPlain("a*b_c").markdown)
|
||||
assertEquals("\\[x\\]", RichTextPlain("[x]").markdown)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun plainHtmlEscapesAngleBrackets() {
|
||||
assertEquals("a&lt;b", RichTextPlain("a<b").html)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rawTextExtractsPlainText() {
|
||||
assertEquals("x", RichTextBold(RichTextPlain("x")).rawText)
|
||||
assertEquals("alt", RichTextCustomEmoji(CustomEmojiId("1"), "alt").rawText)
|
||||
assertEquals("e", RichTextMathematicalExpression("e").rawText)
|
||||
assertEquals(
|
||||
"a b",
|
||||
RichTextGroup(listOf(RichTextPlain("a "), RichTextBold(RichTextPlain("b")))).rawText
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1906,6 +1906,7 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun ifInputInvoiceMessageContent (Ldev/inmo/tgbotapi/abstracts/CommonSendInvoiceData;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifInputInvoiceMessageContent (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifInputLocationMessageContent (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifInputRichMessageContent (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifInputTextMessageContent (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifInputVenueMessageContent (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifInternal (Ldev/inmo/tgbotapi/types/ReplyInfo;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
@@ -1918,6 +1919,7 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun ifLeftChatMember (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifLeftChatMemberEvent (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifLeftChatMemberEvent (Ldev/inmo/tgbotapi/types/message/ChatEvents/abstracts/ChatEvent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifLink (Ldev/inmo/tgbotapi/types/media/BaseTelegramMediaFile;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifLiveLocation (Ldev/inmo/tgbotapi/types/location/Location;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifLiveLocationContent (Ldev/inmo/tgbotapi/types/message/content/ResendableContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifLivePhotoContent (Ldev/inmo/tgbotapi/types/message/content/ResendableContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
@@ -2081,6 +2083,57 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun ifRequestGuestMessage (Ldev/inmo/tgbotapi/types/message/abstracts/Message;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRestrictedChatMember (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRestrictedMemberChatMember (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockAnchor (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockAnimation (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockAudio (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockBlockQuotation (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockCollage (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockDetails (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockDivider (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockFooter (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockList (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockMap (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockMathematicalExpression (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockMedia (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockParagraph (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockPhoto (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockPreformatted (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockPullQuotation (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockSectionHeading (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockSlideshow (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockTable (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockThinking (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockVideo (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichBlockVoiceNote (Ldev/inmo/tgbotapi/types/rich/RichBlock;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichMessageContent (Ldev/inmo/tgbotapi/types/message/content/ResendableContent;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextAnchor (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextAnchorLink (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextBankCardNumber (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextBold (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextBotCommand (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextCashtag (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextCode (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextCustomEmoji (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextDateTime (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextEmailAddress (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextEntity (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextGroup (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextHashtag (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextItalic (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextMarked (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextMathematicalExpression (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextMention (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextPhoneNumber (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextPlain (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextReference (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextReferenceLink (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextSpoiler (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextStrikethrough (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextSubscript (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextSuperscript (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextTextMention (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextUnderline (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifRichTextUrl (Ldev/inmo/tgbotapi/types/rich/RichText;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifSecondaryChatInviteLink (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifSecureValueIdentity (Ldev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValue;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifSecureValueWithData (Ldev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValue;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
@@ -2142,6 +2195,7 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun ifTelegramMediaDocument (Ldev/inmo/tgbotapi/types/media/InputPollMedia;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifTelegramMediaDocument (Ldev/inmo/tgbotapi/types/media/TelegramMedia;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifTelegramMediaFile (Ldev/inmo/tgbotapi/types/media/BaseTelegramMediaFile;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifTelegramMediaLink (Ldev/inmo/tgbotapi/types/media/InputPollOptionMedia;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifTelegramMediaLivePhoto (Ldev/inmo/tgbotapi/types/media/InputPollMedia;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifTelegramMediaLivePhoto (Ldev/inmo/tgbotapi/types/media/InputPollOptionMedia;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ifTelegramMediaLivePhoto (Ldev/inmo/tgbotapi/types/media/TelegramMedia;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
@@ -2340,6 +2394,8 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun inputInvoiceMessageContentOrThrow (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputInvoiceMessageContent;
|
||||
public static final fun inputLocationMessageContentOrNull (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputLocationMessageContent;
|
||||
public static final fun inputLocationMessageContentOrThrow (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputLocationMessageContent;
|
||||
public static final fun inputRichMessageContentOrNull (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputRichMessageContent;
|
||||
public static final fun inputRichMessageContentOrThrow (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputRichMessageContent;
|
||||
public static final fun inputTextMessageContentOrNull (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputTextMessageContent;
|
||||
public static final fun inputTextMessageContentOrThrow (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputTextMessageContent;
|
||||
public static final fun inputVenueMessageContentOrNull (Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputMessageContent;)Ldev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputVenueMessageContent;
|
||||
@@ -2364,6 +2420,8 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun leftChatMemberEventOrThrow (Ldev/inmo/tgbotapi/types/message/ChatEvents/abstracts/ChatEvent;)Ldev/inmo/tgbotapi/types/message/ChatEvents/LeftChatMemberEvent;
|
||||
public static final fun leftChatMemberOrNull (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;)Ldev/inmo/tgbotapi/types/chat/member/LeftChatMember;
|
||||
public static final fun leftChatMemberOrThrow (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;)Ldev/inmo/tgbotapi/types/chat/member/LeftChatMember;
|
||||
public static final fun linkOrNull (Ldev/inmo/tgbotapi/types/media/BaseTelegramMediaFile;)Ldev/inmo/tgbotapi/types/Link;
|
||||
public static final fun linkOrThrow (Ldev/inmo/tgbotapi/types/media/BaseTelegramMediaFile;)Ldev/inmo/tgbotapi/types/Link;
|
||||
public static final fun liveLocationContentOrNull (Ldev/inmo/tgbotapi/types/message/content/ResendableContent;)Ldev/inmo/tgbotapi/types/message/content/LiveLocationContent;
|
||||
public static final fun liveLocationContentOrThrow (Ldev/inmo/tgbotapi/types/message/content/ResendableContent;)Ldev/inmo/tgbotapi/types/message/content/LiveLocationContent;
|
||||
public static final fun liveLocationOrNull (Ldev/inmo/tgbotapi/types/location/Location;)Ldev/inmo/tgbotapi/types/location/LiveLocation;
|
||||
@@ -2690,6 +2748,108 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun restrictedChatMemberOrThrow (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;)Ldev/inmo/tgbotapi/types/chat/member/RestrictedChatMember;
|
||||
public static final fun restrictedMemberChatMemberOrNull (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;)Ldev/inmo/tgbotapi/types/chat/member/RestrictedMemberChatMember;
|
||||
public static final fun restrictedMemberChatMemberOrThrow (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;)Ldev/inmo/tgbotapi/types/chat/member/RestrictedMemberChatMember;
|
||||
public static final fun richBlockAnchorOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockAnchor;
|
||||
public static final fun richBlockAnchorOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockAnchor;
|
||||
public static final fun richBlockAnimationOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockAnimation;
|
||||
public static final fun richBlockAnimationOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockAnimation;
|
||||
public static final fun richBlockAudioOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockAudio;
|
||||
public static final fun richBlockAudioOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockAudio;
|
||||
public static final fun richBlockBlockQuotationOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockBlockQuotation;
|
||||
public static final fun richBlockBlockQuotationOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockBlockQuotation;
|
||||
public static final fun richBlockCollageOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockCollage;
|
||||
public static final fun richBlockCollageOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockCollage;
|
||||
public static final fun richBlockDetailsOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockDetails;
|
||||
public static final fun richBlockDetailsOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockDetails;
|
||||
public static final fun richBlockDividerOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockDivider;
|
||||
public static final fun richBlockDividerOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockDivider;
|
||||
public static final fun richBlockFooterOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockFooter;
|
||||
public static final fun richBlockFooterOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockFooter;
|
||||
public static final fun richBlockListOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockList;
|
||||
public static final fun richBlockListOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockList;
|
||||
public static final fun richBlockMapOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockMap;
|
||||
public static final fun richBlockMapOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockMap;
|
||||
public static final fun richBlockMathematicalExpressionOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockMathematicalExpression;
|
||||
public static final fun richBlockMathematicalExpressionOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockMathematicalExpression;
|
||||
public static final fun richBlockMediaOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockMedia;
|
||||
public static final fun richBlockMediaOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockMedia;
|
||||
public static final fun richBlockParagraphOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockParagraph;
|
||||
public static final fun richBlockParagraphOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockParagraph;
|
||||
public static final fun richBlockPhotoOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockPhoto;
|
||||
public static final fun richBlockPhotoOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockPhoto;
|
||||
public static final fun richBlockPreformattedOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockPreformatted;
|
||||
public static final fun richBlockPreformattedOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockPreformatted;
|
||||
public static final fun richBlockPullQuotationOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockPullQuotation;
|
||||
public static final fun richBlockPullQuotationOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockPullQuotation;
|
||||
public static final fun richBlockSectionHeadingOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockSectionHeading;
|
||||
public static final fun richBlockSectionHeadingOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockSectionHeading;
|
||||
public static final fun richBlockSlideshowOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockSlideshow;
|
||||
public static final fun richBlockSlideshowOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockSlideshow;
|
||||
public static final fun richBlockTableOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockTable;
|
||||
public static final fun richBlockTableOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockTable;
|
||||
public static final fun richBlockThinkingOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockThinking;
|
||||
public static final fun richBlockThinkingOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockThinking;
|
||||
public static final fun richBlockVideoOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockVideo;
|
||||
public static final fun richBlockVideoOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockVideo;
|
||||
public static final fun richBlockVoiceNoteOrNull (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockVoiceNote;
|
||||
public static final fun richBlockVoiceNoteOrThrow (Ldev/inmo/tgbotapi/types/rich/RichBlock;)Ldev/inmo/tgbotapi/types/rich/RichBlockVoiceNote;
|
||||
public static final fun richMessageContentOrNull (Ldev/inmo/tgbotapi/types/message/content/ResendableContent;)Ldev/inmo/tgbotapi/types/message/content/RichMessageContent;
|
||||
public static final fun richMessageContentOrThrow (Ldev/inmo/tgbotapi/types/message/content/ResendableContent;)Ldev/inmo/tgbotapi/types/message/content/RichMessageContent;
|
||||
public static final fun richTextAnchorLinkOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextAnchorLink;
|
||||
public static final fun richTextAnchorLinkOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextAnchorLink;
|
||||
public static final fun richTextAnchorOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextAnchor;
|
||||
public static final fun richTextAnchorOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextAnchor;
|
||||
public static final fun richTextBankCardNumberOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextBankCardNumber;
|
||||
public static final fun richTextBankCardNumberOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextBankCardNumber;
|
||||
public static final fun richTextBoldOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextBold;
|
||||
public static final fun richTextBoldOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextBold;
|
||||
public static final fun richTextBotCommandOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextBotCommand;
|
||||
public static final fun richTextBotCommandOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextBotCommand;
|
||||
public static final fun richTextCashtagOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextCashtag;
|
||||
public static final fun richTextCashtagOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextCashtag;
|
||||
public static final fun richTextCodeOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextCode;
|
||||
public static final fun richTextCodeOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextCode;
|
||||
public static final fun richTextCustomEmojiOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextCustomEmoji;
|
||||
public static final fun richTextCustomEmojiOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextCustomEmoji;
|
||||
public static final fun richTextDateTimeOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextDateTime;
|
||||
public static final fun richTextDateTimeOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextDateTime;
|
||||
public static final fun richTextEmailAddressOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextEmailAddress;
|
||||
public static final fun richTextEmailAddressOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextEmailAddress;
|
||||
public static final fun richTextEntityOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextEntity;
|
||||
public static final fun richTextEntityOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextEntity;
|
||||
public static final fun richTextGroupOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextGroup;
|
||||
public static final fun richTextGroupOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextGroup;
|
||||
public static final fun richTextHashtagOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextHashtag;
|
||||
public static final fun richTextHashtagOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextHashtag;
|
||||
public static final fun richTextItalicOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextItalic;
|
||||
public static final fun richTextItalicOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextItalic;
|
||||
public static final fun richTextMarkedOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextMarked;
|
||||
public static final fun richTextMarkedOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextMarked;
|
||||
public static final fun richTextMathematicalExpressionOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextMathematicalExpression;
|
||||
public static final fun richTextMathematicalExpressionOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextMathematicalExpression;
|
||||
public static final fun richTextMentionOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextMention;
|
||||
public static final fun richTextMentionOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextMention;
|
||||
public static final fun richTextPhoneNumberOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextPhoneNumber;
|
||||
public static final fun richTextPhoneNumberOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextPhoneNumber;
|
||||
public static final fun richTextPlainOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextPlain;
|
||||
public static final fun richTextPlainOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextPlain;
|
||||
public static final fun richTextReferenceLinkOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextReferenceLink;
|
||||
public static final fun richTextReferenceLinkOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextReferenceLink;
|
||||
public static final fun richTextReferenceOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextReference;
|
||||
public static final fun richTextReferenceOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextReference;
|
||||
public static final fun richTextSpoilerOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSpoiler;
|
||||
public static final fun richTextSpoilerOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSpoiler;
|
||||
public static final fun richTextStrikethroughOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextStrikethrough;
|
||||
public static final fun richTextStrikethroughOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextStrikethrough;
|
||||
public static final fun richTextSubscriptOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSubscript;
|
||||
public static final fun richTextSubscriptOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSubscript;
|
||||
public static final fun richTextSuperscriptOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSuperscript;
|
||||
public static final fun richTextSuperscriptOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSuperscript;
|
||||
public static final fun richTextTextMentionOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextTextMention;
|
||||
public static final fun richTextTextMentionOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextTextMention;
|
||||
public static final fun richTextUnderlineOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextUnderline;
|
||||
public static final fun richTextUnderlineOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextUnderline;
|
||||
public static final fun richTextUrlOrNull (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextUrl;
|
||||
public static final fun richTextUrlOrThrow (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextUrl;
|
||||
public static final fun secondaryChatInviteLinkOrNull (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;)Ldev/inmo/tgbotapi/types/SecondaryChatInviteLink;
|
||||
public static final fun secondaryChatInviteLinkOrThrow (Ldev/inmo/tgbotapi/abstracts/OptionallyWithUser;)Ldev/inmo/tgbotapi/types/SecondaryChatInviteLink;
|
||||
public static final fun secureValueIdentityOrNull (Ldev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValue;)Ldev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueIdentity;
|
||||
@@ -2812,6 +2972,8 @@ public final class dev/inmo/tgbotapi/extensions/utils/ClassCastsNewKt {
|
||||
public static final fun telegramMediaDocumentOrThrow (Ldev/inmo/tgbotapi/types/media/TelegramMedia;)Ldev/inmo/tgbotapi/types/media/TelegramMediaDocument;
|
||||
public static final fun telegramMediaFileOrNull (Ldev/inmo/tgbotapi/types/media/BaseTelegramMediaFile;)Ldev/inmo/tgbotapi/types/files/TelegramMediaFile;
|
||||
public static final fun telegramMediaFileOrThrow (Ldev/inmo/tgbotapi/types/media/BaseTelegramMediaFile;)Ldev/inmo/tgbotapi/types/files/TelegramMediaFile;
|
||||
public static final fun telegramMediaLinkOrNull (Ldev/inmo/tgbotapi/types/media/InputPollOptionMedia;)Ldev/inmo/tgbotapi/types/media/TelegramMediaLink;
|
||||
public static final fun telegramMediaLinkOrThrow (Ldev/inmo/tgbotapi/types/media/InputPollOptionMedia;)Ldev/inmo/tgbotapi/types/media/TelegramMediaLink;
|
||||
public static final fun telegramMediaLivePhotoOrNull (Ldev/inmo/tgbotapi/types/media/InputPollMedia;)Ldev/inmo/tgbotapi/types/media/TelegramMediaLivePhoto;
|
||||
public static final fun telegramMediaLivePhotoOrNull (Ldev/inmo/tgbotapi/types/media/InputPollOptionMedia;)Ldev/inmo/tgbotapi/types/media/TelegramMediaLivePhoto;
|
||||
public static final fun telegramMediaLivePhotoOrNull (Ldev/inmo/tgbotapi/types/media/TelegramMedia;)Ldev/inmo/tgbotapi/types/media/TelegramMediaLivePhoto;
|
||||
@@ -3062,6 +3224,7 @@ public final class dev/inmo/tgbotapi/extensions/utils/ContentMessageConversation
|
||||
public static final fun onlyLocationContentMessages (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun onlyPhotoContentMessages (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun onlyPollContentMessages (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun onlyRichMessageContentMessages (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun onlyStickerContentMessages (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun onlyStoryContentMessages (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun onlyTextContentMessages (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||
@@ -3255,6 +3418,7 @@ public final class dev/inmo/tgbotapi/extensions/utils/extensions/raw/CallbackQue
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/utils/extensions/raw/ChatJoinRequestKt {
|
||||
public static final fun getInvite_link (Ldev/inmo/tgbotapi/types/chat/ChatJoinRequest;)Ldev/inmo/tgbotapi/types/ChatInviteLink;
|
||||
public static final fun getQuery_id (Ldev/inmo/tgbotapi/types/chat/ChatJoinRequest;)Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class dev/inmo/tgbotapi/extensions/utils/extensions/raw/ChatMemberUpdatedKt {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@ fun Flow<ContentMessage<*>>.onlyPollContentMessages() = withContentType<PollCont
|
||||
fun Flow<ContentMessage<*>>.onlyStickerContentMessages() = withContentType<StickerContent>()
|
||||
fun Flow<ContentMessage<*>>.onlyTextContentMessages() = withContentType<TextContent>()
|
||||
fun Flow<ContentMessage<*>>.onlyStoryContentMessages() = withContentType<StoryContent>()
|
||||
fun Flow<ContentMessage<*>>.onlyRichMessageContentMessages() = withContentType<RichMessageContent>()
|
||||
fun Flow<ContentMessage<*>>.onlyVenueContentMessages() = withContentType<VenueContent>()
|
||||
fun Flow<ContentMessage<*>>.onlyVideoContentMessages() = withContentType<VideoContent>()
|
||||
fun Flow<ContentMessage<*>>.onlyLivePhotoContentMessages() = withContentType<LivePhotoContent>()
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.extensions.raw
|
||||
|
||||
import dev.inmo.tgbotapi.types.ChatInviteLink
|
||||
import dev.inmo.tgbotapi.types.ChatJoinRequestQueryId
|
||||
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
|
||||
@RiskFeature(RawFieldsUsageWarning)
|
||||
val ChatJoinRequest.invite_link: ChatInviteLink?
|
||||
get() = inviteLink
|
||||
|
||||
@RiskFeature(RawFieldsUsageWarning)
|
||||
val ChatJoinRequest.query_id: ChatJoinRequestQueryId?
|
||||
get() = queryId
|
||||
|
||||
Reference in New Issue
Block a user