mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI-examples.git
synced 2026-04-19 16:32:25 +00:00
Compare commits
1 Commits
33.0.0
...
4cac120697
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cac120697 |
@@ -213,8 +213,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
firstName,
|
firstName,
|
||||||
secondName
|
secondName
|
||||||
)
|
)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse { false }
|
}.getOrElse { false }
|
||||||
reply(it) {
|
reply(it) {
|
||||||
if (set) {
|
if (set) {
|
||||||
@@ -232,8 +230,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
businessConnectionId,
|
businessConnectionId,
|
||||||
username
|
username
|
||||||
)
|
)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
false
|
false
|
||||||
@@ -271,8 +267,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
val transferred = runCatching {
|
val transferred = runCatching {
|
||||||
transferBusinessAccountStars(businessConnectionId, count)
|
transferBusinessAccountStars(businessConnectionId, count)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
false
|
false
|
||||||
@@ -316,8 +310,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
businessConnectionId,
|
businessConnectionId,
|
||||||
bio
|
bio
|
||||||
)
|
)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
false
|
false
|
||||||
@@ -335,8 +327,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
businessConnectionId,
|
businessConnectionId,
|
||||||
initialBio
|
initialBio
|
||||||
)
|
)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
false
|
false
|
||||||
@@ -368,8 +358,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
),
|
),
|
||||||
isPublic = isPublic
|
isPublic = isPublic
|
||||||
)
|
)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
false
|
false
|
||||||
@@ -388,8 +376,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
businessConnectionId,
|
businessConnectionId,
|
||||||
isPublic = isPublic
|
isPublic = isPublic
|
||||||
)
|
)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
false
|
false
|
||||||
@@ -475,8 +461,6 @@ suspend fun main(args: Array<String>) {
|
|||||||
|
|
||||||
val deleted = runCatching {
|
val deleted = runCatching {
|
||||||
deleteStory(businessConnectionId, replyTo.content.story.id)
|
deleteStory(businessConnectionId, replyTo.content.story.id)
|
||||||
}.map {
|
|
||||||
true
|
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
false
|
false
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import dev.inmo.micro_utils.coroutines.runCatchingLogging
|
|
||||||
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||||
import dev.inmo.tgbotapi.bot.ktor.telegramBot
|
import dev.inmo.tgbotapi.bot.ktor.telegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.api.chat.modify.setChatPhoto
|
import dev.inmo.tgbotapi.extensions.api.chat.modify.setChatPhoto
|
||||||
@@ -16,13 +15,17 @@ suspend fun main(args: Array<String>) {
|
|||||||
bot.buildBehaviourWithLongPolling(scope = CoroutineScope(Dispatchers.IO)) {
|
bot.buildBehaviourWithLongPolling(scope = CoroutineScope(Dispatchers.IO)) {
|
||||||
onPhoto {
|
onPhoto {
|
||||||
val bytes = downloadFile(it.content)
|
val bytes = downloadFile(it.content)
|
||||||
runCatchingLogging {
|
runCatchingSafely {
|
||||||
setChatPhoto(
|
setChatPhoto(
|
||||||
it.chat.id,
|
it.chat.id,
|
||||||
bytes.asMultipartFile("sample.jpg")
|
bytes.asMultipartFile("sample.jpg")
|
||||||
)
|
)
|
||||||
}.onSuccess { _ ->
|
}.onSuccess { b ->
|
||||||
reply(it, "Done")
|
if (b) {
|
||||||
|
reply(it, "Done")
|
||||||
|
} else {
|
||||||
|
reply(it, "Something went wrong")
|
||||||
|
}
|
||||||
}.onFailure { e ->
|
}.onFailure { e ->
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'kotlin'
|
|
||||||
apply plugin: 'application'
|
|
||||||
|
|
||||||
mainClassName="CustomBotKt"
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
||||||
|
|
||||||
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
|
|
||||||
}
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
import dev.inmo.kslog.common.KSLog
|
|
||||||
import dev.inmo.kslog.common.LogLevel
|
|
||||||
import dev.inmo.kslog.common.defaultMessageFormatter
|
|
||||||
import dev.inmo.kslog.common.setDefaultKSLog
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeLoggingDropExceptions
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.managed_bots.getManagedBotToken
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.managed_bots.replaceManagedBotToken
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.send
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextData
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildSubcontextInitialAction
|
|
||||||
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.onManagedBotCreated
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onManagedBotUpdated
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.chatEventMessageOrNull
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.groupContentMessageOrNull
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.managedBotCreatedOrNull
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatReplyKeyboard
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.types.buttons.requestManagedBotButton
|
|
||||||
import dev.inmo.tgbotapi.types.Username
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestManagedBot
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.PreparedKeyboardButtonId
|
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
|
||||||
import dev.inmo.tgbotapi.types.request.RequestId
|
|
||||||
import dev.inmo.tgbotapi.types.toChatId
|
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
|
|
||||||
private var BehaviourContextData.update: Update?
|
|
||||||
get() = get("update") as? Update
|
|
||||||
set(value) = set("update", value)
|
|
||||||
|
|
||||||
private var BehaviourContextData.commonMessage: CommonMessage<*>?
|
|
||||||
get() = get("commonMessage") as? CommonMessage<*>
|
|
||||||
set(value) = set("commonMessage", value)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This place can be the playground for your code.
|
|
||||||
*/
|
|
||||||
suspend fun main(vararg args: String) {
|
|
||||||
val botToken = args.first()
|
|
||||||
|
|
||||||
val isDebug = args.any { it == "debug" }
|
|
||||||
val isTestServer = args.any { it == "testServer" }
|
|
||||||
|
|
||||||
if (isDebug) {
|
|
||||||
setDefaultKSLog(
|
|
||||||
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
|
|
||||||
println(defaultMessageFormatter(level, tag, message, throwable))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
telegramBotWithBehaviourAndLongPolling(
|
|
||||||
botToken,
|
|
||||||
CoroutineScope(Dispatchers.IO),
|
|
||||||
testServer = isTestServer,
|
|
||||||
builder = {
|
|
||||||
includeMiddlewares {
|
|
||||||
addMiddleware {
|
|
||||||
doOnRequestReturnResult { result, request, _ ->
|
|
||||||
println("Result of $request:\n\n$result")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
subcontextInitialAction = buildSubcontextInitialAction {
|
|
||||||
add {
|
|
||||||
data.update = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
// start here!!
|
|
||||||
val me = getMe()
|
|
||||||
println(me)
|
|
||||||
|
|
||||||
onCommand("start") {
|
|
||||||
println(data.update)
|
|
||||||
println(data.commonMessage)
|
|
||||||
println(getChat(it.chat))
|
|
||||||
}
|
|
||||||
|
|
||||||
onCommand("canManageBots") {
|
|
||||||
val me = getMe()
|
|
||||||
reply(it, if (me.canManageBots) "Yes" else "No")
|
|
||||||
}
|
|
||||||
|
|
||||||
val requestId = RequestId(0)
|
|
||||||
onCommand("keyboard") {
|
|
||||||
reply(
|
|
||||||
it,
|
|
||||||
"Keyboard",
|
|
||||||
replyMarkup = flatReplyKeyboard(
|
|
||||||
resizeKeyboard = true,
|
|
||||||
oneTimeKeyboard = true,
|
|
||||||
) {
|
|
||||||
requestManagedBotButton(
|
|
||||||
"Add managed bot",
|
|
||||||
KeyboardButtonRequestManagedBot(
|
|
||||||
requestId = requestId,
|
|
||||||
suggestedName = "SampleName",
|
|
||||||
suggestedUsername = Username("@some_sample_bot")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
onManagedBotCreated {
|
|
||||||
reply(it, "Managed bot created successfully: ${it.chatEvent.bot}")
|
|
||||||
val token = getManagedBotToken(
|
|
||||||
it.chatEvent.bot.id.toChatId()
|
|
||||||
)
|
|
||||||
reply(it, "Token: $token")
|
|
||||||
}
|
|
||||||
|
|
||||||
onManagedBotUpdated {
|
|
||||||
send(it.user, "Managed bot has been updated: ${it.bot}")
|
|
||||||
val token = getManagedBotToken(
|
|
||||||
it.bot.id.toChatId()
|
|
||||||
)
|
|
||||||
send(it.user, "Token: $token")
|
|
||||||
}
|
|
||||||
|
|
||||||
onCommand("replaceToken") {
|
|
||||||
val reply = it.replyTo ?.chatEventMessageOrNull() ?: return@onCommand
|
|
||||||
val managedBotCreated = reply.chatEvent.managedBotCreatedOrNull() ?: return@onCommand
|
|
||||||
|
|
||||||
reply(it, "Token in replace update: ${replaceManagedBotToken(managedBotCreated.bot.id.toChatId())}")
|
|
||||||
}
|
|
||||||
|
|
||||||
allUpdatesFlow.subscribeLoggingDropExceptions(this) {
|
|
||||||
println(it)
|
|
||||||
}
|
|
||||||
}.second.join()
|
|
||||||
}
|
|
||||||
@@ -70,18 +70,21 @@ suspend fun main(vararg args: String) {
|
|||||||
|
|
||||||
draftMessagesChannel.send("Photo file have been downloaded. Start set my profile photo")
|
draftMessagesChannel.send("Photo file have been downloaded. Start set my profile photo")
|
||||||
|
|
||||||
setMyProfilePhoto(
|
val setResult = setMyProfilePhoto(
|
||||||
InputProfilePhoto.Static(
|
InputProfilePhoto.Static(
|
||||||
photoFile.asMultipartFile()
|
photoFile.asMultipartFile()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
reply(commandMessage, "New photo have been set")
|
if (setResult) {
|
||||||
|
reply(commandMessage, "New photo have been set")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCommand("removeMyProfilePhoto") {
|
onCommand("removeMyProfilePhoto") {
|
||||||
runCatchingLogging {
|
runCatchingLogging {
|
||||||
removeMyProfilePhoto()
|
if (removeMyProfilePhoto()) {
|
||||||
reply(it, "Photo have been removed")
|
reply(it, "Photo have been removed")
|
||||||
|
}
|
||||||
}.onFailure { e ->
|
}.onFailure { e ->
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
reply(it, "Something web wrong. See logs for details.")
|
reply(it, "Something web wrong. See logs for details.")
|
||||||
|
|||||||
@@ -6,16 +6,11 @@ import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
|||||||
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
|
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.polls.sendQuizPoll
|
import dev.inmo.tgbotapi.extensions.api.send.polls.sendQuizPoll
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.polls.sendRegularPoll
|
import dev.inmo.tgbotapi.extensions.api.send.polls.sendRegularPoll
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.send
|
import dev.inmo.tgbotapi.extensions.api.send.send
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPollAnswer
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPollAnswer
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPollOptionAdded
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPollOptionDeleted
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPollUpdates
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPollUpdates
|
||||||
import dev.inmo.tgbotapi.extensions.utils.accessibleMessageOrNull
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.customEmojiTextSourceOrNull
|
import dev.inmo.tgbotapi.extensions.utils.customEmojiTextSourceOrNull
|
||||||
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgsSources
|
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgsSources
|
||||||
import dev.inmo.tgbotapi.types.BotCommand
|
import dev.inmo.tgbotapi.types.BotCommand
|
||||||
@@ -110,9 +105,7 @@ suspend fun main(vararg args: String) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
isAnonymous = false,
|
isAnonymous = false,
|
||||||
replyParameters = ReplyParameters(it),
|
replyParameters = ReplyParameters(it)
|
||||||
allowAddingOptions = true,
|
|
||||||
hideResultsUntilCloses = true,
|
|
||||||
)
|
)
|
||||||
pollToChatMutex.withLock {
|
pollToChatMutex.withLock {
|
||||||
pollToChat[sentPoll.content.poll.id] = sentPoll.chat.id
|
pollToChat[sentPoll.content.poll.id] = sentPoll.chat.id
|
||||||
@@ -125,12 +118,7 @@ suspend fun main(vararg args: String) {
|
|||||||
.firstOrNull { it.first.command == "quiz" }
|
.firstOrNull { it.first.command == "quiz" }
|
||||||
?.second
|
?.second
|
||||||
?.firstNotNullOfOrNull { it.customEmojiTextSourceOrNull() }
|
?.firstNotNullOfOrNull { it.customEmojiTextSourceOrNull() }
|
||||||
val correctAnswer = mutableListOf<Int>()
|
val correctAnswer = Random.nextInt(10)
|
||||||
(1 until Random.nextInt(9)).forEach {
|
|
||||||
val option = Random.nextInt(10)
|
|
||||||
if (correctAnswer.contains(option)) return@forEach
|
|
||||||
correctAnswer.add(option)
|
|
||||||
}
|
|
||||||
val sentPoll = sendQuizPoll(
|
val sentPoll = sendQuizPoll(
|
||||||
it.chat.id,
|
it.chat.id,
|
||||||
questionEntities = buildEntities {
|
questionEntities = buildEntities {
|
||||||
@@ -139,13 +127,7 @@ suspend fun main(vararg args: String) {
|
|||||||
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
|
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
descriptionTextSources = buildEntities {
|
(1 .. 10).map {
|
||||||
regular("Test quiz poll description:")
|
|
||||||
if (customEmoji != null) {
|
|
||||||
customEmoji(customEmoji.customEmojiId, customEmoji.subsources)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options = (1 .. 10).map {
|
|
||||||
InputPollOption {
|
InputPollOption {
|
||||||
regular(it.toString()) + " "
|
regular(it.toString()) + " "
|
||||||
if (customEmoji != null) {
|
if (customEmoji != null) {
|
||||||
@@ -155,11 +137,7 @@ suspend fun main(vararg args: String) {
|
|||||||
},
|
},
|
||||||
isAnonymous = false,
|
isAnonymous = false,
|
||||||
replyParameters = ReplyParameters(it),
|
replyParameters = ReplyParameters(it),
|
||||||
correctOptionIds = correctAnswer.sorted(),
|
correctOptionId = correctAnswer,
|
||||||
allowsMultipleAnswers = correctAnswer.size > 1,
|
|
||||||
allowsRevoting = true,
|
|
||||||
shuffleOptions = true,
|
|
||||||
hideResultsUntilCloses = true,
|
|
||||||
explanationTextSources = buildEntities {
|
explanationTextSources = buildEntities {
|
||||||
regular("Random solved it to be ") + underline((correctAnswer + 1).toString()) + " "
|
regular("Random solved it to be ") + underline((correctAnswer + 1).toString()) + " "
|
||||||
if (customEmoji != null) {
|
if (customEmoji != null) {
|
||||||
@@ -167,7 +145,6 @@ suspend fun main(vararg args: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
println("Sent poll data: $sentPoll")
|
|
||||||
pollToChatMutex.withLock {
|
pollToChatMutex.withLock {
|
||||||
pollToChat[sentPoll.content.poll.id] = sentPoll.chat.id
|
pollToChat[sentPoll.content.poll.id] = sentPoll.chat.id
|
||||||
}
|
}
|
||||||
@@ -191,32 +168,6 @@ suspend fun main(vararg args: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPollOptionAdded {
|
|
||||||
it.chatEvent.pollMessage ?.accessibleMessageOrNull() ?.let { pollMessage ->
|
|
||||||
reply(pollMessage) {
|
|
||||||
+"Poll option added: \n"
|
|
||||||
+it.chatEvent.optionTextSources
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onPollOptionDeleted {
|
|
||||||
it.chatEvent.pollMessage ?.accessibleMessageOrNull() ?.let { pollMessage ->
|
|
||||||
reply(pollMessage) {
|
|
||||||
+"Poll option deleted: \n"
|
|
||||||
+it.chatEvent.optionTextSources
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onContentMessage {
|
|
||||||
val replyPollOptionId = it.replyInfo ?.pollOptionId ?: return@onContentMessage
|
|
||||||
it.replyTo ?.accessibleMessageOrNull() ?.let { replied ->
|
|
||||||
reply(replied, pollOptionId = replyPollOptionId) {
|
|
||||||
+"Reply to poll option"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setMyCommands(
|
setMyCommands(
|
||||||
BotCommand("anonymous", "Create anonymous regular poll"),
|
BotCommand("anonymous", "Create anonymous regular poll"),
|
||||||
BotCommand("public", "Create non anonymous regular poll"),
|
BotCommand("public", "Create non anonymous regular poll"),
|
||||||
|
|||||||
@@ -44,11 +44,7 @@ suspend fun main(args: Array<String>) {
|
|||||||
onCommand("delete") {
|
onCommand("delete") {
|
||||||
val deleted = runCatchingSafely {
|
val deleted = runCatchingSafely {
|
||||||
deleteStickerSet(it.chat.stickerSetName())
|
deleteStickerSet(it.chat.stickerSetName())
|
||||||
}.map {
|
}.getOrElse { false }
|
||||||
true
|
|
||||||
}.getOrElse {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
reply(it, "Deleted")
|
reply(it, "Deleted")
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'kotlin'
|
|
||||||
apply plugin: 'application'
|
|
||||||
|
|
||||||
mainClassName="TagsBotKt"
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
||||||
|
|
||||||
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
import dev.inmo.kslog.common.KSLog
|
|
||||||
import dev.inmo.kslog.common.LogLevel
|
|
||||||
import dev.inmo.kslog.common.defaultMessageFormatter
|
|
||||||
import dev.inmo.kslog.common.setDefaultKSLog
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeLoggingDropExceptions
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
|
||||||
import dev.inmo.tgbotapi.abstracts.FromUser
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.business.getBusinessAccountGiftsFlow
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.chat.members.promoteChatAdministrator
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.chat.members.promoteChatMember
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.chat.members.setChatMemberTag
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.gifts.getChatGiftsFlow
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.gifts.getUserGiftsFlow
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.withTypingAction
|
|
||||||
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.behaviour_builder.triggers_handling.onGiveawayCompleted
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onGiveawayContent
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onGiveawayCreated
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onGiveawayWinners
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.extensions.raw.sender_chat
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.extensions.raw.sender_tag
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.fromUserOrNull
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.groupContentMessageOrNull
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.idChatIdentifierOrNull
|
|
||||||
import dev.inmo.tgbotapi.extensions.utils.potentiallyFromUserGroupContentMessageOrNull
|
|
||||||
import dev.inmo.tgbotapi.types.UserTag
|
|
||||||
import dev.inmo.tgbotapi.types.chat.BusinessChat
|
|
||||||
import dev.inmo.tgbotapi.types.chat.PrivateChat
|
|
||||||
import dev.inmo.tgbotapi.types.chat.PublicChat
|
|
||||||
import dev.inmo.tgbotapi.types.chat.UnknownChatType
|
|
||||||
import dev.inmo.tgbotapi.types.gifts.OwnedGift
|
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.OptionallyFromUserMessage
|
|
||||||
import dev.inmo.tgbotapi.types.message.textsources.splitForText
|
|
||||||
import dev.inmo.tgbotapi.utils.bold
|
|
||||||
import dev.inmo.tgbotapi.utils.buildEntities
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
|
|
||||||
suspend fun main(vararg args: String) {
|
|
||||||
val botToken = args.first()
|
|
||||||
|
|
||||||
val isDebug = args.any { it == "debug" }
|
|
||||||
val isTestServer = args.any { it == "testServer" }
|
|
||||||
|
|
||||||
if (isDebug) {
|
|
||||||
setDefaultKSLog(
|
|
||||||
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
|
|
||||||
println(defaultMessageFormatter(level, tag, message, throwable))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
telegramBotWithBehaviourAndLongPolling(botToken, testServer = isTestServer) {
|
|
||||||
// start here!!
|
|
||||||
val me = getMe()
|
|
||||||
println(me)
|
|
||||||
|
|
||||||
onCommand("setChatMemberTag", requireOnlyCommandInMessage = false) {
|
|
||||||
val reply = it.replyTo ?.groupContentMessageOrNull() ?: return@onCommand
|
|
||||||
val title = it.content.text.removePrefix("/setChatMemberTag").removePrefix(" ")
|
|
||||||
setChatMemberTag(
|
|
||||||
chatId = reply.chat.id,
|
|
||||||
userId = reply.fromUserOrNull() ?.user ?.id ?: return@onCommand,
|
|
||||||
tag = UserTag(title)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
onCommand("setCanManageTags", requireOnlyCommandInMessage = false) {
|
|
||||||
val reply = it.replyTo ?.groupContentMessageOrNull() ?: return@onCommand
|
|
||||||
val setOrUnset = it.content.text.removePrefix("/setCanManageTags").removePrefix(" ") == "true"
|
|
||||||
promoteChatAdministrator(
|
|
||||||
it.chat.id,
|
|
||||||
reply.fromUserOrNull() ?.user ?.id ?: return@onCommand,
|
|
||||||
canManageTags = setOrUnset
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
onCommand("removeChatMemberTag") {
|
|
||||||
val reply = it.replyTo ?.groupContentMessageOrNull() ?: return@onCommand
|
|
||||||
setChatMemberTag(
|
|
||||||
chatId = reply.chat.id,
|
|
||||||
userId = reply.fromUserOrNull() ?.user ?.id ?: return@onCommand,
|
|
||||||
tag = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
onContentMessage {
|
|
||||||
val groupContentMessage = it.potentiallyFromUserGroupContentMessageOrNull() ?: return@onContentMessage
|
|
||||||
reply(it, "Tag after casting: ${groupContentMessage.senderTag}")
|
|
||||||
reply(it, "Tag by getting via risk API: ${it.sender_tag}")
|
|
||||||
}
|
|
||||||
|
|
||||||
allUpdatesFlow.subscribeLoggingDropExceptions(this) {
|
|
||||||
println(it)
|
|
||||||
}
|
|
||||||
}.second.join()
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import dev.inmo.tgbotapi.types.buttons.PreparedKeyboardButtonId
|
|
||||||
import dev.inmo.tgbotapi.types.request.RequestId
|
|
||||||
import kotlin.random.Random
|
|
||||||
import kotlin.random.nextUInt
|
|
||||||
|
|
||||||
val preparedSampleKeyboardRequestId = RequestId(Random.nextUInt().toUShort())
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
|
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
|
||||||
import dev.inmo.tgbotapi.types.CustomEmojiId
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.PreparedKeyboardButtonId
|
|
||||||
import dev.inmo.tgbotapi.types.userIdField
|
import dev.inmo.tgbotapi.types.userIdField
|
||||||
import dev.inmo.tgbotapi.types.webAppQueryIdField
|
import dev.inmo.tgbotapi.types.webAppQueryIdField
|
||||||
import dev.inmo.tgbotapi.webapps.*
|
import dev.inmo.tgbotapi.webapps.*
|
||||||
@@ -18,7 +16,6 @@ import io.ktor.client.request.*
|
|||||||
import io.ktor.client.statement.bodyAsText
|
import io.ktor.client.statement.bodyAsText
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.http.content.TextContent
|
import io.ktor.http.content.TextContent
|
||||||
import kotlinx.browser.document
|
|
||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.dom.appendElement
|
import kotlinx.dom.appendElement
|
||||||
@@ -67,12 +64,7 @@ fun main() {
|
|||||||
}
|
}
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val isSafeState = remember { mutableStateOf<Boolean?>(null) }
|
val isSafeState = remember { mutableStateOf<Boolean?>(null) }
|
||||||
val logsState = remember {
|
val logsState = remember { mutableStateListOf<Any?>() }
|
||||||
mutableStateListOf<Any?>(
|
|
||||||
window.location.href,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val buttonIdState = remember { mutableStateOf<PreparedKeyboardButtonId?>(null) }
|
|
||||||
|
|
||||||
// Text(window.location.href)
|
// Text(window.location.href)
|
||||||
// P()
|
// P()
|
||||||
@@ -101,30 +93,6 @@ fun main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(baseUrl) {
|
|
||||||
val response = client.post("$baseUrl/getPreparedKeyboardButtonId") {
|
|
||||||
setBody(
|
|
||||||
Json.encodeToString(
|
|
||||||
WebAppDataWrapper.serializer(),
|
|
||||||
WebAppDataWrapper(webApp.initData, webApp.initDataUnsafe.hash)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
parameter(userIdField, webApp.initDataUnsafe.user ?.id ?.long ?: return@LaunchedEffect)
|
|
||||||
}
|
|
||||||
when (response.status) {
|
|
||||||
HttpStatusCode.OK -> {
|
|
||||||
val buttonId = response.bodyAsText()
|
|
||||||
buttonIdState.value = PreparedKeyboardButtonId(buttonId)
|
|
||||||
}
|
|
||||||
HttpStatusCode.NoContent -> {
|
|
||||||
buttonIdState.value = null
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
logsState.add("Error while getting prepared keyboard button id: ${response.status}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
when (isSafeState.value) {
|
when (isSafeState.value) {
|
||||||
null -> "Checking safe state..."
|
null -> "Checking safe state..."
|
||||||
@@ -280,23 +248,6 @@ fun main() {
|
|||||||
Text("Confirm")
|
Text("Confirm")
|
||||||
}
|
}
|
||||||
|
|
||||||
P()
|
|
||||||
H3 { Text("Prepared keyboard button") }
|
|
||||||
val buttonIdValue = buttonIdState.value
|
|
||||||
if (buttonIdValue == null) {
|
|
||||||
Text("Ensure that you have called /prepareKeyboard in bot. If you did it, check logs of server")
|
|
||||||
} else {
|
|
||||||
Button({
|
|
||||||
onClick {
|
|
||||||
webApp.requestChat(buttonIdValue) {
|
|
||||||
logsState.add("Chat have been received: $it")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Text("Prepared keyboard button")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
P()
|
P()
|
||||||
H3 { Text("Write access callbacks") }
|
H3 { Text("Write access callbacks") }
|
||||||
Button({
|
Button({
|
||||||
@@ -444,15 +395,6 @@ fun main() {
|
|||||||
}
|
}
|
||||||
mainButton.apply {
|
mainButton.apply {
|
||||||
setText("Main button")
|
setText("Main button")
|
||||||
runCatching {
|
|
||||||
setParams(
|
|
||||||
BottomButtonParams(
|
|
||||||
iconCustomEmojiId = CustomEmojiId("5370976574969486150") // 😏
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}.onFailure {
|
|
||||||
logsState.add("Can't set params for main button: $it")
|
|
||||||
}
|
|
||||||
onClick {
|
onClick {
|
||||||
logsState.add("Main button clicked")
|
logsState.add("Main button clicked")
|
||||||
hapticFeedback.notificationOccurred(
|
hapticFeedback.notificationOccurred(
|
||||||
@@ -463,15 +405,6 @@ fun main() {
|
|||||||
}
|
}
|
||||||
secondaryButton.apply {
|
secondaryButton.apply {
|
||||||
setText("Secondary button")
|
setText("Secondary button")
|
||||||
runCatching {
|
|
||||||
setParams(
|
|
||||||
BottomButtonParams(
|
|
||||||
iconCustomEmojiId = CustomEmojiId("5370763368497944736") // 😒
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}.onFailure {
|
|
||||||
logsState.add("Can't set params for secondary button: $it")
|
|
||||||
}
|
|
||||||
onClick {
|
onClick {
|
||||||
logsState.add("Secondary button clicked")
|
logsState.add("Secondary button clicked")
|
||||||
hapticFeedback.notificationOccurred(
|
hapticFeedback.notificationOccurred(
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import dev.inmo.micro_utils.ktor.server.createKtorServer
|
|||||||
import dev.inmo.tgbotapi.extensions.api.answers.answerInlineQuery
|
import dev.inmo.tgbotapi.extensions.api.answers.answerInlineQuery
|
||||||
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
||||||
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
|
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
|
||||||
import dev.inmo.tgbotapi.extensions.api.savePreparedKeyboardButton
|
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.reply
|
import dev.inmo.tgbotapi.extensions.api.send.reply
|
||||||
import dev.inmo.tgbotapi.extensions.api.send.send
|
import dev.inmo.tgbotapi.extensions.api.send.send
|
||||||
import dev.inmo.tgbotapi.extensions.api.set.setUserEmojiStatus
|
import dev.inmo.tgbotapi.extensions.api.set.setUserEmojiStatus
|
||||||
@@ -22,10 +21,6 @@ import dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton
|
|||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
|
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
|
||||||
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputTextMessageContent
|
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputTextMessageContent
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestManagedBot
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.PreparedKeyboardButton
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.PreparedKeyboardButtonId
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.reply.requestManagedBotReplyButton
|
|
||||||
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
@@ -64,7 +59,6 @@ suspend fun main(vararg args: String) {
|
|||||||
val initiationLogger = KSLog("Initialization")
|
val initiationLogger = KSLog("Initialization")
|
||||||
|
|
||||||
val bot = telegramBot(telegramBotAPIUrlsKeeper)
|
val bot = telegramBot(telegramBotAPIUrlsKeeper)
|
||||||
val usersToButtonsMap = mutableMapOf<UserId, PreparedKeyboardButtonId>()
|
|
||||||
createKtorServer(
|
createKtorServer(
|
||||||
"0.0.0.0",
|
"0.0.0.0",
|
||||||
args.getOrNull(2) ?.toIntOrNull() ?: 8080
|
args.getOrNull(2) ?.toIntOrNull() ?: 8080
|
||||||
@@ -129,24 +123,6 @@ suspend fun main(vararg args: String) {
|
|||||||
|
|
||||||
call.respond(HttpStatusCode.OK, set.toString())
|
call.respond(HttpStatusCode.OK, set.toString())
|
||||||
}
|
}
|
||||||
post("getPreparedKeyboardButtonId") {
|
|
||||||
val requestBody = call.receiveText()
|
|
||||||
val webAppCheckData = Json.decodeFromString(WebAppDataWrapper.serializer(), requestBody)
|
|
||||||
|
|
||||||
val isSafe = telegramBotAPIUrlsKeeper.checkWebAppData(webAppCheckData.data, webAppCheckData.hash)
|
|
||||||
val rawUserId = call.parameters[userIdField] ?.toLongOrNull() ?.let(::RawChatId) ?: error("$userIdField should be presented as long value")
|
|
||||||
|
|
||||||
if (isSafe) {
|
|
||||||
val buttonId = usersToButtonsMap[UserId(rawUserId)]
|
|
||||||
if (buttonId == null) {
|
|
||||||
call.respond(HttpStatusCode.NoContent)
|
|
||||||
} else {
|
|
||||||
call.respond(HttpStatusCode.OK, buttonId.string)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
call.respond(HttpStatusCode.Forbidden)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.start(false)
|
}.start(false)
|
||||||
|
|
||||||
@@ -195,20 +171,6 @@ suspend fun main(vararg args: String) {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onCommand("prepareKeyboard") {
|
|
||||||
val preparedKeyboardButton = savePreparedKeyboardButton(
|
|
||||||
userId = it.chat.id.toChatId(),
|
|
||||||
button = requestManagedBotReplyButton(
|
|
||||||
text = "Saved sample button",
|
|
||||||
requestManagedBot = KeyboardButtonRequestManagedBot(
|
|
||||||
requestId = preparedSampleKeyboardRequestId,
|
|
||||||
suggestedName = "Saved sample button bot",
|
|
||||||
suggestedUsername = Username.prepare("saved_sample_button_bot")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
usersToButtonsMap[it.chat.id.toChatId()] = preparedKeyboardButton.id
|
|
||||||
}
|
|
||||||
onBaseInlineQuery {
|
onBaseInlineQuery {
|
||||||
answerInlineQuery(
|
answerInlineQuery(
|
||||||
it,
|
it,
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ org.gradle.jvmargs=-Xmx3148m
|
|||||||
kotlin.daemon.jvmargs=-Xmx3g -Xms500m
|
kotlin.daemon.jvmargs=-Xmx3g -Xms500m
|
||||||
|
|
||||||
|
|
||||||
kotlin_version=2.3.20
|
kotlin_version=2.2.21
|
||||||
telegram_bot_api_version=33.0.0
|
telegram_bot_api_version=31.0.0
|
||||||
micro_utils_version=0.29.1
|
micro_utils_version=0.26.9
|
||||||
serialization_version=1.10.0
|
serialization_version=1.9.0
|
||||||
ktor_version=3.4.1
|
ktor_version=3.3.2
|
||||||
compose_version=1.10.2
|
compose_version=1.10.1
|
||||||
|
|||||||
@@ -67,7 +67,3 @@ include ":ChecklistsBot"
|
|||||||
include ":DraftsBot"
|
include ":DraftsBot"
|
||||||
|
|
||||||
include ":GiftsBot"
|
include ":GiftsBot"
|
||||||
|
|
||||||
include ":TagsBot"
|
|
||||||
|
|
||||||
include ":ManagedBotsBot"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user