Compare commits

..

9 Commits

Author SHA1 Message Date
a547bbce65 Merge branch 'master' into 0.38.16 2022-04-30 08:39:01 +06:00
0b7d8c087f update tgbotapi and add webapps example 2022-04-29 20:57:16 +06:00
8ec282e3d5 Merge pull request #96 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.15
2022-04-26 15:48:10 +06:00
Renovate Bot
e8433cd8ac Update dependency dev.inmo:tgbotapi to v0.38.15 2022-04-26 09:46:32 +00:00
222134836a update up to 0.38.13 2022-04-17 00:26:04 +06:00
c18e02dcb3 Merge pull request #94 from InsanusMokrassar/0.38.12
Add keyboards and update tgbotapi up to 0.38.12
2022-04-16 23:52:43 +06:00
f9050061d1 add keyboards and update tgbotapi up to 0.38.12 2022-04-09 12:20:35 +06:00
a3e3f6c22c Update gradle.properties 2022-03-30 07:54:57 +06:00
516cc7bfcb Merge pull request #89 from InsanusMokrassar/0.38.10
Update up to 0.38.10
2022-03-25 21:26:18 +06:00
23 changed files with 416 additions and 14 deletions

View File

@@ -26,7 +26,9 @@ suspend fun main(args: Array<String>) {
}
)
val content = waitContentMessage().first()
val contentMessage = waitContentMessage().first()
val content = contentMessage.content
when {
content is TextContent && content.parseCommandsWithParams().keys.contains("stop") -> StopState(it.context)
else -> {

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

View File

@@ -0,0 +1,32 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
}
kotlin {
jvm()
js(IR) {
browser()
binaries.executable()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "dev.inmo:tgbotapi:$telegram_bot_api_version"
}
}
}
}

View File

@@ -0,0 +1,107 @@
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.answers.answer
import dev.inmo.tgbotapi.extensions.api.edit.text.editMessageText
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.send.media.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.shortcuts.*
import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.types.message.content.TextContent
import kotlinx.coroutines.*
private const val nextPageData = "next"
private const val previousPageData = "previous"
fun String.parsePageAndCount(): Pair<Int, Int>? {
val (pageString, countString) = split(" ").takeIf { it.count() > 1 } ?: return null
return Pair(
pageString.toIntOrNull() ?: return null,
countString.toIntOrNull() ?: return null
)
}
fun InlineKeyboardBuilder.includePageButtons(page: Int, count: Int) {
val numericButtons = listOfNotNull(
page - 1,
page,
page + 1,
)
row {
val numbersRange = 1 .. count
numericButtons.forEach {
if (it in numbersRange) {
dataButton(it.toString(), "$it $count")
}
}
}
row {
if (page - 1 > 2) {
dataButton("<<", "1 $count")
}
if (page - 1 > 1) {
dataButton("<", "${page - 2} $count")
}
if (page + 1 < count) {
dataButton(">", "${page + 2} $count")
}
if (page + 2 < count) {
dataButton(">>", "$count $count")
}
}
}
suspend fun activateKeyboardsBot(
token: String,
print: (Any) -> Unit
) {
val bot = telegramBot(token)
print(bot.getMe())
bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
onCommandWithArgs("inline") { message, args ->
val numberOfPages = args.firstOrNull() ?.toIntOrNull() ?: 10
reply(
message,
"Your inline keyboard with $numberOfPages pages",
replyMarkup = inlineKeyboard {
row {
includePageButtons(1, numberOfPages)
}
}
)
}
onMessageDataCallbackQuery {
val (page, count) = it.data.parsePageAndCount() ?: it.let {
answer(it, "Unsupported data :(")
return@onMessageDataCallbackQuery
}
editMessageText(
it.message.withContent<TextContent>() ?: it.let {
answer(it, "Unsupported message type :(")
return@onMessageDataCallbackQuery
},
"This is $page of $count",
replyMarkup = inlineKeyboard {
row {
includePageButtons(page, count)
}
}
)
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
}.join()
}

View File

@@ -0,0 +1,32 @@
import kotlinx.browser.document
import kotlinx.coroutines.*
import org.w3c.dom.*
private val scope = CoroutineScope(Dispatchers.Default)
fun main() {
document.addEventListener(
"DOMContentLoaded",
{
val botsContainer = document.getElementById("bots_container") ?: return@addEventListener
(document.getElementById("bot_token_form") as? HTMLFormElement) ?.onsubmit = {
(document.getElementById("bot_token") as? HTMLInputElement) ?.value ?.let { token ->
val botContainer = document.createElement("div") as HTMLDivElement
botsContainer.append(botContainer)
val infoDiv = document.createElement("div") as HTMLDivElement
botContainer.append(infoDiv)
scope.launch {
activateKeyboardsBot(token) {
infoDiv.innerHTML = it.toString()
}
}
}
false
}
}
)
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Keyboards bot</title>
</head>
<body>
<form id="bot_token_form">
<input type="text" id="bot_token">
<input type="submit" value="Start bot">
</form>
<div id="start_offer">Type your bot token to the input above to start its work</div>
<script type="text/javascript" src="KeyboardsBotLib.js"></script>
<div id="bots_container"></div>
</body>
</html>

View File

@@ -0,0 +1,21 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="KeyboardsBotJvmKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(":KeyboardsBot:KeyboardsBotLib")
}

View File

@@ -0,0 +1,10 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
suspend fun main(args: Array<String>) {
withContext(Dispatchers.IO) { // IO for inheriting of it in side of activateKeyboardsBot
activateKeyboardsBot(args.first()) {
println(it)
}
}
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {

55
WebApp/build.gradle Normal file
View File

@@ -0,0 +1,55 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
}
apply plugin: 'application'
kotlin {
jvm()
js(IR) {
browser()
binaries.executable()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
}
}
jsMain {
dependencies {
implementation "dev.inmo:tgbotapi.webapps:$telegram_bot_api_version"
}
}
jvmMain {
dependencies {
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
implementation "dev.inmo:micro_utils.ktor.server:$micro_utils_version"
implementation "io.ktor:ktor-server-tomcat:$ktor_version"
}
}
}
}
application {
mainClassName = "WebAppServerKt"
}
tasks.getByName("compileKotlinJvm")
.dependsOn(jsBrowserDistribution)
tasks.getByName("compileKotlinJvm").configure {
mustRunAfter jsBrowserDistribution
}

View File

@@ -0,0 +1,42 @@
import dev.inmo.tgbotapi.webapps.*
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.readText
import io.ktor.http.encodeURLPath
import kotlinx.browser.document
import kotlinx.browser.window
import kotlinx.coroutines.*
import kotlinx.dom.appendElement
import kotlinx.dom.appendText
fun main() {
console.log("Web app started")
window.onload = {
val scope = CoroutineScope(Dispatchers.Default)
runCatching {
document.body ?.appendElement("button") {
addEventListener(
"click",
{
webApp.sendData("Clicked")
}
)
appendText("Example button")
} ?: window.alert("Unable to load body")
webApp.apply {
onThemeChanged {
document.body ?.appendText("Theme changed: ${webApp.themeParams}")
document.body ?.appendElement("p", {})
}
onViewportChanged {
document.body ?.appendText("Viewport changed: ${it.isStateStable}")
document.body ?.appendElement("p", {})
}
}
webApp.ready()
}.onFailure {
window.alert(it.stackTraceToString())
}
}
}

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Web App Example</title>
</head>
<body>
<script type="application/javascript" src="https://telegram.org/js/telegram-web-app.js"></script>
<script type="application/javascript" src="WebApp.js"></script>
</body>
</html>

View File

@@ -0,0 +1,61 @@
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.ktor.server.createKtorServer
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
import io.ktor.application.call
import io.ktor.http.content.files
import io.ktor.http.content.static
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.tomcat.Tomcat
import kotlinx.coroutines.Dispatchers
import java.io.File
/**
* Accepts two parameters:
*
* * Telegram Token
* * URL where will be placed
*
* Will start the server to share the static (index.html and WebApp.js) on 0.0.0.0:8080
*/
suspend fun main(vararg args: String) {
createKtorServer(
Tomcat,
"0.0.0.0",
8080,
additionalEngineEnvironmentConfigurator = {
parentCoroutineContext += Dispatchers.IO
}
) {
routing {
static {
files(File("WebApp/build/distributions"))
}
}
}.start(false)
telegramBotWithBehaviourAndLongPolling(
args.first(),
defaultExceptionsHandler = { it.printStackTrace() }
) {
onCommand("start") {
reply(
it,
"Button:",
replyMarkup = inlineKeyboard {
row {
webAppButton("Open", args[1])
}
}
)
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
println(getMe())
}.second.join()
}

View File

@@ -1,7 +1,7 @@
allprojects {
repositories {
mavenLocal()
jcenter()
mavenCentral()
if (project.hasProperty("GITHUB_USER") && project.hasProperty("GITHUB_TOKEN")) {
maven {
url "https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"
@@ -12,4 +12,4 @@ allprojects {
}
}
}
}
}

View File

@@ -3,5 +3,6 @@ org.gradle.parallel=true
kotlin_version=1.6.10
telegram_bot_api_version=0.38.10
micro_utils_version=0.9.16
telegram_bot_api_version=0.38.16
micro_utils_version=0.9.24
ktor_version=1.6.8

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip

View File

@@ -1,9 +1,21 @@
include ":ForwardInfoSenderBot"
include ":RandomFileSenderBot"
include ":HelloBot"
include ":GetMeBot"
include ":FilesLoaderBot"
include ":ResenderBot:ResenderBotLib"
include ":ResenderBot:jvm_launcher"
include ":KeyboardsBot:KeyboardsBotLib"
include ":KeyboardsBot:jvm_launcher"
include ":SlotMachineDetectorBot"
include ":WebApp"
include ":FSMBot"