Compare commits

...

39 Commits

Author SHA1 Message Date
0217f97014 checked 2.1.0 and Bot API 6.1 + update several examples 2022-06-21 19:45:24 +06:00
4ae700b58a Merge pull request #121 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.3
2022-06-17 17:44:48 +06:00
renovate[bot]
804fb1e5ee Update dependency dev.inmo:micro_utils.ktor.server to v0.11.3 2022-06-17 11:44:38 +00:00
d443c39813 Merge pull request #122 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v2.0.3
2022-06-17 17:43:10 +06:00
renovate[bot]
cd96547d15 Update telegram_bot_api_version to v2.0.3 2022-06-17 11:42:07 +00:00
f107b4144d Update gradle.properties 2022-06-05 21:25:59 +06:00
39f4196b76 Merge pull request #119 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.0
2022-06-05 21:25:40 +06:00
Renovate Bot
22b9776c26 Update dependency dev.inmo:micro_utils.ktor.server to v0.11.0 2022-06-05 05:10:25 +00:00
2f8f6f3169 Merge pull request #118 from Akkihi/master
fixing example webapp mobile view with html meta
2022-06-04 16:49:52 +06:00
f2b6a50cb5 fixing example webapp mobile view with html meta 2022-06-04 14:46:28 +04:00
acd602d6fa Merge pull request #116 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.10.8
2022-06-03 10:33:33 +06:00
fdb80bf471 Merge pull request #115 from InsanusMokrassar/renovate/ktor_version
Update dependency io.ktor:ktor-server-cio to v2.0.2
2022-06-03 08:57:38 +06:00
Renovate Bot
78c58db4b7 Update dependency dev.inmo:micro_utils.ktor.server to v0.10.8 2022-06-03 02:57:34 +00:00
edd6399bcc Merge pull request #117 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v2.0.1
2022-06-03 08:56:53 +06:00
Renovate Bot
9513e77ba3 Update telegram_bot_api_version to v2.0.1 2022-05-29 20:26:33 +00:00
Renovate Bot
ac75f6487e Update dependency io.ktor:ktor-server-cio to v2.0.2 2022-05-27 18:22:47 +00:00
07750a71c0 Merge pull request #114 from InsanusMokrassar/2.0.0
2.0.0
2022-05-22 14:55:10 +06:00
0bf7e33df3 migration onto 2.0.0 and several improvements 2022-05-22 12:57:53 +06:00
7fb308ea4b Merge pull request #113 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v1.1.3
2022-05-19 14:57:05 -04:00
Renovate Bot
75b403ac98 Update telegram_bot_api_version to v1.1.3 2022-05-19 18:56:32 +00:00
5976e37046 Merge pull request #112 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.10.5
2022-05-19 14:56:10 -04:00
Renovate Bot
c8a94496c7 Update dependency dev.inmo:micro_utils.ktor.server to v0.10.5 2022-05-19 17:40:28 +00:00
f6550bd401 Merge pull request #110 from InsanusMokrassar/1.1.2
1.1.2
2022-05-18 10:24:09 -04:00
389d96f323 fix of checkWebAppData method call 2022-05-18 17:46:50 +06:00
803c5fd664 add handling of errors in FSMBot and update up to tgbotapi 1.1.2 2022-05-18 17:46:04 +06:00
b6eb4fe134 Merge pull request #108 from InsanusMokrassar/1.1.1
1.1.1
2022-05-17 16:05:35 -04:00
9a4bd55ef6 update tgbotapi version 2022-05-17 19:55:42 +06:00
4dac411693 add support of data checking in webapp 2022-05-17 18:58:43 +06:00
d386d50f1c Merge pull request #107 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v1.1.0
2022-05-14 17:33:30 +06:00
Renovate Bot
1b846a6383 Update telegram_bot_api_version to v1.1.0 2022-05-14 11:33:22 +00:00
568b845890 Merge pull request #106 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.10.4
2022-05-14 17:32:48 +06:00
Renovate Bot
3ebca4a058 Update dependency dev.inmo:micro_utils.ktor.server to v0.10.4 2022-05-12 15:37:39 +00:00
2b9af2f667 Merge pull request #104 from InsanusMokrassar/1.0.0
1.0.0
2022-05-12 17:05:10 +06:00
16410debff decrease xmx 2022-05-12 17:00:22 +06:00
a18f22fe8f update xmx for builds 2022-05-12 16:47:46 +06:00
0489f217b3 update examples 2022-05-11 12:15:18 +06:00
e772cfda3b start migration onto 1.0.0 2022-05-11 02:47:37 +06:00
9d42385662 1.0.0 migration preview 2022-05-11 00:23:14 +06:00
b740203116 0.38.23 2022-05-08 00:41:13 +06:00
19 changed files with 220 additions and 83 deletions

View File

@@ -8,9 +8,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 11
- name: Build with Gradle
run: ./gradlew build

View File

@@ -1,3 +1,4 @@
import dev.inmo.micro_utils.coroutines.AccumulatorFlow
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.tgbotapi.extensions.api.send.sendMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
@@ -9,6 +10,7 @@ import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.TextContent
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.first
sealed interface BotState : State
data class ExpectContentOrStopState(override val context: ChatId, val sourceMessage: CommonMessage<TextContent>) : BotState
@@ -17,7 +19,22 @@ data class StopState(override val context: ChatId) : BotState
suspend fun main(args: Array<String>) {
val botToken = args.first()
telegramBotWithBehaviourAndFSMAndStartLongPolling<BotState>(botToken, CoroutineScope(Dispatchers.IO)) {
telegramBotWithBehaviourAndFSMAndStartLongPolling<BotState>(
botToken,
CoroutineScope(Dispatchers.IO),
onStateHandlingErrorHandler = { state, e ->
when (state) {
is ExpectContentOrStopState -> {
println("Thrown error on ExpectContentOrStopState")
}
is StopState -> {
println("Thrown error on StopState")
}
}
e.printStackTrace()
state
}
) {
strictlyOn<ExpectContentOrStopState> {
sendMessage(
it.context,

View File

@@ -1,7 +1,6 @@
import dev.inmo.tgbotapi.extensions.api.files.downloadFile
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviour
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onMedia
@@ -21,11 +20,9 @@ suspend fun main(args: Array<String>) {
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
onMedia(initialFilter = null) {
val pathedFile = bot.getFileAdditionalInfo(it.content.media)
val file = File(directoryOrFile, pathedFile.filePath.filenameFromUrl).apply {
createNewFile()
writeBytes(bot.downloadFile(pathedFile))
}
reply(it, "Saved to ${file.absolutePath}")
val outFile = File(directoryOrFile, pathedFile.filePath.filenameFromUrl)
bot.downloadFile(it.content.media, outFile)
reply(it, "Saved to ${outFile.absolutePath}")
}
onContentMessage { println(it) }
}.second.join()

View File

@@ -2,7 +2,9 @@ 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.onContentMessage
import dev.inmo.tgbotapi.extensions.utils.formatting.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.CommonBot
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.chat.ExtendedBot
import dev.inmo.tgbotapi.types.message.*
import kotlinx.coroutines.*
@@ -24,7 +26,13 @@ suspend fun main(vararg args: String) {
is UserForwardInfo -> {
val user = forwardInfo.from
when (user) {
is CommonUser -> regular("User ")
is CommonUser -> {
if (user.isPremium) {
regular("Premium user ")
} else {
regular("User ")
}
}
is CommonBot,
is ExtendedBot -> regular("Bot ")
} + code(user.id.chatId.toString()) + " (${user.firstName} ${user.lastName}: ${user.username ?.username ?: "Without username"})"
@@ -34,8 +42,6 @@ suspend fun main(vararg args: String) {
}
}
reply(it, toAnswer)
coroutineContext.job.invokeOnCompletion { println("completance of onContentMessage") }
}
coroutineContext.job.invokeOnCompletion { println("Completed :)") }
}.second.join()
}

View File

@@ -1,4 +1,4 @@
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
/**
@@ -10,4 +10,4 @@ suspend fun main(vararg args: String) {
val bot = telegramBot(botToken)
println(bot.getMe())
}
}

View File

@@ -6,15 +6,19 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAn
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
import dev.inmo.tgbotapi.extensions.utils.formatting.linkMarkdownV2
import dev.inmo.tgbotapi.extensions.utils.formatting.textMentionMarkdownV2
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.types.chat.abstracts.*
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.message.MarkdownV2
import dev.inmo.tgbotapi.utils.PreviewFeature
import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Common
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()
@@ -27,8 +31,8 @@ suspend fun main(vararg args: String) {
return@onContentMessage
}
val answerText = "Oh, hi, " + when (chat) {
is PrivateChat -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is User -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is PrivateChat -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is SupergroupChat -> (chat.username ?.username ?: getChat(chat).inviteLink) ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title

View File

@@ -9,7 +9,7 @@ buildscript {
}
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
id "org.jetbrains.kotlin.multiplatform"
}

View File

@@ -1,17 +1,17 @@
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.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.answers.answer
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
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.formatting.botCommand
import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities
import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.message.content.TextContent
import kotlinx.coroutines.*
@@ -86,12 +86,14 @@ suspend fun activateKeyboardsBot(
return@onMessageDataCallbackQuery
}
val text = "This is $page of $count"
editMessageText(
it.message.withContent<TextContent>() ?: it.let {
answer(it, "Unsupported message type :(")
return@onMessageDataCallbackQuery
},
"This is $page of $count",
text,
replyMarkup = inlineKeyboard {
row {
includePageButtons(page, count)
@@ -100,6 +102,22 @@ suspend fun activateKeyboardsBot(
)
}
onUnhandledCommand {
reply(
it,
buildEntities {
+"Use " + botCommand("inline") + " to get pagination inline keyboard"
},
replyMarkup = replyKeyboard(resizeKeyboard = true, oneTimeKeyboard = true) {
row {
simpleButton("/inline")
}
}
)
}
setMyCommands(BotCommand("inline", "Creates message with pagination inline keyboard"))
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}

View File

@@ -1,4 +1,5 @@
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
import dev.inmo.micro_utils.common.filesize
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
@@ -6,18 +7,13 @@ import dev.inmo.tgbotapi.extensions.api.send.media.sendDocument
import dev.inmo.tgbotapi.extensions.api.send.media.sendDocumentsGroup
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.withUploadDocumentAction
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommandWithArgs
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
import dev.inmo.tgbotapi.requests.abstracts.toInputFile
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.InputMedia.DocumentMediaGroupMemberInputMedia
import dev.inmo.tgbotapi.types.InputMedia.InputMediaDocument
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.media.TelegramMediaDocument
import dev.inmo.tgbotapi.types.mediaCountInMediaGroup
import kotlinx.coroutines.*
import java.io.File
private const val command = "send_file"
@@ -50,7 +46,7 @@ suspend fun main(args: Array<String>) {
)
else -> sendDocumentsGroup(
chat,
files.map { InputMediaDocument(it.asMultipartFile()) },
files.map { TelegramMediaDocument(it.asMultipartFile()) },
protectContent = true
)
}
@@ -69,9 +65,9 @@ suspend fun main(args: Array<String>) {
val chosen = mutableListOf<File>()
while (left > 0) {
left--
val picked = pickFile() ?: continue
val picked = pickFile() ?.takeIf { it.filesize > 0 } ?: continue
chosen.add(picked)
left--
if (chosen.size >= mediaCountInMediaGroup.last) {
sendFiles(message.chat, chosen)
chosen.clear()

View File

@@ -9,7 +9,7 @@ buildscript {
}
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
id "org.jetbrains.kotlin.multiplatform"
}

View File

@@ -1,6 +1,6 @@
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.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.send.media.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
@@ -8,7 +8,6 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilte
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.types.message.abstracts.Message
import kotlinx.coroutines.*
suspend fun activateResenderBot(
@@ -32,19 +31,19 @@ suspend fun activateResenderBot(
onVisualGallery {
val chat = it.chat ?: return@onVisualGallery
withUploadPhotoAction(chat) {
sendVisualMediaGroup(chat, it.map { it.content.toMediaGroupMemberInputMedia() })
sendVisualMediaGroup(chat, it.map { it.content.toMediaGroupMemberTelegramMedia() })
}
}
onPlaylist {
val chat = it.chat ?: return@onPlaylist
withUploadDocumentAction(chat) {
sendPlaylist(chat, it.map { it.content.toMediaGroupMemberInputMedia() })
sendPlaylist(chat, it.map { it.content.toMediaGroupMemberTelegramMedia() })
}
}
onDocumentsGroup {
val chat = it.chat ?: return@onDocumentsGroup
withUploadDocumentAction(chat) {
sendDocumentsGroup(chat, it.map { it.content.toMediaGroupMemberInputMedia() })
sendDocumentsGroup(chat, it.map { it.content.toMediaGroupMemberTelegramMedia() })
}
}

View File

@@ -1,35 +1,26 @@
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onDice
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.extensions.utils.shortcuts.filterContentMessages
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
import dev.inmo.tgbotapi.types.dice.SlotMachineDiceAnimationType
import dev.inmo.tgbotapi.types.message.content.DiceContent
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
suspend fun main(args: Array<String>) {
val bot = telegramBot(args.first())
val scope = CoroutineScope(Dispatchers.Default)
bot.longPolling(scope = scope) {
filterContentMessages<DiceContent>(scope).onEach {
bot.buildBehaviourWithLongPolling(scope = CoroutineScope(Dispatchers.IO)) {
onDice {
val content = it.content
val dice = content.dice
val diceType = dice.animationType
safely ({ it.printStackTrace() }) {
if (diceType == SlotMachineDiceAnimationType) {
val result = dice.calculateSlotMachineResult() ?: return@safely
bot.reply(it, "${result.leftReel}|${result.centerReel}|${result.rightReel}")
} else {
bot.reply(it, "There is no slot machine dice in message")
}
if (diceType == SlotMachineDiceAnimationType) {
val result = dice.calculateSlotMachineResult() ?: return@onDice
bot.reply(it, "${result.leftReel}|${result.centerReel}|${result.rightReel}")
} else {
bot.reply(it, "There is no slot machine dice in message")
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
}
}
}.join()
}

View File

@@ -9,7 +9,8 @@ buildscript {
}
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
}
apply plugin: 'application'
@@ -25,6 +26,7 @@ kotlin {
commonMain {
dependencies {
implementation kotlin('stdlib')
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization_version"
}
}

View File

@@ -0,0 +1,7 @@
import kotlinx.serialization.Serializable
@Serializable
data class WebAppDataWrapper(
val data: String,
val hash: String
)

View File

@@ -1,11 +1,11 @@
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.types.webAppQueryIdField
import dev.inmo.tgbotapi.webapps.*
import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackStyle
import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackType
import io.ktor.client.HttpClient
import io.ktor.client.call.receive
import io.ktor.client.request.*
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.readText
import io.ktor.client.statement.bodyAsText
import io.ktor.http.*
import io.ktor.http.content.TextContent
import kotlinx.browser.document
@@ -13,25 +13,54 @@ import kotlinx.browser.window
import kotlinx.coroutines.*
import kotlinx.dom.appendElement
import kotlinx.dom.appendText
import kotlinx.serialization.json.Json
import org.w3c.dom.HTMLElement
fun HTMLElement.log(text: String) {
appendElement("p", {})
appendText(text)
appendElement("p", {})
}
fun main() {
console.log("Web app started")
val client = HttpClient()
val baseUrl = window.location.origin.removeSuffix("/")
window.onload = {
val scope = CoroutineScope(Dispatchers.Default)
runCatching {
scope.launchSafelyWithoutExceptions {
val response = client.post("$baseUrl/check") {
setBody(
Json { }.encodeToString(
WebAppDataWrapper.serializer(),
WebAppDataWrapper(webApp.initData, webApp.initDataUnsafe.hash)
)
)
}
val dataIsSafe = response.bodyAsText().toBoolean()
document.body ?.log(
if (dataIsSafe) {
"Data is safe"
} else {
"Data is unsafe"
}
)
document.body ?.log(
webApp.initDataUnsafe.chat.toString()
)
}
document.body ?.appendElement("button") {
addEventListener("click", {
scope.launchSafelyWithoutExceptions {
handleResult({ "Clicked" }) {
HttpClient().post<HttpResponse>("${window.location.origin.removeSuffix("/")}/inline") {
client.post("${window.location.origin.removeSuffix("/")}/inline") {
parameter(webAppQueryIdField, it)
body = TextContent("Clicked", ContentType.Text.Plain)
setBody(TextContent("Clicked", ContentType.Text.Plain))
document.body ?.log(url.build().toString())
}.coroutineContext.job.join()
}
@@ -46,6 +75,28 @@ fun main() {
onViewportChanged {
document.body ?.log("Viewport changed: ${it.isStateStable}")
}
backButton.apply {
onClick {
document.body ?.log("Back button clicked")
hapticFeedback.impactOccurred(
HapticFeedbackStyle.Heavy
)
}
show()
}
mainButton.apply {
setText("Main button")
onClick {
document.body ?.log("Main button clicked")
hapticFeedback.notificationOccurred(
HapticFeedbackType.Success
)
}
show()
}
onSettingsButtonClicked {
document.body ?.log("Settings button clicked")
}
}
webApp.ready()
}.onFailure {

View File

@@ -2,6 +2,11 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="HandheldFriendly" content="True"/>
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<title>Web App Example</title>
</head>
<body>

View File

@@ -1,4 +1,5 @@
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.crypto.hmacSha256
import dev.inmo.micro_utils.ktor.server.createKtorServer
import dev.inmo.tgbotapi.extensions.api.answers.answer
import dev.inmo.tgbotapi.extensions.api.bot.getMe
@@ -7,20 +8,27 @@ import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.telegramBot
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.formatting.botCommand
import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities
import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputTextMessageContent
import dev.inmo.tgbotapi.types.webAppQueryIdField
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.http.content.*
import io.ktor.request.receiveText
import io.ktor.response.respond
import io.ktor.routing.*
import dev.inmo.tgbotapi.utils.PreviewFeature
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.http.*
import io.ktor.server.application.call
import io.ktor.server.http.content.*
import io.ktor.server.request.receiveText
import io.ktor.server.response.respond
import io.ktor.server.routing.post
import io.ktor.server.routing.routing
import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.json.Json
import java.io.File
import java.nio.charset.Charset
/**
* Accepts two parameters:
@@ -30,8 +38,13 @@ import java.io.File
*
* Will start the server to share the static (index.html and WebApp.js) on 0.0.0.0:8080
*/
@OptIn(PreviewFeature::class)
suspend fun main(vararg args: String) {
val bot = telegramBot(args.first(), testServer = args.any { it == "testServer" })
val telegramBotAPIUrlsKeeper = TelegramAPIUrlsKeeper(
args.first(),
testServer = args.any { it == "testServer" }
)
val bot = telegramBot(telegramBotAPIUrlsKeeper)
createKtorServer(
"0.0.0.0",
8080,
@@ -51,6 +64,14 @@ suspend fun main(vararg args: String) {
bot.answer(queryId, InlineQueryResultArticle(queryId, "Result", InputTextMessageContent(requestBody)))
call.respond(HttpStatusCode.OK)
}
post("check") {
val requestBody = call.receiveText()
val webAppCheckData = Json { }.decodeFromString(WebAppDataWrapper.serializer(), requestBody)
val isSafe = telegramBotAPIUrlsKeeper.checkWebAppData(webAppCheckData.data, webAppCheckData.hash)
call.respond(HttpStatusCode.OK, isSafe.toString())
}
}
}.start(false)
@@ -81,6 +102,15 @@ suspend fun main(vararg args: String) {
)
}
onUnhandledCommand {
reply(
it,
buildEntities {
+"Use " + botCommand("inline") + " to get inline web app button\n"
+"Use " + botCommand("reply_markup") + " to get reply markup web app button\n"
}
)
}
setMyCommands(
BotCommand("reply_markup", "Use to get reply markup keyboard with web app trigger"),
BotCommand("inline", "Use to get inline keyboard with web app trigger"),

View File

@@ -1,3 +1,14 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
allprojects {
repositories {
mavenLocal()

View File

@@ -1,8 +1,11 @@
kotlin.code.style=official
org.gradle.parallel=true
# Due to parallel compilation project require next amount of memory on full build
org.gradle.jvmargs=-Xmx768m
kotlin_version=1.6.10
telegram_bot_api_version=0.38.22
micro_utils_version=0.9.24
ktor_version=1.6.8
kotlin_version=1.6.21
telegram_bot_api_version=2.1.0
micro_utils_version=0.11.3
serialization_version=1.3.3
ktor_version=2.0.2