package dev.inmo.tgbotapi.extensions.api.send import dev.inmo.micro_utils.coroutines.safelyWithResult import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.send.SendAction import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.actions.* import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId import dev.inmo.tgbotapi.types.chat.Chat import kotlinx.coroutines.* import kotlin.contracts.* private const val refreshTime: MilliSeconds = (botActionActualityTime - 1) * 1000L typealias TelegramBotActionCallback = suspend TelegramBot.() -> T @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withAction( actionRequest: SendAction, block: TelegramBotActionCallback ): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } val botActionJob = CoroutineScope(currentCoroutineContext()).launch { while (isActive) { delay(refreshTime) safelyWithoutExceptions { execute(actionRequest) } } } val result = safelyWithResult { block() } botActionJob.cancel() return result.getOrThrow() } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withAction( chatId: IdChatIdentifier, action: BotAction, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, block: TelegramBotActionCallback ): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction( SendAction(chatId, action, threadId, businessConnectionId), block ) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withAction( chat: Chat, action: BotAction, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback ): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction( chat.id, action, threadId, businessConnectionId, block ) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withTypingAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, TypingAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadPhotoAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, UploadPhotoAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withRecordVideoAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, RecordVideoAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadVideoAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, UploadVideoAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withRecordVoiceAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, RecordVoiceAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadVoiceAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, UploadVoiceAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadDocumentAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, UploadDocumentAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withFindLocationAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, FindLocationAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withRecordVideoNoteAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, RecordVideoNoteAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadVideoNoteAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, UploadVideoNoteAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withChooseStickerAction(chatId: IdChatIdentifier, threadId: MessageThreadId? = chatId.threadId, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chatId, ChooseStickerAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withTypingAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, TypingAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadPhotoAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, UploadPhotoAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withRecordVideoAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, RecordVideoAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadVideoAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, UploadVideoAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withRecordVoiceAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, RecordVoiceAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadVoiceAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, UploadVoiceAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadDocumentAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, UploadDocumentAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withFindLocationAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, FindLocationAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withRecordVideoNoteAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, RecordVideoNoteAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withUploadVideoNoteAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, UploadVideoNoteAction, threadId, businessConnectionId, block) } @OptIn(ExperimentalContracts::class) suspend fun TelegramBot.withChooseStickerAction(chat: Chat, threadId: MessageThreadId? = chat.id.threadId, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, block: TelegramBotActionCallback) : T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return withAction(chat, ChooseStickerAction, threadId, businessConnectionId, block) }