diff --git a/LiveLocationsBot/README.md b/LiveLocationsBot/README.md new file mode 100644 index 0000000..f731caf --- /dev/null +++ b/LiveLocationsBot/README.md @@ -0,0 +1,9 @@ +# LiveLocationsBot + +This bot will send you live location and update it from time to time + +## Launch + +```bash +../gradlew run --args="BOT_TOKEN" +``` diff --git a/LiveLocationsBot/build.gradle b/LiveLocationsBot/build.gradle new file mode 100644 index 0000000..b71f585 --- /dev/null +++ b/LiveLocationsBot/build.gradle @@ -0,0 +1,21 @@ +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName="LiveLocationsBotKt" + + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + implementation "dev.inmo:tgbotapi:$telegram_bot_api_version" +} diff --git a/LiveLocationsBot/src/main/kotlin/LiveLocationsBot.kt b/LiveLocationsBot/src/main/kotlin/LiveLocationsBot.kt new file mode 100644 index 0000000..e0ce8aa --- /dev/null +++ b/LiveLocationsBot/src/main/kotlin/LiveLocationsBot.kt @@ -0,0 +1,84 @@ +import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions +import dev.inmo.tgbotapi.extensions.api.EditLiveLocationInfo +import dev.inmo.tgbotapi.extensions.api.chat.get.getChat +import dev.inmo.tgbotapi.extensions.api.edit.edit +import dev.inmo.tgbotapi.extensions.api.handleLiveLocation +import dev.inmo.tgbotapi.extensions.api.send.* +import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitMessageDataCallbackQuery +import dev.inmo.tgbotapi.extensions.behaviour_builder.oneOf +import dev.inmo.tgbotapi.extensions.behaviour_builder.parallel +import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling +import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand +import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage +import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage +import dev.inmo.tgbotapi.extensions.utils.formatting.linkMarkdownV2 +import dev.inmo.tgbotapi.extensions.utils.formatting.textMentionMarkdownV2 +import dev.inmo.tgbotapi.extensions.utils.ifFromChannelGroupContentMessage +import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton +import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard +import dev.inmo.tgbotapi.types.chat.* +import dev.inmo.tgbotapi.types.chat.GroupChat +import dev.inmo.tgbotapi.types.chat.PrivateChat +import dev.inmo.tgbotapi.types.chat.SupergroupChat +import dev.inmo.tgbotapi.types.location.LiveLocation +import dev.inmo.tgbotapi.types.message.MarkdownV2 +import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage +import dev.inmo.tgbotapi.types.message.content.LiveLocationContent +import dev.inmo.tgbotapi.types.message.content.LocationContent +import dev.inmo.tgbotapi.utils.PreviewFeature +import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Common +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow + +/** + * This bot will send you live location and update it from time to time + */ +suspend fun main(vararg args: String) { + val botToken = args.first() + + telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) { + val locationsFlow = flow { + var i = 0 + while (isActive) { + val newInfo = EditLiveLocationInfo( + latitude = i.toDouble(), + longitude = i.toDouble(), + replyMarkup = flatInlineKeyboard { + dataButton("Cancel", "cancel") + } + ) + emit(newInfo) + i++ + delay(3000L) // 3 seconds + } + } + onCommand("start") { + // in this flow will be actual message with live location + val currentMessageState = MutableStateFlow?>(null) + val sendingJob = launch { + handleLiveLocation( + it.chat.id, + locationsFlow, + sentMessageFlow = FlowCollector { currentMessageState.emit(it) } + ) + } + + waitMessageDataCallbackQuery().filter { + it.message.sameMessage( + currentMessageState.value ?: return@filter false + ) && it.data == "cancel" + }.first() + + sendingJob.cancel() // ends live location + currentMessageState.value ?.let { + edit(it, replyMarkup = null) // removing reply keyboard + } + } + allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) } + }.second.join() +} + diff --git a/gradle.properties b/gradle.properties index 088dac6..006292a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx768m kotlin_version=1.7.22 -telegram_bot_api_version=5.1.0 -micro_utils_version=0.16.8 +telegram_bot_api_version=5.2.0 +micro_utils_version=0.16.10 serialization_version=1.4.1 ktor_version=2.2.3 diff --git a/settings.gradle b/settings.gradle index 262e635..d7e3bf9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -32,3 +32,5 @@ include ":TopicsHandling" include ":UserChatShared" include ":RightsChangerBot" + +include ":LiveLocationsBot"