mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI-examples.git
synced 2025-12-05 22:05:38 +00:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4435fdc80c | |||
| cd9eba0393 | |||
| ef74b33d68 | |||
| 522d1b55ba | |||
| d062ab86ae | |||
| 48292ecf72 | |||
| 22c0fcb439 | |||
| c90952d3ca | |||
| b9e9f981c4 | |||
| 11836b1e17 | |||
| d30e673539 | |||
|
|
5337f1e4f8 | ||
| 26fc3c5924 | |||
| 9e0f43dcc0 | |||
| aa89a289ce | |||
| aeb75d48b9 | |||
| a67db1c214 | |||
| 3c06da09c2 | |||
| c15c6d2cf1 | |||
| febfacc3d5 | |||
| 3c71bf287f | |||
| 6f265640a7 | |||
|
|
b9e8705b2e | ||
| 746f3e8a14 | |||
| bd621047ee | |||
|
|
98f14faeb2 | ||
| ccb29d6977 | |||
| f5b526e0c5 | |||
| c1cfd05446 | |||
| fb7795414b | |||
|
|
5cb998b390 | ||
| 6f182c774c | |||
| 79cc1a7c9a | |||
| 4ce79657ac | |||
| 9a86360682 | |||
| 50f8e0df61 | |||
| bb846406da | |||
| 6766dc4a8f | |||
| b440757331 | |||
|
|
94bfa67eb3 | ||
| 6d066532fb | |||
| d49ce88a0b | |||
| 3820e29bf2 | |||
| 7b66c89632 | |||
| 8f79b9e380 |
16
.github/workflows/build.yml
vendored
Normal file
16
.github/workflows/build.yml
vendored
Normal 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
|
||||
10
FSMBot/README.md
Normal file
10
FSMBot/README.md
Normal 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"
|
||||
```
|
||||
22
FSMBot/build.gradle
Normal file
22
FSMBot/build.gradle
Normal file
@@ -0,0 +1,22 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'application'
|
||||
|
||||
mainClassName="SimpleFSMBotKt"
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
|
||||
implementation "dev.inmo:micro_utils.fsm.common:$micro_utils_version"
|
||||
}
|
||||
90
FSMBot/src/main/kotlin/SimpleFSMBot.kt
Normal file
90
FSMBot/src/main/kotlin/SimpleFSMBot.kt
Normal file
@@ -0,0 +1,90 @@
|
||||
import dev.inmo.micro_utils.fsm.common.State
|
||||
import dev.inmo.micro_utils.fsm.common.dsl.buildFSM
|
||||
import dev.inmo.micro_utils.fsm.common.dsl.strictlyOn
|
||||
import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup
|
||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
||||
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.command
|
||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
|
||||
import dev.inmo.tgbotapi.types.ChatId
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
sealed interface State : State
|
||||
data class ExpectContentOrStopState(override val context: ChatId, val sourceMessage: CommonMessage<TextContent>) : State
|
||||
data class StopState(override val context: ChatId) : State
|
||||
|
||||
fun TextContent.containsStopCommand() = parseCommandsWithParams().keys.firstOrNull { it == "stop" } != null
|
||||
|
||||
suspend fun main(args: Array<String>) {
|
||||
val botToken = args.first()
|
||||
|
||||
telegramBotWithBehaviour(botToken, CoroutineScope(Dispatchers.IO)) {
|
||||
val fsm = buildFSM {
|
||||
strictlyOn<ExpectContentOrStopState> {
|
||||
sendMessage(
|
||||
it.context,
|
||||
buildEntities {
|
||||
+"Send me some content or "
|
||||
botCommand("stop")
|
||||
+" if you want to stop sending"
|
||||
}
|
||||
)
|
||||
|
||||
val content = oneOf(
|
||||
parallel {
|
||||
waitContentMessage(includeMediaGroups = false) { if (chat.id == it.context) content else null }.also(::println)
|
||||
},
|
||||
parallel {
|
||||
waitMediaGroup { chat ?.id == it.context }.also(::println)
|
||||
},
|
||||
parallel {
|
||||
waitText { if (content.containsStopCommand()) content else null }.also(::println)
|
||||
}
|
||||
).first()
|
||||
|
||||
when {
|
||||
content is TextContent && content.containsStopCommand() -> StopState(it.context) // assume we got "stop" command
|
||||
content is List<*> -> { // assume it is media group
|
||||
val casted = (content as List<MediaGroupContent>)
|
||||
|
||||
reply(it.sourceMessage, "Ok, I got this media group and now will resend it to you")
|
||||
sendMediaGroup(it.context, casted.map { it.toMediaGroupMemberInputMedia() })
|
||||
|
||||
it
|
||||
}
|
||||
content is MessageContent -> {
|
||||
|
||||
reply(it.sourceMessage, "Ok, I got this content and now will resend it to you")
|
||||
execute(content.createResend(it.context))
|
||||
|
||||
it
|
||||
}
|
||||
else -> {
|
||||
sendMessage(it.context, "Unknown internal error")
|
||||
it
|
||||
}
|
||||
}
|
||||
}
|
||||
strictlyOn<StopState> {
|
||||
sendMessage(it.context, "You have stopped sending of content")
|
||||
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
command("start") {
|
||||
fsm.startChain(ExpectContentOrStopState(it.chat.id, it))
|
||||
}
|
||||
|
||||
fsm.start(this)
|
||||
}.second.join()
|
||||
}
|
||||
@@ -13,10 +13,6 @@ apply plugin: 'application'
|
||||
|
||||
mainClassName="FilesLoaderBotKt"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import dev.inmo.tgbotapi.extensions.api.downloadFile
|
||||
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
||||
import dev.inmo.tgbotapi.extensions.api.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.utils.flatMap
|
||||
import dev.inmo.tgbotapi.extensions.utils.safely
|
||||
import dev.inmo.tgbotapi.extensions.utils.shortcuts.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviour
|
||||
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.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
@@ -19,24 +17,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))
|
||||
}
|
||||
telegramBotWithBehaviour(botToken, CoroutineScope(Dispatchers.IO)) {
|
||||
onMedia(includeMediaGroups = true) {
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -11,11 +11,8 @@ buildscript {
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'application'
|
||||
|
||||
mainClassName="ForwarderBotKt"
|
||||
mainClassName="ForwardInfoSenderBotKt"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
39
ForwardInfoSenderBot/src/main/kotlin/ForwardInfoSenderBot.kt
Normal file
39
ForwardInfoSenderBot/src/main/kotlin/ForwardInfoSenderBot.kt
Normal file
@@ -0,0 +1,39 @@
|
||||
import dev.inmo.micro_utils.coroutines.defaultSafelyExceptionHandler
|
||||
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviour
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.*
|
||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
||||
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()
|
||||
|
||||
telegramBotWithBehaviour(botToken, CoroutineScope(Dispatchers.IO)) {
|
||||
onContentMessage(includeMediaGroups = 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
|
||||
regular("User ") + 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()
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import dev.inmo.tgbotapi.extensions.api.send.sendTextMessage
|
||||
import dev.inmo.tgbotapi.extensions.api.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.codeMarkdownV2
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.regularMarkdownV2
|
||||
import dev.inmo.tgbotapi.extensions.utils.safely
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.asContentMessagesFlow
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
|
||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
||||
import dev.inmo.tgbotapi.types.message.*
|
||||
import dev.inmo.tgbotapi.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()
|
||||
}
|
||||
@@ -13,9 +13,6 @@ apply plugin: 'application'
|
||||
|
||||
mainClassName="HelloBotKt"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
||||
import dev.inmo.tgbotapi.extensions.api.telegramBot
|
||||
|
||||
/**
|
||||
* This is one of the most easiest bot - it will just print information about itself
|
||||
|
||||
@@ -13,9 +13,6 @@ apply plugin: 'application'
|
||||
|
||||
mainClassName="HelloBotKt"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
|
||||
import dev.inmo.tgbotapi.extensions.api.chat.get.getChatAdministrators
|
||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
||||
import dev.inmo.tgbotapi.extensions.api.send.sendTextMessage
|
||||
import dev.inmo.tgbotapi.extensions.api.telegramBot
|
||||
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviour
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
|
||||
import dev.inmo.tgbotapi.extensions.utils.asChannelChat
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.linkMarkdownV2
|
||||
import dev.inmo.tgbotapi.extensions.utils.formatting.textMentionMarkdownV2
|
||||
import dev.inmo.tgbotapi.extensions.utils.safely
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
|
||||
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.toChatId
|
||||
import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Common
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@@ -22,45 +23,30 @@ import kotlinx.coroutines.flow.onEach
|
||||
suspend fun main(vararg args: String) {
|
||||
val botToken = args.first()
|
||||
|
||||
val bot = telegramBot(botToken)
|
||||
|
||||
val scope = CoroutineScope(Dispatchers.Default)
|
||||
|
||||
scope.launch {
|
||||
println(bot.getChatAdministrators((-1001433262056L).toChatId()))
|
||||
}
|
||||
|
||||
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
|
||||
messageFlow.onEach {
|
||||
safely {
|
||||
val message = it.data
|
||||
val chat = message.chat
|
||||
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 ?: 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.reply(
|
||||
message,
|
||||
answerText,
|
||||
MarkdownV2
|
||||
)
|
||||
telegramBotWithBehaviour(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
|
||||
)
|
||||
}
|
||||
}.second.join()
|
||||
}
|
||||
|
||||
30
README.md
30
README.md
@@ -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))
|
||||
|
||||
@@ -13,9 +13,6 @@ apply plugin: 'application'
|
||||
|
||||
mainClassName="RandomFileSenderBotKt"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import dev.inmo.tgbotapi.bot.Ktor.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.sendTextMessage
|
||||
import dev.inmo.tgbotapi.extensions.api.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.utils.safely
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.filterExactCommands
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
|
||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
|
||||
import dev.inmo.tgbotapi.requests.abstracts.toInputFile
|
||||
import dev.inmo.tgbotapi.types.BotCommand
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import java.io.File
|
||||
|
||||
private const val command = "send_file"
|
||||
@@ -33,25 +30,18 @@ suspend fun main(args: Array<String>) {
|
||||
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 :(")
|
||||
}
|
||||
}.launchIn(scope)
|
||||
}
|
||||
|
||||
safely {
|
||||
bot.setMyCommands(
|
||||
bot.buildBehaviour(scope) {
|
||||
onCommand(command.toRegex()) { message ->
|
||||
pickFile() ?.let {
|
||||
bot.sendDocument(
|
||||
message.chat.id,
|
||||
it.toInputFile()
|
||||
)
|
||||
} ?: bot.reply(message, "Nothing selected :(")
|
||||
}
|
||||
setMyCommands(
|
||||
BotCommand(command, "Send some random file in picker directory")
|
||||
)
|
||||
println(bot.getMe())
|
||||
}
|
||||
|
||||
scope.coroutineContext[Job]!!.join()
|
||||
println(getMe())
|
||||
}.join()
|
||||
}
|
||||
|
||||
@@ -12,12 +12,10 @@ plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
// js(LEGACY) {
|
||||
js(IR) {
|
||||
browser()
|
||||
binaries.executable()
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
||||
import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup
|
||||
import dev.inmo.tgbotapi.extensions.api.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.utils.safely
|
||||
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
|
||||
import dev.inmo.tgbotapi.extensions.api.send.media.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
|
||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.shortcuts.*
|
||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
suspend fun activateResenderBot(
|
||||
token: String,
|
||||
@@ -18,26 +16,20 @@ 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.buildBehaviour(CoroutineScope(coroutineContext + SupervisorJob())) {
|
||||
onContentMessage(
|
||||
additionalFilter = { it !is MediaGroupMessage<*> }
|
||||
) {
|
||||
executeUnsafe(it.content.createResend(it.chat.id, replyToMessageId = it.messageId))
|
||||
}
|
||||
}
|
||||
onVisualGallery {
|
||||
sendVisualMediaGroup(it.chat!!, it.map { it.content.toMediaGroupMemberInputMedia() })
|
||||
}
|
||||
onPlaylist {
|
||||
sendPlaylist(it.chat!!, it.map { it.content.toMediaGroupMemberInputMedia() })
|
||||
}
|
||||
onDocumentsGroup {
|
||||
sendDocumentsGroup(it.chat!!, it.map { it.content.toMediaGroupMemberInputMedia() })
|
||||
}
|
||||
}.join()
|
||||
}
|
||||
|
||||
@@ -13,9 +13,6 @@ apply plugin: 'application'
|
||||
|
||||
mainClassName="ResenderBotJvmKt"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
9
SlotMachineDetectorBot/README.md
Normal file
9
SlotMachineDetectorBot/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# SlotMachineDetectorBot
|
||||
|
||||
This bot must reply with information about slot machine answer
|
||||
|
||||
## Launch
|
||||
|
||||
```bash
|
||||
../gradlew run --args="BOT_TOKEN"
|
||||
```
|
||||
21
SlotMachineDetectorBot/build.gradle
Normal file
21
SlotMachineDetectorBot/build.gradle
Normal file
@@ -0,0 +1,21 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
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-jdk8:$kotlin_version"
|
||||
|
||||
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
10
build.gradle
10
build.gradle
@@ -1,5 +1,15 @@
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
kotlin.code.style=official
|
||||
org.gradle.parallel=true
|
||||
|
||||
kotlin_version=1.4.10
|
||||
telegram_bot_api_version=0.29.0
|
||||
|
||||
kotlin_version=1.5.20
|
||||
telegram_bot_api_version=0.35.1
|
||||
micro_utils_version=0.5.15
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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.0-bin.zip
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
include ":ForwarderBot"
|
||||
include ":ForwardInfoSenderBot"
|
||||
include ":RandomFileSenderBot"
|
||||
include ":HelloBot"
|
||||
include ":GetMeBot"
|
||||
include ":FilesLoaderBot"
|
||||
include ":ResenderBot:ResenderBotLib"
|
||||
include ":ResenderBot:jvm_launcher"
|
||||
include ":SlotMachineDetectorBot"
|
||||
include ":FSMBot"
|
||||
|
||||
Reference in New Issue
Block a user