Compare commits

...

112 Commits

Author SHA1 Message Date
Renovate Bot
37bd7696eb Update plugin org.jetbrains.kotlin.multiplatform to v1.6.21 2022-04-30 04:08:46 +00:00
1c16a9f868 Create README.md 2022-04-30 08:47:35 +06:00
00c3aba12b Merge pull request #97 from InsanusMokrassar/0.38.16
0.38.16
2022-04-30 08:40:17 +06:00
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
c707a11b66 update gradle 2022-03-24 16:53:32 +06:00
c6c418c393 update up to 0.38.10 2022-03-24 16:52:13 +06:00
e0795c3c14 update up to 0.38.8 2022-03-21 11:25:59 +06:00
dec55990dc Merge pull request #87 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.7
2022-03-12 22:59:42 +06:00
Renovate Bot
169f3f5bd5 Update dependency dev.inmo:tgbotapi to v0.38.7 2022-03-12 16:26:32 +00:00
e175bb6143 Update gradle-wrapper.properties 2022-02-28 09:07:15 +06:00
290d722ae6 Update gradle.properties 2022-02-28 09:06:50 +06:00
9ee85df1ad Merge pull request #85 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.6
2022-02-28 09:06:20 +06:00
Renovate Bot
2953c40963 Update dependency dev.inmo:tgbotapi to v0.38.6 2022-02-28 03:04:39 +00:00
512067b056 Merge pull request #84 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.5
2022-02-12 12:55:49 +06:00
Renovate Bot
0cb209dc6e Update dependency dev.inmo:tgbotapi to v0.38.5 2022-02-09 11:00:15 +00:00
7cf6814d89 update up to 0.38.4 2022-02-02 13:30:32 +06:00
09e8492439 Merge pull request #82 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.3
2022-01-14 23:19:51 +06:00
Renovate Bot
71222f42e5 Update dependency dev.inmo:tgbotapi to v0.38.3 2022-01-14 17:18:46 +00:00
426d649877 Merge pull request #81 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.2
2022-01-12 01:26:24 +06:00
Renovate Bot
93faf9654a Update dependency dev.inmo:tgbotapi to v0.38.2 2022-01-11 16:19:57 +00:00
288386e25a Update gradle.properties 2022-01-11 20:19:49 +06:00
99e83589a4 Merge pull request #80 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.1
2022-01-07 15:51:02 +06:00
Renovate Bot
fbea95fc0a Update dependency dev.inmo:tgbotapi to v0.38.1 2022-01-07 09:31:59 +00:00
0edaa28151 several small updates 2022-01-02 12:06:32 +06:00
df874b0783 update up to 0.38.0 2022-01-02 01:06:04 +06:00
5f5722398d update up to 0.37.3 2021-12-20 14:13:55 +06:00
cc29ec75ca Merge pull request #76 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.37.1
2021-11-15 09:57:36 +06:00
Renovate Bot
a42173acf6 Update dependency dev.inmo:tgbotapi to v0.37.1 2021-11-14 15:41:13 +00:00
d936bc4643 upgrade up to 0.37.0 2021-11-11 12:34:52 +06:00
1b340d8db5 Merge pull request #74 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.36.1
2021-10-24 11:52:00 +06:00
Renovate Bot
4cd1980778 Update dependency dev.inmo:tgbotapi to v0.36.1 2021-10-24 05:26:22 +00:00
d89202aebb update up to 0.36.0 2021-10-18 20:21:58 +06:00
be2de6e372 Merge pull request #71 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.31
2021-10-01 20:30:11 +06:00
Renovate Bot
08796f18e8 Update dependency dev.inmo:micro_utils.fsm.common to v0.5.31 2021-10-01 14:28:11 +00:00
8bd7e116e3 Merge pull request #70 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.30
2021-09-25 18:12:40 +06:00
Renovate Bot
39d7a95c95 Update dependency dev.inmo:micro_utils.fsm.common to v0.5.30 2021-09-25 12:11:44 +00:00
526ecac89a Merge pull request #68 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.29
2021-09-23 17:35:05 +06:00
Renovate Bot
1e4e246fab Update dependency dev.inmo:micro_utils.fsm.common to v0.5.29 2021-09-23 10:02:04 +00:00
6aa7fe151e update up to 0.35.9 2021-09-21 23:22:13 +06:00
16c27fa493 Merge pull request #67 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.26
2021-09-09 17:32:00 +06:00
Renovate Bot
f6a811acca Update dependency dev.inmo:micro_utils.fsm.common to v0.5.26 2021-09-09 11:26:29 +00:00
17c08fc906 Update RandomFileSenderBot.kt 2021-09-09 09:20:17 +06:00
aee0943a5e update dependencies and RandomFileSenderBot example 2021-09-08 23:00:19 +06:00
c07f4f2ed1 Update gradle-wrapper.properties 2021-09-05 09:23:25 +06:00
817acb8faf Update gradle.properties 2021-09-05 09:23:00 +06:00
8b294a0cc0 Merge pull request #66 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.35.7
2021-09-05 09:22:26 +06:00
Renovate Bot
0139cc5dcc Update dependency dev.inmo:tgbotapi to v0.35.7 2021-09-04 12:47:15 +00:00
6d16508277 small actualizations 2021-08-25 15:58:27 +06:00
ce2051d32d Update gradle.properties 2021-08-25 15:52:00 +06:00
1abbcc8789 Update gradle.properties 2021-08-17 09:23:50 +06:00
c5e05dfce1 Update gradle.properties 2021-08-13 22:24:44 +06:00
c1d7129af8 update dependencies 2021-08-09 17:39:04 +06:00
496fc45d2d tgbotapi -> 0.35.3 2021-08-08 20:32:26 +06:00
cdb634e91a Update gradle-wrapper.properties 2021-07-30 13:14:55 +06:00
9d17311918 Update dependencies 2021-07-30 13:14:14 +06:00
12ef88c757 Merge pull request #56 from InsanusMokrassar/0.35.1
0.35.1
2021-06-30 20:42:03 +06:00
4435fdc80c Merge branch 'master' into 0.35.1 2021-06-30 20:28:22 +06:00
cd9eba0393 Update gradle.properties 2021-06-30 20:25:08 +06:00
ef74b33d68 fix main in FSMBot 2021-06-30 13:50:08 +06:00
522d1b55ba add example with oneof and fsm 2021-06-30 13:12:15 +06:00
d062ab86ae update up to 0.35.1 2021-06-28 01:14:16 +06:00
48292ecf72 Merge pull request #54 from InsanusMokrassar/tgbotapi/0.35.0
tgbotapi 0.35.0
2021-06-13 10:08:19 +06:00
22c0fcb439 Update gradle.properties 2021-06-07 19:34:21 +06:00
c90952d3ca update tgbotapi version 2021-05-06 18:24:31 +06:00
b9e9f981c4 Update up to 0.4.34 2021-04-18 17:26:17 +06:00
11836b1e17 Update gradle-wrapper.properties 2021-04-11 04:07:29 +06:00
d30e673539 Merge pull request #44 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.33.3
2021-04-06 22:41:03 +06:00
Renovate Bot
5337f1e4f8 Update dependency dev.inmo:tgbotapi to v0.33.3 2021-04-06 16:35:58 +00:00
26fc3c5924 Update gradle.properties 2021-03-30 22:55:20 +06:00
9e0f43dcc0 update 2021-03-12 15:49:16 +06:00
aa89a289ce Update gradle-wrapper.properties 2021-03-04 15:44:47 +06:00
aeb75d48b9 Update gradle.properties 2021-03-04 15:43:33 +06:00
a67db1c214 Update gradle.properties 2021-02-22 14:42:22 +06:00
3c06da09c2 Update gradle.properties 2021-02-18 16:29:21 +06:00
c15c6d2cf1 Update gradle.properties 2021-02-10 01:19:59 +06:00
febfacc3d5 Update gradle-wrapper.properties 2021-02-10 01:18:49 +06:00
3c71bf287f Merge pull request #34 from InsanusMokrassar/renovate/org.jetbrains.kotlin-kotlin-gradle-plugin-1.x
Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.4.30
2021-02-10 01:18:11 +06:00
6f265640a7 update repositories definition 2021-02-04 15:19:36 +06:00
Renovate Bot
b9e8705b2e Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.4.30 2021-02-03 16:27:00 +00:00
746f3e8a14 Create build.yml 2021-02-02 20:30:24 +06:00
bd621047ee Merge pull request #32 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.32.3
2021-02-02 20:25:11 +06:00
Renovate Bot
98f14faeb2 Update dependency dev.inmo:tgbotapi to v0.32.3 2021-02-02 14:18:38 +00:00
ccb29d6977 update tgbotapi version up to 0.32.1, gradle wrapper and resender bot logic according to update of tgbotapi 2021-02-01 12:57:39 +06:00
f5b526e0c5 update up to tgbotapi 0.31.0 2021-01-18 23:32:47 +06:00
c1cfd05446 Update gradle-wrapper.properties 2021-01-09 15:04:58 +06:00
fb7795414b Merge pull request #27 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.30.13
2021-01-09 15:01:15 +06:00
Renovate Bot
5cb998b390 Update dependency dev.inmo:tgbotapi to v0.30.13 2021-01-09 08:46:38 +00:00
6f182c774c update tgbotapi version up to 0.30.12, update of readme 2021-01-06 00:01:41 +06:00
79cc1a7c9a Update tgbotapi 0.30.8 -> 0.30.10 2020-12-09 18:21:48 +06:00
4ce79657ac update kotlin 2020-11-21 20:24:17 +06:00
9a86360682 Merge pull request #18 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.30.8
2020-11-21 20:23:02 +06:00
50f8e0df61 update 2020-11-21 20:22:11 +06:00
bb846406da Merge pull request #14 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.30.7
2020-11-20 16:42:14 +06:00
6766dc4a8f temporal fix for legacy in resender bot 2020-11-18 12:37:24 +06:00
b440757331 update 2020-11-18 12:35:45 +06:00
Renovate Bot
94bfa67eb3 Update dependency dev.inmo:tgbotapi to v0.30.4 2020-11-13 15:21:18 +00:00
6d066532fb rename forwarder bot 2020-11-02 22:44:15 +06:00
d49ce88a0b update and add SlotMachineDetectorBot 2020-11-02 22:35:28 +06:00
3820e29bf2 update tgbotapi version 2020-11-02 14:39:36 +06:00
7b66c89632 update version of telegram bot api 2020-10-27 16:23:27 +06:00
8f79b9e380 Merge pull request #11 from InsanusMokrassar/0.29.0
0.29.0
2020-10-04 23:50:55 +06:00
358bfdaa05 update hello example 2020-10-04 19:18:16 +06:00
dfae8b7f29 update dependencies 2020-10-04 19:11:48 +06:00
1eb9676c19 migration onto 0.29.0 2020-10-04 17:32:50 +06:00
41 changed files with 890 additions and 256 deletions

16
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ settings.xml
.gradle/
build/
out/
kotlin-js-store/

View File

@@ -1,11 +0,0 @@
language: java
install: true
os: linux
dist: trusty
jdk: oraclejdk8
script:
- ./gradlew build -s

10
FSMBot/README.md Normal file
View File

@@ -0,0 +1,10 @@
# FSM
This bot contains an example of working with FSM included in project
[MicroUtils](https://github.com/InsanusMokrassar/MicroUtils)
## Launch
```bash
../gradlew run --args="BOT_TOKEN"
```

26
FSMBot/build.gradle Normal file
View File

@@ -0,0 +1,26 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="SimpleFSMBotKt"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,50 @@
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.tgbotapi.extensions.api.send.sendMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
import dev.inmo.tgbotapi.extensions.utils.formatting.*
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.*
sealed interface BotState : State
data class ExpectContentOrStopState(override val context: ChatId, val sourceMessage: CommonMessage<TextContent>) : BotState
data class StopState(override val context: ChatId) : BotState
suspend fun main(args: Array<String>) {
val botToken = args.first()
telegramBotWithBehaviourAndFSMAndStartLongPolling<BotState>(botToken, CoroutineScope(Dispatchers.IO)) {
strictlyOn<ExpectContentOrStopState> {
sendMessage(
it.context,
buildEntities {
+"Send me some content or " + botCommand("stop") + " if you want to stop sending"
}
)
val contentMessage = waitContentMessage().first()
val content = contentMessage.content
when {
content is TextContent && content.parseCommandsWithParams().keys.contains("stop") -> StopState(it.context)
else -> {
execute(content.createResend(it.context))
it
}
}
}
strictlyOn<StopState> {
sendMessage(it.context, "You have stopped sending of content")
null
}
command("start") {
startChain(ExpectContentOrStopState(it.chat.id, it))
}
}.second.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,8 @@ apply plugin: 'application'
mainClassName="FilesLoaderBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,14 +1,13 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.downloadFile
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.get.getFileAdditionalInfo
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.flatMap
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts.*
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MediaContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.filenameFromUrl
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
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
import dev.inmo.tgbotapi.utils.filenameFromUrl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import java.io.File
/**
@@ -19,24 +18,15 @@ suspend fun main(args: Array<String>) {
val directoryOrFile = args.getOrNull(1) ?.let { File(it) } ?: File("")
directoryOrFile.mkdirs()
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
val flow = merge (
filterContentMessages<MediaContent>(),
mediaGroupMessages().flatMap()
)
flow.onEach {
safely({ it.printStackTrace() }) {
val pathedFile = bot.getFileAdditionalInfo(it.content.media)
File(directoryOrFile, pathedFile.filePath.filenameFromUrl).apply {
createNewFile()
writeBytes(bot.downloadFile(pathedFile))
}
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))
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
reply(it, "Saved to ${file.absolutePath}")
}
onContentMessage { println(it) }
}.second.join()
}

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

View File

@@ -0,0 +1,41 @@
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.message.*
import kotlinx.coroutines.*
/**
* This bot will always return message about forwarder. In cases when sent message was not a forward message it will
* send suitable message
*/
suspend fun main(vararg args: String) {
val botToken = args.first()
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
onContentMessage(subcontextUpdatesFilter = { _, _ -> true }) {
val toAnswer = buildEntities {
when (val forwardInfo = it.forwardInfo) {
null -> +"There is no forward info"
is AnonymousForwardInfo -> {
regular("Anonymous user which signed as \"") + code(forwardInfo.senderName) + "\""
}
is UserForwardInfo -> {
val user = forwardInfo.from
when (user) {
is CommonUser -> regular("User ")
is CommonBot,
is ExtendedBot -> regular("Bot ")
} + code(user.id.chatId.toString()) + " (${user.firstName} ${user.lastName}: ${user.username ?.username ?: "Without username"})"
}
is ForwardFromChannelInfo -> regular("Channel (") + code((forwardInfo.channelChat).title) + ")"
is ForwardFromSupergroupInfo -> regular("Supergroup (") + code((forwardInfo.group).title) + ")"
}
}
reply(it, toAnswer)
coroutineContext.job.invokeOnCompletion { println("completance of onContentMessage") }
}
coroutineContext.job.invokeOnCompletion { println("Completed :)") }
}.second.join()
}

View File

@@ -1,24 +0,0 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="ForwarderBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
}

View File

@@ -1,43 +0,0 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.sendTextMessage
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.codeMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.regularMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.asContentMessagesFlow
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.types.message.*
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.PossiblyForwardedMessage
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
/**
* This bot will always return message about forwarder. In cases when sent message was not a forward message it will
* send suitable message
*/
suspend fun main(vararg args: String) {
val botToken = args.first()
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
messageFlow.asContentMessagesFlow().mapNotNull { it as? PossiblyForwardedMessage }.onEach { message ->
safely({ it.printStackTrace() }) {
val toAnswer = when (val forwardInfo = message.forwardInfo) {
null -> "There is no forward info"
is AnonymousForwardInfo -> "Anonymous user which signed as \"${forwardInfo.senderName.codeMarkdownV2()}\""
is UserForwardInfo -> forwardInfo.from.let { user ->
"User ${user.id.chatId.toString().codeMarkdownV2()} " + "(${user.firstName} ${user.lastName}: ${user.username ?.username ?: "Without username"})".regularMarkdownV2()
}
is ForwardFromChannelInfo -> "Channel (".regularMarkdownV2() + (forwardInfo.channelChat).title.codeMarkdownV2() + ")".regularMarkdownV2()
is ForwardFromSupergroupInfo -> "Supergroup (".regularMarkdownV2() + (forwardInfo.group).title.codeMarkdownV2() + ")".regularMarkdownV2()
}
bot.sendTextMessage(message.chat, toAnswer, MarkdownV2)
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="HelloBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,5 +1,5 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.getMe
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
/**
* This is one of the most easiest bot - it will just print information about itself

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="HelloBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,17 +1,16 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.chat.get.getChat
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.sendTextMessage
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.linkMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.textMentionMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.types.User
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.*
import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.escapeMarkdownV2Common
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.sendTextMessage
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.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.utils.extensions.escapeMarkdownV2Common
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
/**
* The main purpose of this bot is just to answer "Oh, hi, " and add user mention here
@@ -19,36 +18,31 @@ import kotlinx.coroutines.flow.onEach
suspend fun main(vararg args: String) {
val botToken = args.first()
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
messageFlow.onEach {
safely {
val chat = it.data.chat
val message = "Oh, hi, " + when (chat) {
is PrivateChat -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is User -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is SupergroupChat -> (chat.username ?.username ?: bot.getChat(chat).inviteLink) ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
is GroupChat -> bot.getChat(chat).inviteLink ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
else -> "Unknown :(".escapeMarkdownV2Common()
}
bot.sendTextMessage(chat, message, MarkdownV2)
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
onContentMessage { message ->
val chat = message.chat
if (chat is ChannelChat) {
val answer = "Hi everybody in this channel \"${chat.title}\""
sendTextMessage(chat, answer, MarkdownV2)
return@onContentMessage
}
}.launchIn(scope)
channelPostFlow.onEach {
safely {
val chat = it.data.chat
val message = "Hi everybody in this channel \"${(chat as ChannelChat).title}\""
bot.sendTextMessage(chat, message, MarkdownV2)
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 SupergroupChat -> (chat.username ?.username ?: getChat(chat).inviteLink) ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
is GroupChat -> bot.getChat(chat).inviteLink ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
else -> "Unknown :(".escapeMarkdownV2Common()
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
}
reply(
message,
answerText,
MarkdownV2
)
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) }
}.second.join()
}

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,2 +1,32 @@
# TelegramBotAPI-examples
This repository contains several examples of simple bots which are using TelegramBotAPI
## How to use this repository
This repository contains several important things:
* Example subprojects
* Commits
* Structure
### Example subproject
Each example subproject contains information about how to run this example and what is it
doing. Usually, it is some simple thing like sending "hello" message to the user which
wrote to the bot.
### Commits
Commits can contains some things like migration onto new version (especially it is actual
for major version changes), updates according to the new features in versions and
different other things which usually more important in context of history or changes
between library version
### Structure
Structure of this repository fully representative (it is the reason why this repo
contains multiplatform subprojects) and you can use it as some template (but I am strongly
recommend you to use my
[TelegramBot template](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template) or
[Multiplatform Project template](https://github.com/InsanusMokrassar/KotlinMultiplatformProjectTemplate))

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="RandomFileSenderBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,22 +1,33 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.getMe
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.setMyCommands
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.media.sendDocument
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.sendTextMessage
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.filterExactCommands
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.toInputFile
import com.github.insanusmokrassar.TelegramBotAPI.types.BotCommand
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
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.mediaCountInMediaGroup
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import java.io.File
private const val command = "send_file"
/**
* This bot will send files inside of working directory OR from directory in the second argument
* This bot will send files inside of working directory OR from directory in the second argument.
* You may send /send_file command to this bot to get random file from the directory OR
* `/send_file $number` when you want to receive required number of files. For example,
* /send_file and `/send_file 1` will have the same effect - bot will send one random file.
* But if you will send `/send_file 5` it will choose 5 random files and send them as group
*/
suspend fun main(args: Array<String>) {
val botToken = args.first()
@@ -26,32 +37,63 @@ suspend fun main(args: Array<String>) {
if (currentRoot.isFile) {
return currentRoot
} else {
return pickFile(currentRoot.listFiles() ?.random() ?: return null)
return pickFile(currentRoot.listFiles() ?.takeIf { it.isNotEmpty() } ?.random() ?: return null)
}
}
suspend fun TelegramBot.sendFiles(chat: Chat, files: List<File>) {
when (files.size) {
1 -> sendDocument(
chat.id,
files.first().asMultipartFile(),
protectContent = true
)
else -> sendDocumentsGroup(
chat,
files.map { InputMediaDocument(it.asMultipartFile()) },
protectContent = true
)
}
}
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
messageFlow.filterExactCommands(Regex(command)).onEach { message ->
safely {
pickFile() ?.let {
bot.sendDocument(
message.chat.id,
it.toInputFile()
)
} ?: bot.sendTextMessage(message.chat.id, "Nothing selected :(")
bot.buildBehaviourWithLongPolling (defaultExceptionsHandler = { it.printStackTrace() }) {
onCommandWithArgs(command) { message, args ->
withUploadDocumentAction(message.chat) {
val count = args.firstOrNull() ?.toIntOrNull() ?: 1
var sent = false
var left = count
val chosen = mutableListOf<File>()
while (left > 0) {
left--
val picked = pickFile() ?: continue
chosen.add(picked)
if (chosen.size >= mediaCountInMediaGroup.last) {
sendFiles(message.chat, chosen)
chosen.clear()
sent = true
}
}
if (chosen.isNotEmpty()) {
sendFiles(message.chat, chosen)
sent = true
}
if (!sent) {
bot.reply(message, "Nothing selected :(")
}
}
}.launchIn(scope)
}
}
safely {
bot.setMyCommands(
setMyCommands(
BotCommand(command, "Send some random file in picker directory")
)
println(bot.getMe())
}
scope.coroutineContext[Job]!!.join()
println(getMe())
}.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -12,12 +12,10 @@ plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
}
repositories {
jcenter()
}
kotlin {
jvm()
// js(LEGACY) {
js(IR) {
browser()
binaries.executable()
@@ -28,7 +26,7 @@ kotlin {
dependencies {
implementation kotlin('stdlib')
api "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
api "dev.inmo:tgbotapi:$telegram_bot_api_version"
}
}
}

View File

@@ -1,14 +1,15 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.getMe
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.media.sendMediaGroup
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts.*
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MediaGroupContent
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
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.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.types.message.abstracts.Message
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
suspend fun activateResenderBot(
token: String,
@@ -18,26 +19,37 @@ suspend fun activateResenderBot(
print(bot.getMe())
supervisorScope {
val scope = this
bot.startGettingFlowsUpdatesByLongPolling {
filterContentMessages<MessageContent>(scope).onEach {
it.content.createResends(it.chat.id, replyToMessageId = it.messageId).forEach {
bot.executeUnsafe(it) {
it.forEach(print)
} ?.also {
print(it)
}
}
}.launchIn(scope)
mediaGroupMessages(scope).onEach {
safely({ print(it.stackTraceToString()) }) {
println(it.chat)
bot.execute(it.createResend(it.chat ?: return@safely, replyTo = it.first().messageId)).also {
print(it)
}
}
}.launchIn(scope)
bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
onContentMessage(
initialFilter = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter = MessageFilterByChat
) {
val chat = it.chat
withTypingAction(chat) {
executeUnsafe(it.content.createResend(chat.id, replyToMessageId = it.messageId))
}
}
}
onVisualGallery {
val chat = it.chat ?: return@onVisualGallery
withUploadPhotoAction(chat) {
sendVisualMediaGroup(chat, it.map { it.content.toMediaGroupMemberInputMedia() })
}
}
onPlaylist {
val chat = it.chat ?: return@onPlaylist
withUploadDocumentAction(chat) {
sendPlaylist(chat, it.map { it.content.toMediaGroupMemberInputMedia() })
}
}
onDocumentsGroup {
val chat = it.chat ?: return@onDocumentsGroup
withUploadDocumentAction(chat) {
sendDocumentsGroup(chat, it.map { it.content.toMediaGroupMemberInputMedia() })
}
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
}.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="ResenderBotJvmKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(":ResenderBot:ResenderBotLib")
}

View File

@@ -0,0 +1,9 @@
# SlotMachineDetectorBot
This bot must reply with information about slot machine answer
## 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="SlotMachineDetectorBotKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,35 @@
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.send.reply
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 {
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")
}
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
}

17
WebApp/README.md Normal file
View File

@@ -0,0 +1,17 @@
# WebApp
Here you may find simple example of `WebApp`. For work of this example you will need one of two things:
* Your own domain with SSL (letsencrypt is okay)
* Test account in telegram
What is there in this module:
* JVM part of this example is a server with simple static webapp sharing and bot which just gives the webapp button to open webapp
* JS part is the WebApp with one button and reacting to chaged user theme and app viewport
## How to run
```kotlin
./gradlew run --args="TOKEN WEB_APP_ADDRESS"
```

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,5 +1,15 @@
allprojects {
repositories {
mavenLocal()
mavenCentral()
if (project.hasProperty("GITHUB_USER") && project.hasProperty("GITHUB_TOKEN")) {
maven {
url "https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"
credentials {
username = project.getProperty("GITHUB_USER")
password = project.getProperty("GITHUB_TOKEN")
}
}
}
}
}
}

View File

@@ -1,5 +1,8 @@
kotlin.code.style=official
org.gradle.parallel=true
kotlin_version=1.4.10
telegram_bot_api_version=0.28.5
kotlin_version=1.6.21
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-6.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip

View File

@@ -1,7 +1,21 @@
include ":ForwarderBot"
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"