Compare commits

...

15 Commits

14 changed files with 378 additions and 47 deletions

View File

@@ -16,4 +16,4 @@ jobs:
with: with:
java-version: 17 java-version: 17
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew build run: ./gradlew build --no-daemon

9
CustomBot/README.md Normal file
View File

@@ -0,0 +1,9 @@
# CustomBot
This bot basically have no any useful behaviour, but you may customize it as a playground
## Launch
```bash
../gradlew run --args="BOT_TOKEN"
```

21
CustomBot/build.gradle Normal file
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="CustomBotKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,33 @@
import dev.inmo.kslog.common.KSLog
import dev.inmo.kslog.common.LogLevel
import dev.inmo.kslog.common.defaultMessageFormatter
import dev.inmo.kslog.common.setDefaultKSLog
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.utils.PreviewFeature
import kotlinx.coroutines.*
/**
* The main purpose of this bot is just to answer "Oh, hi, " and add user mention here
*/
@OptIn(PreviewFeature::class)
suspend fun main(vararg args: String) {
val botToken = args.first()
val isDebug = args.any { it == "debug" }
if (isDebug) {
setDefaultKSLog(
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
println(defaultMessageFormatter(level, tag, message, throwable))
}
)
}
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
val me = getMe()
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) }
}.second.join()
}

View File

@@ -1,33 +1,16 @@
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.EditLiveLocationInfo import dev.inmo.tgbotapi.extensions.api.EditLiveLocationInfo
import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
import dev.inmo.tgbotapi.extensions.api.edit.edit
import dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation import dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation
import dev.inmo.tgbotapi.extensions.api.handleLiveLocation import dev.inmo.tgbotapi.extensions.api.handleLiveLocation
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitMessageDataCallbackQuery import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitMessageDataCallbackQuery
import dev.inmo.tgbotapi.extensions.behaviour_builder.oneOf
import dev.inmo.tgbotapi.extensions.behaviour_builder.parallel
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage
import dev.inmo.tgbotapi.extensions.utils.formatting.linkMarkdownV2
import dev.inmo.tgbotapi.extensions.utils.formatting.textMentionMarkdownV2
import dev.inmo.tgbotapi.extensions.utils.ifFromChannelGroupContentMessage
import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton
import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard
import dev.inmo.tgbotapi.types.chat.*
import dev.inmo.tgbotapi.types.chat.GroupChat
import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.chat.SupergroupChat
import dev.inmo.tgbotapi.types.location.LiveLocation import dev.inmo.tgbotapi.types.location.LiveLocation
import dev.inmo.tgbotapi.types.message.MarkdownV2
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.LiveLocationContent
import dev.inmo.tgbotapi.types.message.content.LocationContent import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.utils.PreviewFeature
import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Common
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.FlowCollector import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -64,7 +47,7 @@ suspend fun main(vararg args: String) {
handleLiveLocation( handleLiveLocation(
it.chat.id, it.chat.id,
locationsFlow, locationsFlow,
sentMessageFlow = FlowCollector { currentMessageState.emit(it) } sentMessageFlow = FlowCollector { currentMessageState.emit(it) },
) )
} }

View File

@@ -1,11 +1,19 @@
import com.benasher44.uuid.uuid4 import com.benasher44.uuid.uuid4
import dev.inmo.kslog.common.KSLog
import dev.inmo.kslog.common.LogLevel
import dev.inmo.kslog.common.defaultMessageFormatter
import dev.inmo.kslog.common.setDefaultKSLog
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.getMe import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.api.chat.get.getChat import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
import dev.inmo.tgbotapi.extensions.api.send.* import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.send.polls.sendQuizPoll
import dev.inmo.tgbotapi.extensions.api.send.polls.sendRegularPoll import dev.inmo.tgbotapi.extensions.api.send.polls.sendRegularPoll
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.* import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.customEmojiTextSourceOrNull
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgsSources
import dev.inmo.tgbotapi.extensions.utils.extensions.raw.sender_chat import dev.inmo.tgbotapi.extensions.utils.extensions.raw.sender_chat
import dev.inmo.tgbotapi.extensions.utils.formatting.linkMarkdownV2 import dev.inmo.tgbotapi.extensions.utils.formatting.linkMarkdownV2
import dev.inmo.tgbotapi.extensions.utils.formatting.textMentionMarkdownV2 import dev.inmo.tgbotapi.extensions.utils.formatting.textMentionMarkdownV2
@@ -17,15 +25,13 @@ import dev.inmo.tgbotapi.types.chat.GroupChat
import dev.inmo.tgbotapi.types.chat.PrivateChat import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.chat.SupergroupChat import dev.inmo.tgbotapi.types.chat.SupergroupChat
import dev.inmo.tgbotapi.types.message.MarkdownV2 import dev.inmo.tgbotapi.types.message.MarkdownV2
import dev.inmo.tgbotapi.types.polls.Poll import dev.inmo.tgbotapi.types.polls.*
import dev.inmo.tgbotapi.types.polls.PollAnswer import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.types.polls.PollOption
import dev.inmo.tgbotapi.types.polls.RegularPoll
import dev.inmo.tgbotapi.utils.PreviewFeature
import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Common import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Common
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlin.random.Random
/** /**
* This bot will answer with anonymous or public poll and send message on * This bot will answer with anonymous or public poll and send message on
@@ -37,6 +43,15 @@ import kotlinx.coroutines.sync.withLock
@OptIn(PreviewFeature::class) @OptIn(PreviewFeature::class)
suspend fun main(vararg args: String) { suspend fun main(vararg args: String) {
val botToken = args.first() val botToken = args.first()
val isDebug = args.any { it == "debug" }
if (isDebug) {
setDefaultKSLog(
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
println(defaultMessageFormatter(level, tag, message, throwable))
}
)
}
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) { telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
val me = getMe() val me = getMe()
@@ -44,12 +59,27 @@ suspend fun main(vararg args: String) {
val pollToChat = mutableMapOf<PollId, IdChatIdentifier>() val pollToChat = mutableMapOf<PollId, IdChatIdentifier>()
val pollToChatMutex = Mutex() val pollToChatMutex = Mutex()
onCommand("anonymous") { onCommand("anonymous", requireOnlyCommandInMessage = false) {
val customEmoji = it.content.parseCommandsWithArgsSources()
.toList()
.firstOrNull { it.first.command == "anonymous" }
?.second
?.firstNotNullOfOrNull { it.customEmojiTextSourceOrNull() }
val sentPoll = sendRegularPoll( val sentPoll = sendRegularPoll(
it.chat, it.chat.id,
"Test regular anonymous poll", buildEntities {
regular("Test regular anonymous poll")
if (customEmoji != null) {
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
}
},
(1 .. 10).map { (1 .. 10).map {
it.toString() InputPollOption {
regular(it.toString()) + " "
if (customEmoji != null) {
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
}
}
}, },
isAnonymous = true, isAnonymous = true,
replyParameters = ReplyParameters(it) replyParameters = ReplyParameters(it)
@@ -59,12 +89,27 @@ suspend fun main(vararg args: String) {
} }
} }
onCommand("public") { onCommand("public", requireOnlyCommandInMessage = false) {
val customEmoji = it.content.parseCommandsWithArgsSources()
.toList()
.firstOrNull { it.first.command == "public" }
?.second
?.firstNotNullOfOrNull { it.customEmojiTextSourceOrNull() }
val sentPoll = sendRegularPoll( val sentPoll = sendRegularPoll(
it.chat, it.chat.id,
"Test regular anonymous poll", buildEntities {
regular("Test regular non anonymous poll")
if (customEmoji != null) {
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
}
},
(1 .. 10).map { (1 .. 10).map {
it.toString() InputPollOption {
regular(it.toString()) + " "
if (customEmoji != null) {
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
}
}
}, },
isAnonymous = false, isAnonymous = false,
replyParameters = ReplyParameters(it) replyParameters = ReplyParameters(it)
@@ -74,6 +119,44 @@ suspend fun main(vararg args: String) {
} }
} }
onCommand("quiz", requireOnlyCommandInMessage = false) {
val customEmoji = it.content.parseCommandsWithArgsSources()
.toList()
.firstOrNull { it.first.command == "quiz" }
?.second
?.firstNotNullOfOrNull { it.customEmojiTextSourceOrNull() }
val correctAnswer = Random.nextInt(10)
val sentPoll = sendQuizPoll(
it.chat.id,
questionEntities = buildEntities {
regular("Test quiz poll")
if (customEmoji != null) {
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
}
},
(1 .. 10).map {
InputPollOption {
regular(it.toString()) + " "
if (customEmoji != null) {
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
}
}
},
isAnonymous = false,
replyParameters = ReplyParameters(it),
correctOptionId = correctAnswer,
explanationTextSources = buildEntities {
regular("Random solved it to be ") + underline((correctAnswer + 1).toString()) + " "
if (customEmoji != null) {
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
}
}
)
pollToChatMutex.withLock {
pollToChat[sentPoll.content.poll.id] = sentPoll.chat.id
}
}
onPollAnswer { onPollAnswer {
val chatId = pollToChat[it.pollId] ?: return@onPollAnswer val chatId = pollToChat[it.pollId] ?: return@onPollAnswer
@@ -92,6 +175,12 @@ suspend fun main(vararg args: String) {
} }
} }
setMyCommands(
BotCommand("anonymous", "Create anonymous regular poll"),
BotCommand("public", "Create non anonymous regular poll"),
BotCommand("quiz", "Create quiz poll with random right answer"),
)
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) } allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) }
}.second.join() }.second.join()
} }

View File

@@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups 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.filters.MessageFilterByChat
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.* import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.possiblyWithEffectMessageOrNull
import dev.inmo.tgbotapi.extensions.utils.shortcuts.* import dev.inmo.tgbotapi.extensions.utils.shortcuts.*
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
import dev.inmo.tgbotapi.types.ReplyParameters import dev.inmo.tgbotapi.types.ReplyParameters
@@ -39,7 +40,8 @@ suspend fun activateResenderBot(
entities = quote ?.textSources ?: emptyList(), entities = quote ?.textSources ?: emptyList(),
quotePosition = quote ?.position quotePosition = quote ?.position
) )
} },
effectId = it.possiblyWithEffectMessageOrNull() ?.effectId
) )
) { ) {
it.forEach(print) it.forEach(print)

View File

@@ -0,0 +1,9 @@
# CustomBot
This bot basically have no any useful behaviour, but you may customize it as a playground
## Launch
```bash
../gradlew run --args="BOT_TOKEN"
```

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="StarTransactionsBotKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,131 @@
import dev.inmo.kslog.common.KSLog
import dev.inmo.kslog.common.LogLevel
import dev.inmo.kslog.common.defaultMessageFormatter
import dev.inmo.kslog.common.setDefaultKSLog
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.answers.answer
import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryOk
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.edit.edit
import dev.inmo.tgbotapi.extensions.api.get.getStarTransactions
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.command
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onMessageDataCallbackQuery
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPreCheckoutQuery
import dev.inmo.tgbotapi.extensions.utils.extensions.sameChat
import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton
import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard
import dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard
import dev.inmo.tgbotapi.extensions.utils.types.buttons.payButton
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
import dev.inmo.tgbotapi.types.RawChatId
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
import dev.inmo.tgbotapi.types.payments.LabeledPrice
import dev.inmo.tgbotapi.types.payments.stars.StarTransaction
import dev.inmo.tgbotapi.utils.*
import kotlinx.coroutines.*
/**
* The main purpose of this bot is just to answer "Oh, hi, " and add user mention here
*/
@OptIn(PreviewFeature::class)
suspend fun main(vararg args: String) {
val botToken = args.first()
val adminUserId = args.getOrNull(1) ?.toLongOrNull() ?.let(::RawChatId) ?.let(::UserId) ?: error("Pass user-admin for full access to the bot")
val isDebug = args.any { it == "debug" }
val isTestServer = args.any { it == "testServer" }
if (isDebug) {
setDefaultKSLog(
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
println(defaultMessageFormatter(level, tag, message, throwable))
}
)
}
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO), testServer = isTestServer) {
val me = getMe()
val payload = "sample payload"
command("start") {
reply(
it,
price = LabeledPrice("1", 1L),
title = "Sample",
description = "Sample description",
payload = payload,
replyMarkup = flatInlineKeyboard {
payButton("Pay")
},
)
}
onPreCheckoutQuery(initialFilter = { it.invoicePayload == payload }) {
answerPreCheckoutQueryOk(it)
}
val transactionsDataPrefix = "getStarTransactions"
fun buildTransactionsData(offset: Int, limit: Int = 10) = "$transactionsDataPrefix $offset $limit"
fun parseTransactionsData(data: String): Pair<Int, Int> = data.split(" ").drop(1).let {
it.first().toInt() to it.last().toInt()
}
suspend fun buildStarTransactionsPage(offset: Int, limit: Int = 10): Pair<TextSourcesList, InlineKeyboardMarkup> {
val transactions = getStarTransactions(offset, limit)
return buildEntities {
transactions.transactions.forEach {
regular("Transaction Id: ") + bold(it.id.string) + "\n"
regular("Date: ") + bold(it.date.asDate.toStringDefault()) + "\n"
regular("Amount: ") + bold(it.amount.toString()) + "\n"
when (it) {
is StarTransaction.Incoming -> {
regular("Type: ") + bold("incoming") + "\n"
regular("Partner: ") + bold(it.partner.type) + "\n"
}
is StarTransaction.Outgoing -> {
regular("Type: ") + bold("outgoing") + "\n"
regular("Partner: ") + bold(it.partner.type) + "\n"
}
is StarTransaction.Unknown -> {
regular("Type: ") + bold("unknown") + "\n"
regular("Partner: ") + bold(it.partner.type) + "\n"
}
}
}
} to inlineKeyboard {
row {
val prevOffset = (offset - limit).coerceAtLeast(0)
if (prevOffset < offset) {
dataButton("<", buildTransactionsData(prevOffset, limit))
}
val nextOffset = (offset + limit)
dataButton(">", buildTransactionsData(nextOffset, limit))
}
}
}
onCommand("transactions", initialFilter = { it.sameChat(adminUserId) }) {
val (text, keyboard) = buildStarTransactionsPage(0)
reply(it, text, replyMarkup = keyboard)
}
onMessageDataCallbackQuery(Regex("$transactionsDataPrefix \\d+ \\d+")) {
val (offset, limit) = parseTransactionsData(it.data)
val (text, keyboard) = buildStarTransactionsPage(offset, limit)
edit(
it.message.withContentOrNull<TextContent>() ?: return@onMessageDataCallbackQuery,
text,
replyMarkup = keyboard,
)
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) }
}.second.join()
}

View File

@@ -1,4 +1,5 @@
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.getMe import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.files.downloadFile import dev.inmo.tgbotapi.extensions.api.files.downloadFile
import dev.inmo.tgbotapi.extensions.api.files.downloadFileToTemp import dev.inmo.tgbotapi.extensions.api.files.downloadFileToTemp
@@ -77,10 +78,18 @@ suspend fun main(args: Array<String>) {
runCatchingSafely { runCatchingSafely {
getStickerSet(stickerSetName) getStickerSet(stickerSetName)
}.onSuccess { stickerSet -> }.onSuccess { stickerSet ->
addStickerToSet(it.chat.id.toChatId(), stickerSet.name, newSticker).also { _ -> runCatching {
addStickerToSet(it.chat.id.toChatId(), stickerSet.name, newSticker).also { _ ->
reply(
it,
getStickerSet(stickerSetName).stickers.last()
)
}
}.onFailure { exception ->
exception.printStackTrace()
reply( reply(
it, it,
getStickerSet(stickerSetName).stickers.last() "Unable to add sticker in stickerset"
) )
} }
}.onFailure { exception -> }.onFailure { exception ->
@@ -100,5 +109,9 @@ suspend fun main(args: Array<String>) {
} }
} }
} }
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
}.second.join() }.second.join()
} }

View File

@@ -1,7 +1,4 @@
import dev.inmo.kslog.common.KSLog import dev.inmo.kslog.common.*
import dev.inmo.kslog.common.LogLevel
import dev.inmo.kslog.common.defaultMessageFormatter
import dev.inmo.kslog.common.setDefaultKSLog
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.ktor.server.createKtorServer import dev.inmo.micro_utils.ktor.server.createKtorServer
import dev.inmo.tgbotapi.extensions.api.answers.answer import dev.inmo.tgbotapi.extensions.api.answers.answer
@@ -40,6 +37,7 @@ import java.nio.charset.Charset
* *
* * Telegram Token * * Telegram Token
* * URL where will be placed * * URL where will be placed
* * Port (default 8080)
* *
* Will start the server to share the static (index.html and WebApp.js) on 0.0.0.0:8080 * Will start the server to share the static (index.html and WebApp.js) on 0.0.0.0:8080
*/ */
@@ -58,6 +56,7 @@ suspend fun main(vararg args: String) {
} }
) )
} }
val initiationLogger = KSLog("Initialization")
val bot = telegramBot(telegramBotAPIUrlsKeeper) val bot = telegramBot(telegramBotAPIUrlsKeeper)
createKtorServer( createKtorServer(
@@ -69,12 +68,28 @@ suspend fun main(vararg args: String) {
) { ) {
routing { routing {
val baseJsFolder = File("WebApp/build/dist/js/") val baseJsFolder = File("WebApp/build/dist/js/")
baseJsFolder.list() ?.forEach { val prodSubFolder = File(baseJsFolder, "productionExecutable")
if (it == "productionExecutable" || it == "developmentExecutable") { val devSubFolder = File(baseJsFolder, "developmentExecutable")
staticFiles("", File(baseJsFolder, it)) {
default("WebApp/build/dist/js/$it/index.html") val staticFolder = when {
} prodSubFolder.exists() -> {
initiationLogger.i("Folder for static is ${prodSubFolder.absolutePath}")
prodSubFolder
} }
devSubFolder.exists() -> {
initiationLogger.i("Folder for static is ${devSubFolder.absolutePath}")
devSubFolder
}
else -> error("""
Unable to detect any folder with static. Current working directory: ${File("").absolutePath}.
Searched paths:
* ${prodSubFolder.absolutePath}
* ${devSubFolder.absolutePath}
""".trimIndent())
}
staticFiles("", staticFolder) {
default("${staticFolder.absolutePath}${File.separator}index.html")
} }
post("inline") { post("inline") {
val requestBody = call.receiveText() val requestBody = call.receiveText()

View File

@@ -2,10 +2,11 @@ kotlin.code.style=official
org.gradle.parallel=true org.gradle.parallel=true
# Due to parallel compilation project require next amount of memory on full build # Due to parallel compilation project require next amount of memory on full build
org.gradle.jvmargs=-Xmx2344m org.gradle.jvmargs=-Xmx2344m
kotlin.daemon.jvmargs=-Xmx2g -Xms500m
kotlin_version=1.9.23 kotlin_version=1.9.23
telegram_bot_api_version=12.0.0 telegram_bot_api_version=15.0.0
micro_utils_version=0.20.39 micro_utils_version=0.21.0
serialization_version=1.6.3 serialization_version=1.6.3
ktor_version=2.3.9 ktor_version=2.3.11

View File

@@ -49,3 +49,7 @@ include ":LinkPreviewsBot"
include ":BoostsInfoBot" include ":BoostsInfoBot"
include ":BusinessConnectionsBot" include ":BusinessConnectionsBot"
include ":StarTransactionsBot"
include ":CustomBot"