Compare commits

...

3 Commits

Author SHA1 Message Date
11a97c520a update 2024-04-19 19:34:48 +06:00
d6a6ad8d37 improvements in samples 2024-04-19 18:10:46 +06:00
c04a367375 fixes and improvements 2024-04-18 20:06:59 +06:00
8 changed files with 242 additions and 25 deletions

View File

@@ -0,0 +1,9 @@
# BusinessConnectionBotBot
When bot connected or disconnected to the business chat, it will notify this chat
## 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="BusinessConnectionsBotKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,85 @@
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.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.get.getBusinessConnection
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.send
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.ifBusinessContentMessage
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
suspend fun main(args: Array<String>) {
val botToken = args.first()
val isDebug = args.getOrNull(1) == "debug"
if (isDebug) {
setDefaultKSLog(
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
println(defaultMessageFormatter(level, tag, message, throwable))
}
)
}
val businessConnectionsChats = mutableMapOf<BusinessConnectionId, ChatId>()
val businessConnectionsChatsMutex = Mutex()
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
val me = getMe()
println(me)
onBusinessConnectionEnabled {
businessConnectionsChatsMutex.withLock {
businessConnectionsChats[it.id] = it.userChatId
}
send(it.userChatId, "Business connection ${it.businessConnectionId.string} has been enabled")
}
onBusinessConnectionDisabled {
businessConnectionsChatsMutex.withLock {
businessConnectionsChats.remove(it.id)
}
send(it.userChatId, "Business connection ${it.businessConnectionId.string} has been disabled")
}
onContentMessage {
it.ifBusinessContentMessage {
val sent = execute(it.content.createResend(it.from.id))
if (it.sentByBusinessConnectionOwner) {
reply(sent, "You have sent this message to the ${it.businessConnectionId.string} related chat")
} else {
reply(sent, "User have sent this message to you in the ${it.businessConnectionId.string} related chat")
}
}
}
onEditedContentMessage {
it.ifBusinessContentMessage {
val sent = execute(it.content.createResend(it.from.id))
if (it.sentByBusinessConnectionOwner) {
reply(sent, "You have edited this message in the ${it.businessConnectionId.string} related chat")
} else {
reply(sent, "User have edited this message to you in the ${it.businessConnectionId.string} related chat")
}
}
}
onBusinessMessagesDeleted {
var businessConnectionOwnerChat = businessConnectionsChatsMutex.withLock {
businessConnectionsChats[it.businessConnectionId]
}
if (businessConnectionOwnerChat == null) {
val businessConnection = getBusinessConnection(it.businessConnectionId)
businessConnectionsChatsMutex.withLock {
businessConnectionsChats[businessConnection.businessConnectionId] = businessConnection.userChatId
}
businessConnectionOwnerChat = businessConnection.userChatId
}
send(businessConnectionOwnerChat, "There are several removed messages in chat ${it.chat.id}: ${it.messageIds}")
}
}.second.join()
}

View File

@@ -1,4 +1,5 @@
import dev.inmo.micro_utils.coroutines.AccumulatorFlow import dev.inmo.micro_utils.coroutines.AccumulatorFlow
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.fsm.common.State import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.tgbotapi.extensions.api.send.send import dev.inmo.tgbotapi.extensions.api.send.send
import dev.inmo.tgbotapi.extensions.api.send.sendMessage import dev.inmo.tgbotapi.extensions.api.send.sendMessage
@@ -8,6 +9,8 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithArgs
import dev.inmo.tgbotapi.extensions.utils.extensions.sameThread import dev.inmo.tgbotapi.extensions.utils.extensions.sameThread
import dev.inmo.tgbotapi.extensions.utils.formatting.* import dev.inmo.tgbotapi.extensions.utils.formatting.*
import dev.inmo.tgbotapi.extensions.utils.textContentOrNull
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
import dev.inmo.tgbotapi.types.IdChatIdentifier import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageThreadId import dev.inmo.tgbotapi.types.MessageThreadId
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
@@ -54,7 +57,8 @@ suspend fun main(args: Array<String>) {
val content = contentMessage.content val content = contentMessage.content
when { when {
content is TextContent && content.parseCommandsWithArgs().keys.contains("stop") -> StopState(it.context) content is TextContent && content.text == "/stop"
|| content is TextContent && content.parseCommandsWithArgs().keys.contains("stop") -> StopState(it.context)
else -> { else -> {
execute(content.createResend(it.context)) execute(content.createResend(it.context))
it it
@@ -72,5 +76,17 @@ suspend fun main(args: Array<String>) {
) { ) {
startChain(ExpectContentOrStopState(it.chat.id, it)) startChain(ExpectContentOrStopState(it.chat.id, it))
} }
onContentMessage(
{
it.content.textContentOrNull() ?.text == "/start"
}
) {
startChain(ExpectContentOrStopState(it.chat.id, it.withContentOrNull() ?: return@onContentMessage))
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
}.second.join() }.second.join()
} }

View File

@@ -10,6 +10,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.shortcuts.* import dev.inmo.tgbotapi.extensions.utils.shortcuts.*
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
import dev.inmo.tgbotapi.types.ReplyParameters import dev.inmo.tgbotapi.types.ReplyParameters
import dev.inmo.tgbotapi.types.message.abstracts.BusinessContentMessage
import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.quoteEntitiesField import dev.inmo.tgbotapi.types.quoteEntitiesField
import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull
@@ -22,6 +23,7 @@ suspend fun activateResenderBot(
telegramBotWithBehaviourAndLongPolling(token, scope = CoroutineScope(currentCoroutineContext() + SupervisorJob())) { telegramBotWithBehaviourAndLongPolling(token, scope = CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
onContentMessage( onContentMessage(
subcontextUpdatesFilter = MessageFilterByChat, subcontextUpdatesFilter = MessageFilterByChat,
initialFilter = { it !is BusinessContentMessage<*> || !it.sentByBusinessConnectionOwner }
) { ) {
val chat = it.chat val chat = it.chat

View File

@@ -83,7 +83,7 @@ suspend fun main(args: Array<String>) {
getStickerSet(stickerSetName).stickers.last() getStickerSet(stickerSetName).stickers.last()
) )
} }
}.onFailure { _ -> }.onFailure { exception ->
createNewStickerSet( createNewStickerSet(
it.chat.id.toChatId(), it.chat.id.toChatId(),
stickerSetName.string, stickerSetName.string,

View File

@@ -1,3 +1,7 @@
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.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.bot.setMyCommands import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
@@ -18,6 +22,15 @@ import dev.inmo.tgbotapi.utils.row
suspend fun main(args: Array<String>) { suspend fun main(args: Array<String>) {
val botToken = args.first() val botToken = args.first()
val isDebug = args.getOrNull(1) == "debug"
if (isDebug) {
setDefaultKSLog(
KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
println(defaultMessageFormatter(level, tag, message, throwable))
}
)
}
val bot = telegramBot(botToken) val bot = telegramBot(botToken)
@@ -55,35 +68,53 @@ suspend fun main(args: Array<String>) {
row { row {
requestUserOrBotButton( requestUserOrBotButton(
"\uD83D\uDC64/\uD83E\uDD16 (1)", "\uD83D\uDC64/\uD83E\uDD16 (1)",
requestIdUserOrBot requestIdUserOrBot,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
} }
row { row {
requestUserButton( requestUserButton(
"\uD83D\uDC64☆ (1)", "\uD83D\uDC64☆ (1)",
requestIdUserNonPremium, requestIdUserNonPremium,
premiumUser = false premiumUser = false,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
requestUserButton( requestUserButton(
"\uD83D\uDC64 (1)", "\uD83D\uDC64 (1)",
requestIdUserAny, requestIdUserAny,
premiumUser = null premiumUser = null,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
requestUserButton( requestUserButton(
"\uD83D\uDC64★ (1)", "\uD83D\uDC64★ (1)",
requestIdUserPremium, requestIdUserPremium,
premiumUser = true premiumUser = true,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
requestBotButton( requestBotButton(
"\uD83E\uDD16 (1)", "\uD83E\uDD16 (1)",
requestIdBot requestIdBot,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
} }
row { row {
requestUsersOrBotsButton( requestUsersOrBotsButton(
"\uD83D\uDC64/\uD83E\uDD16", "\uD83D\uDC64/\uD83E\uDD16",
requestIdUsersOrBots, requestIdUsersOrBots,
maxCount = keyboardButtonRequestUserLimit.last maxCount = keyboardButtonRequestUserLimit.last,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
} }
row { row {
@@ -91,101 +122,152 @@ suspend fun main(args: Array<String>) {
"\uD83D\uDC64", "\uD83D\uDC64",
requestIdUsersNonPremium, requestIdUsersNonPremium,
premiumUser = false, premiumUser = false,
maxCount = keyboardButtonRequestUserLimit.last maxCount = keyboardButtonRequestUserLimit.last,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
requestUsersButton( requestUsersButton(
"\uD83D\uDC64", "\uD83D\uDC64",
requestIdUsersAny, requestIdUsersAny,
premiumUser = null, premiumUser = null,
maxCount = keyboardButtonRequestUserLimit.last maxCount = keyboardButtonRequestUserLimit.last,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
requestUsersButton( requestUsersButton(
"\uD83D\uDC64", "\uD83D\uDC64",
requestIdUsersPremium, requestIdUsersPremium,
premiumUser = true, premiumUser = true,
maxCount = keyboardButtonRequestUserLimit.last maxCount = keyboardButtonRequestUserLimit.last,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
requestBotsButton( requestBotsButton(
"\uD83E\uDD16", "\uD83E\uDD16",
requestIdBots, requestIdBots,
maxCount = keyboardButtonRequestUserLimit.last maxCount = keyboardButtonRequestUserLimit.last,
requestName = true,
requestUsername = true,
requestPhoto = true
) )
} }
row { row {
requestChatButton( requestChatButton(
"\uD83D\uDDE3/\uD83D\uDC65", "\uD83D\uDDE3/\uD83D\uDC65",
requestIdAnyChat requestIdAnyChat,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
} }
row { row {
requestChatButton( requestChatButton(
"\uD83D\uDDE3", "\uD83D\uDDE3",
requestIdChannel, requestIdChannel,
isChannel = true isChannel = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestChatButton( requestChatButton(
"\uD83D\uDDE3\uD83D\uDD17", "\uD83D\uDDE3\uD83D\uDD17",
requestIdPublicChannel, requestIdPublicChannel,
isChannel = true, isChannel = true,
isPublic = true isPublic = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestChatButton( requestChatButton(
"\uD83D\uDDE3\uD83D\uDD17", "\uD83D\uDDE3\uD83D\uDD17",
requestIdPrivateChannel, requestIdPrivateChannel,
isChannel = true, isChannel = true,
isPublic = false isPublic = false,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestChatButton( requestChatButton(
"\uD83D\uDDE3\uD83D\uDC6E", "\uD83D\uDDE3\uD83D\uDC6E",
requestIdChannelUserOwner, requestIdChannelUserOwner,
isChannel = true, isChannel = true,
isOwnedBy = true isOwnedBy = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
} }
row { row {
requestGroupButton( requestGroupButton(
"👥", "👥",
requestIdGroup requestIdGroup,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestGroupButton( requestGroupButton(
"👥\uD83D\uDD17", "👥\uD83D\uDD17",
requestIdPublicGroup, requestIdPublicGroup,
isPublic = true isPublic = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestGroupButton( requestGroupButton(
"👥❌\uD83D\uDD17", "👥❌\uD83D\uDD17",
requestIdPrivateGroup, requestIdPrivateGroup,
isPublic = false isPublic = false,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestGroupButton( requestGroupButton(
"👥\uD83D\uDC6E", "👥\uD83D\uDC6E",
requestIdGroupUserOwner, requestIdGroupUserOwner,
isOwnedBy = true isOwnedBy = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
} }
row { row {
requestGroupButton( requestGroupButton(
"🏛", "🏛",
requestIdForum, requestIdForum,
isForum = true isForum = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestGroupButton( requestGroupButton(
"🏛\uD83D\uDD17", "🏛\uD83D\uDD17",
requestIdPublicForum, requestIdPublicForum,
isPublic = true, isPublic = true,
isForum = true isForum = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestGroupButton( requestGroupButton(
"🏛❌\uD83D\uDD17", "🏛❌\uD83D\uDD17",
requestIdPrivateForum, requestIdPrivateForum,
isPublic = false, isPublic = false,
isForum = true isForum = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
requestGroupButton( requestGroupButton(
"🏛\uD83D\uDC6E", "🏛\uD83D\uDC6E",
requestIdForumUserOwner, requestIdForumUserOwner,
isOwnedBy = true, isOwnedBy = true,
isForum = true isForum = true,
requestTitle = true,
requestUsername = true,
requestPhoto = true
) )
} }
} }

View File

@@ -47,3 +47,5 @@ include ":ReactionsInfoBot"
include ":LinkPreviewsBot" include ":LinkPreviewsBot"
include ":BoostsInfoBot" include ":BoostsInfoBot"
include ":BusinessConnectionsBot"