├── README.md ├── src └── iris │ ├── connection │ ├── Connection.kt │ ├── ConnectionHttpClientAbstract.kt │ ├── ConnectionHttpClientDefault.kt │ ├── ConnectionHttpClientFuture.kt │ ├── StringBuilderUrlEncoder.java │ └── query │ │ ├── ArrayQuery.kt │ │ ├── BasicQuery.kt │ │ ├── MapQuery.kt │ │ ├── PairArrayQuery.kt │ │ ├── PairQuery.kt │ │ ├── Query.kt │ │ ├── RowArrayQuery.kt │ │ └── SinglePairQuery.kt │ └── tg │ ├── QueuedService.kt │ ├── TgReadWriteBufferDefault.kt │ ├── TgReadWriteBufferDefault.kt1 │ ├── TgReadWriteProcessor.kt │ ├── TgReadWriteUpdateBuffer.kt │ ├── TgReadable.kt │ ├── TgUpdateWriter.kt │ ├── api │ ├── AllowedUpdates.kt │ ├── Jsonifier.kt │ ├── JsonifierSimple.kt │ ├── MediaGroupBuilder.kt │ ├── ResponseHandler.kt │ ├── SendDefaults.kt │ ├── TgApi.kt │ ├── TgApiAbstract.kt │ ├── TgApiFuture.kt │ ├── TgApiObjFuture.kt │ ├── TgApiObject.kt │ ├── items │ │ ├── Animation.kt │ │ ├── Audio.kt │ │ ├── CallbackGame.kt │ │ ├── CallbackQuery.kt │ │ ├── Chat.kt │ │ ├── ChatInviteLink.kt │ │ ├── ChatJoinRequest.kt │ │ ├── ChatLocation.kt │ │ ├── ChatMember.kt │ │ ├── ChatMemberUpdated.kt │ │ ├── ChatPermissions.kt │ │ ├── ChatPhoto.kt │ │ ├── ChosenInlineResult.kt │ │ ├── Contact.kt │ │ ├── Dice.kt │ │ ├── Document.kt │ │ ├── EncryptedCredentials.kt │ │ ├── EncryptedPassportElement.kt │ │ ├── Error.kt │ │ ├── File.kt │ │ ├── ForceReply.kt │ │ ├── Game.kt │ │ ├── InlineKeyboardButton.kt │ │ ├── InlineKeyboardMarkup.kt │ │ ├── InlineQuery.kt │ │ ├── InputMediaAudio.kt │ │ ├── Invoice.kt │ │ ├── Location.kt │ │ ├── LoginUrl.kt │ │ ├── MaskPosition.kt │ │ ├── Message.kt │ │ ├── MessageAutoDeleteTimerChanged.kt │ │ ├── MessageEntity.kt │ │ ├── PassportData.kt │ │ ├── PhotoSize.kt │ │ ├── Poll.kt │ │ ├── PollAnswer.kt │ │ ├── PollOption.kt │ │ ├── PreCheckoutQuery.kt │ │ ├── ProximityAlertTriggered.kt │ │ ├── ReplyKeyboardMarkup.kt │ │ ├── ReplyKeyboardRemove.kt │ │ ├── ReplyMarkup.kt │ │ ├── ShippingQuery.kt │ │ ├── Sticker.kt │ │ ├── SuccessfulPayment.kt │ │ ├── TgItem.kt │ │ ├── Update.kt │ │ ├── UpdateExt.kt │ │ ├── User.kt │ │ ├── Venue.kt │ │ ├── Video.kt │ │ ├── VideoNote.kt │ │ ├── Voice.kt │ │ ├── VoiceChatEnded.kt │ │ ├── VoiceChatParticipantsInvited.kt │ │ ├── VoiceChatScheduled.kt │ │ └── VoiceChatStarted.kt │ └── response │ │ ├── AnswerCallbackQueryResponse.kt │ │ ├── BanChatMemberResponse.kt │ │ ├── BooleanResponse.kt │ │ ├── DeleteMessageResponse.kt │ │ ├── GetChatAdministratorsResponse.kt │ │ ├── GetChatMemberCountResponse.kt │ │ ├── GetChatMemberResponse.kt │ │ ├── GetChatResponse.kt │ │ ├── GetFileResponse.kt │ │ ├── GetPathResponse.kt │ │ ├── GetUpdatesResponse.kt │ │ ├── IntegerResponse.kt │ │ ├── KickChatMemberResponse.kt │ │ ├── RestrictChatMemberResponse.kt │ │ ├── SendMessageResponse.kt │ │ ├── SendPhotoResponse.kt │ │ ├── TgResponse.kt │ │ ├── UnbanChatMember.kt │ │ └── UnbanChatMemberResponse.kt │ ├── command │ ├── Command.kt │ ├── CommandExtractor.kt │ ├── CommandExtractorDefault.kt │ ├── CommandMatcher.kt │ ├── CommandMatcherRegex.kt │ ├── CommandMatcherSimple.kt │ ├── CommandMatcherWithHash.kt │ ├── TgCommandHandler.kt │ └── TgSingleCommandHandler.kt1 │ ├── irisjson │ ├── ResponseHandler_IrisJson.kt │ ├── ResponseHandler_IrisJsonObj.kt │ ├── TgApiFuture_IrisJson.kt │ ├── TgApi_IrisJson.kt │ ├── TgLongPoll_IrisJson.kt │ ├── items │ │ ├── IrisJsonAnimation.kt │ │ ├── IrisJsonAudio.kt │ │ ├── IrisJsonCallbackQuery.kt │ │ ├── IrisJsonChat.kt │ │ ├── IrisJsonChatLocation.kt │ │ ├── IrisJsonChatMember.kt │ │ ├── IrisJsonChatMemberUpdated.kt │ │ ├── IrisJsonChatPermissions.kt │ │ ├── IrisJsonContact.kt │ │ ├── IrisJsonDice.kt │ │ ├── IrisJsonDocument.kt │ │ ├── IrisJsonError.kt │ │ ├── IrisJsonFile.kt │ │ ├── IrisJsonGame.kt │ │ ├── IrisJsonInlineKeyboardMarkup.kt │ │ ├── IrisJsonInvoice.kt │ │ ├── IrisJsonLocation.kt │ │ ├── IrisJsonMaskPosition.kt │ │ ├── IrisJsonMessage.kt │ │ ├── IrisJsonMessageAutoDeleteTimerChanged.kt │ │ ├── IrisJsonPassportData.kt │ │ ├── IrisJsonPhotoSize.kt │ │ ├── IrisJsonPoll.kt │ │ ├── IrisJsonPollOption.kt │ │ ├── IrisJsonProximityAlertTriggered.kt │ │ ├── IrisJsonSticker.kt │ │ ├── IrisJsonSuccessfulPayment.kt │ │ ├── IrisJsonTgItem.kt │ │ ├── IrisJsonUpdate.kt │ │ ├── IrisJsonUser.kt │ │ ├── IrisJsonVenue.kt │ │ ├── IrisJsonVideo.kt │ │ ├── IrisJsonVideoNote.kt │ │ ├── IrisJsonVoice.kt │ │ ├── IrisJsonVoiceChatEnded.kt │ │ ├── IrisJsonVoiceChatParticipantsInvited.kt │ │ ├── IrisJsonVoiceChatScheduled.kt │ │ ├── IrisJsonVoiceChatStarted.kt │ │ └── IrisMessageEntry.kt │ └── response │ │ ├── IrisJsonBanChatMemberResponse.kt │ │ ├── IrisJsonBooleanResponse.kt │ │ ├── IrisJsonGetChatAdministratorsResponse.kt │ │ ├── IrisJsonGetChatMemberCountResponse.kt │ │ ├── IrisJsonGetChatMemberResponse.kt │ │ ├── IrisJsonGetChatResponse.kt │ │ ├── IrisJsonGetFileResponse.kt │ │ ├── IrisJsonGetUpdatesResponse.kt │ │ ├── IrisJsonIntegerResponse.kt │ │ ├── IrisJsonResponse.kt │ │ ├── IrisJsonResponseDefault.kt │ │ └── IrisJsonSendMessageResponse.kt │ ├── keyboard │ ├── callback │ │ └── CallbackHandler.kt │ └── rrr.kt │ ├── longpoll │ ├── GetUpdateExceptionHandler.kt │ └── TgLongPoll.kt │ ├── pojo │ └── items │ │ ├── ChatLocation_Pojo.kt │ │ ├── ChatPermissions_Pojo.kt │ │ ├── Chat_Pojo.kt │ │ ├── InlineKeyboardButton_Pojo.kt │ │ ├── InlineKeyboardMarkup_Pojo.kt │ │ ├── InputMedia.kt │ │ ├── Location_Pojo.kt │ │ ├── MessageEntity_Pojo.kt │ │ ├── Message_Pojo.kt │ │ └── ReplyKeyboardRemove_Pojo.kt │ ├── processors │ ├── TgEventHandler.kt │ ├── TgUpdateExtToSimpleProcessor.kt │ ├── TgUpdateMultibotProcessor.kt │ ├── TgUpdateProcessor.kt │ ├── TgUpdateProcessor2Multibot.kt │ ├── er.kt │ ├── pack │ │ ├── TgChatMemberUpdatedFilter.kt │ │ ├── TgChatMemberUpdatedHandler.kt │ │ ├── TgChatMemberUpdatedSplitter.kt │ │ ├── TgEventMessagePackFilter.kt │ │ ├── TgEventMessagePackFilterAdapter.kt │ │ ├── TgEventMessagePackFilterHandler.kt │ │ ├── TgEventMessagePackHandler.kt │ │ ├── TgEventMessagePackHandlerAdapter.kt │ │ ├── TgEventMessagePackHandlerArray.kt │ │ ├── TgEventMessagePackHandlerList.kt │ │ ├── TgEventPackBasicType2CustomHandler.kt │ │ ├── TgEventPackFilter.kt │ │ ├── TgEventPackHandler.kt │ │ ├── TgEventPackSplitMessageHandler.kt │ │ ├── TgMessagePackFilter.kt │ │ ├── TgMessagePackHandler.kt │ │ ├── TgTextPackHandler.kt │ │ ├── TgUpdateProcessorPack.kt │ │ ├── TgUpdateProcessorPack2.kt1 │ │ └── Update2CustomPackHandler.kt │ └── single │ │ ├── TgChatMemberUpdatedSingleFilter.kt │ │ ├── TgChatMemberUpdatedSingleHandler.kt │ │ ├── TgChatMemberUpdatedSplitter.kt │ │ ├── TgEventMessageSingleFilter.kt │ │ ├── TgEventMessageSingleFilterAdapter.kt │ │ ├── TgEventMessageSingleFilterHandler.kt │ │ ├── TgEventMessageSingleHandler.kt │ │ ├── TgEventMessageSingleHandlerAdapter.kt │ │ ├── TgEventMessageSingleHandlerArray.kt │ │ ├── TgEventMessageSingleHandlerList.kt │ │ ├── TgEventSingleBasicType2CustomHandler.kt │ │ ├── TgEventSingleFilter.kt │ │ ├── TgEventSingleHandler.kt │ │ ├── TgEventSplitMessageHandler.kt │ │ ├── TgMessageSingleFilter.kt │ │ ├── TgMessageSingleHandler.kt │ │ ├── TgTextSingleHandler.kt │ │ ├── TgUpdateProcessorSingle.kt │ │ └── Update2CustomSingleHandler.kt │ ├── py │ ├── Bot.kt │ ├── PyResponseHandler.kt │ ├── PySingleHandlerConverter.kt │ ├── TriggerFilterHandlerPackPy.kt │ ├── TriggerHandlerPackPy.kt │ ├── TriggerHandlerSinglePy.kt │ ├── items │ │ ├── PyCallbackQuery.kt │ │ ├── PyItem.kt │ │ ├── PyMessage.kt │ │ └── PyUpdate.kt │ └── response │ │ ├── PyGetUpdateResponse.kt │ │ ├── PyResponse.kt │ │ └── PySendMessageResponse.kt │ ├── tg.kt │ ├── trigger │ ├── TriggerHandlerPack.kt │ ├── TriggerHandlerPackBasicTypes.kt │ ├── TriggerHandlerSingle.kt │ ├── TriggerHandlerSingleBasicTypes.kt │ ├── TriggerPack.kt │ ├── TriggerPack2Lambda.kt │ ├── TriggerPack2Single.kt │ ├── TriggerPackFilter.kt │ ├── TriggerPackFilterHandler.kt │ ├── TriggerPackFilterLambda.kt │ ├── TriggerPackFilterSingleLambda.kt │ ├── TriggerPackLambda.kt │ ├── TriggerSingle.kt │ ├── TriggerSingleFilter.kt │ ├── TriggerSingleFilterLambda.kt │ └── TriggerSingleLambda.kt │ └── webhook │ ├── AddressTester.kt │ ├── AddressTesterDefault.kt │ ├── BotSource.kt │ ├── BotSourceSimple.kt │ ├── TgWebhookBot.kt1 │ ├── TgWebhookBotBuilder.kt │ ├── TgWebhookMultibot.kt │ ├── TgWebhookMultibotBuilder.kt │ ├── TgWebhookRequestHandler.kt │ ├── TgWebhookRequestHandlerDefault.kt │ ├── TgWebhookRequestServer.kt │ └── TgWebhookRequestServerDefault.kt └── test ├── iris └── tg │ ├── examples │ ├── 10.0_py_doorway_handler.kt │ ├── 10.1_py_bottle_bot.kt │ ├── 10.2_py_custom_response_handler.kt │ ├── 1_send_message.kt │ ├── 2_send_message_future.kt │ ├── 3.0_bot_polling.kt │ ├── 3.1_bot_polling_queue.kt │ ├── 4.0_bot_webhook.kt │ ├── 4.1_multibot_webhook.kt │ ├── 5_command_handler.kt │ ├── 6_command_handler_dsl.kt │ ├── 7_command_trigger_style.kt │ ├── 8_command_trigger_style_dsl.kt │ ├── 9_callback_handler.kt │ └── Util.kt │ └── test │ ├── api │ └── sendMediaGroup.kt │ ├── query_speed.kt │ ├── read_write_buffer_default.kt │ └── simple_jsonifier │ ├── input_media.kt │ └── keyboard.kt └── ttt.kt /src/iris/connection/Connection.kt: -------------------------------------------------------------------------------- 1 | package iris.connection 2 | 3 | import iris.connection.query.Query 4 | import java.io.ByteArrayInputStream 5 | import java.io.File 6 | import java.io.InputStream 7 | import java.nio.file.Files 8 | 9 | /** 10 | * @created 07.09.2019 11 | * @author [Ivan Ivanov](https://t.me/irisism) 12 | */ 13 | interface Connection { 14 | fun request(url:String, data: Query?): Response 15 | fun request(url:String, data:String? = null): Response 16 | fun requestUpload(url:String, files:Map, data: Query? = null): Response 17 | fun requestByteArray(url: String): BinaryResponse 18 | 19 | abstract class BinaryData(var mimeType: String? = null, var fileName: String? = null) { 20 | abstract fun binary(): ByteArray 21 | abstract fun stream(): InputStream 22 | } 23 | 24 | class BinaryDataFile(val file: File, mimeType: String? = Files.probeContentType(file.toPath()), fileName: String? = file.name) : BinaryData(mimeType, fileName) { 25 | override fun binary(): ByteArray = file.readBytes() 26 | override fun stream(): InputStream = file.inputStream() 27 | } 28 | 29 | class BinaryDataByteArray(val bytes: ByteArray, mimeType: String? = null, fileName: String? = null): BinaryData(mimeType, fileName) { 30 | override fun binary(): ByteArray = bytes 31 | override fun stream(): InputStream = ByteArrayInputStream(bytes) 32 | } 33 | } -------------------------------------------------------------------------------- /src/iris/connection/ConnectionHttpClientDefault.kt: -------------------------------------------------------------------------------- 1 | package iris.connection 2 | 3 | import java.net.http.HttpClient 4 | import java.net.http.HttpRequest 5 | import java.net.http.HttpResponse 6 | 7 | /** 8 | * @created 30.10.2020 9 | * @author [Ivan Ivanov](https://t.me/irisism) 10 | */ 11 | class ConnectionHttpClientDefault(client: HttpClient, timeout: Long = 0) : ConnectionHttpClientAbstract(client, timeout) { 12 | override fun customRequest(request: HttpRequest, responseHandler: HttpResponse.BodyHandler<*>): R { 13 | return client.send(request, responseHandler).body() as R 14 | } 15 | } -------------------------------------------------------------------------------- /src/iris/connection/ConnectionHttpClientFuture.kt: -------------------------------------------------------------------------------- 1 | package iris.connection 2 | 3 | import java.net.http.HttpClient 4 | import java.net.http.HttpRequest 5 | import java.net.http.HttpResponse 6 | import java.util.concurrent.CompletableFuture 7 | 8 | /** 9 | * @created 30.10.2020 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | class ConnectionHttpClientFuture(client: HttpClient, timeout: Long = 0) : ConnectionHttpClientAbstract, CompletableFuture>(client, timeout) { 13 | 14 | override fun customRequest(request: HttpRequest, responseHandler: HttpResponse.BodyHandler<*>): R { 15 | return client.sendAsync(request, responseHandler).thenApply { it.body() } as R 16 | } 17 | } -------------------------------------------------------------------------------- /src/iris/connection/query/ArrayQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.connection.query 2 | 3 | import iris.connection.StringBuilderUrlEncoder 4 | import java.nio.charset.StandardCharsets 5 | import kotlin.math.max 6 | 7 | open class ArrayQuery(initialCapacity: Int = 16) : MutableQuery { 8 | 9 | private var keys: Array = arrayOfNulls(initialCapacity) 10 | private var values: Array = arrayOfNulls(initialCapacity) 11 | private var pointer = 0 12 | 13 | constructor(vararg pairs: Pair) : this(pairs.size) { 14 | ensureCapacity(pairs.size) 15 | for ((key, value) in pairs) { 16 | keys[pointer] = key 17 | values[pointer] = value 18 | pointer++ 19 | } 20 | } 21 | 22 | private fun ensureCapacity(minCapacity: Int) { 23 | if (minCapacity > keys.size) { 24 | val oldCapacity: Int = keys.size 25 | val newCapacity = newLength( 26 | oldCapacity, 27 | minCapacity - oldCapacity, /* minimum growth */ 28 | oldCapacity shr 1 /* preferred growth */ 29 | ) 30 | keys = keys.copyOf(newCapacity) 31 | values = values.copyOf(newCapacity) 32 | } 33 | } 34 | 35 | private fun newLength(oldLength: Int, minGrowth: Int, prefGrowth: Int): Int { 36 | val newLength = max(minGrowth, prefGrowth) + oldLength 37 | return if (newLength - Int.MAX_VALUE - 8 <= 0) { 38 | newLength 39 | } else throw OutOfMemoryError() 40 | } 41 | 42 | override fun joinTo(sb: A): A { 43 | encodeOptions(sb) 44 | return sb 45 | } 46 | 47 | override fun toString(): String { 48 | return joinTo(StringBuilder()).toString() 49 | } 50 | 51 | private fun encode(sb: StringBuilder, o: String) { 52 | StringBuilderUrlEncoder.encode(sb, o, StandardCharsets.UTF_8) 53 | } 54 | 55 | private fun encodeOptions(sb: StringBuilder) { 56 | if (pointer == 0) return 57 | for (i in 0 until pointer) { 58 | val key = keys[i]!! 59 | val value = values[i] 60 | encode(sb, key) 61 | sb.append('=') 62 | value?.apply { encode(sb, this.toString()) } 63 | sb.append("&") 64 | } 65 | } 66 | 67 | override fun set(key: String, value: Any?) { 68 | ensureCapacity(pointer + 1) 69 | keys[pointer] = key 70 | values[pointer] = value 71 | pointer++ 72 | } 73 | 74 | override fun toList(): List> { 75 | val res = ArrayList>(keys.size) 76 | for (i in 0 until pointer) { 77 | val key = keys[i]!! 78 | val value = values[i] 79 | res += key to value 80 | } 81 | return res 82 | } 83 | 84 | override fun toMap(): Map { 85 | val res = HashMap(keys.size) 86 | for (i in 0 until pointer) { 87 | val key = keys[i]!! 88 | val value = values[i] 89 | res[key] = value 90 | } 91 | return res 92 | } 93 | } -------------------------------------------------------------------------------- /src/iris/connection/query/BasicQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.connection.query 2 | 3 | import iris.connection.StringBuilderUrlEncoder 4 | import java.nio.charset.StandardCharsets 5 | 6 | open class BasicQuery(initialCapacity: Int = 5) : MutableQuery { 7 | 8 | private val keys: ArrayList = ArrayList(initialCapacity) 9 | private val values: ArrayList = ArrayList(initialCapacity) 10 | 11 | constructor(vararg pairs: Pair) : this(pairs.size) { 12 | for ((key, value) in pairs) { 13 | keys += key 14 | values += value 15 | } 16 | } 17 | 18 | override fun joinTo(sb: A): A { 19 | encodeOptions(sb) 20 | return sb 21 | } 22 | 23 | override fun toString(): String { 24 | return joinTo(StringBuilder()).toString() 25 | } 26 | 27 | private fun encode(sb: StringBuilder, o: String) { 28 | StringBuilderUrlEncoder.encode(sb, o, StandardCharsets.UTF_8) 29 | } 30 | 31 | private fun encodeOptions(sb: StringBuilder) { 32 | if (keys.isEmpty()) return 33 | for (i in keys.indices) { 34 | val key = keys[i] 35 | val value = values[i] 36 | encode(sb, key) 37 | sb.append('=') 38 | value?.apply { encode(sb, this.toString()) } 39 | sb.append("&") 40 | } 41 | } 42 | 43 | override fun set(key: String, value: Any?) { 44 | keys += key 45 | values += value 46 | } 47 | 48 | override fun toList(): List> { 49 | val res = ArrayList>(keys.size) 50 | for (i in keys.indices) { 51 | val key = keys[i] 52 | val value = values[i] 53 | res += key to value 54 | } 55 | return res 56 | } 57 | 58 | override fun toMap(): Map { 59 | val res = HashMap(keys.size) 60 | for (i in keys.indices) { 61 | val key = keys[i] 62 | val value = values[i] 63 | res[key] = value 64 | } 65 | return res 66 | } 67 | } -------------------------------------------------------------------------------- /src/iris/connection/query/MapQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.connection.query 2 | 3 | import iris.connection.StringBuilderUrlEncoder 4 | import java.nio.charset.StandardCharsets 5 | 6 | class MapQuery(val map: Map): Query { 7 | 8 | override fun joinTo(sb: A): A { 9 | encodeOptions(sb) 10 | return sb 11 | } 12 | 13 | override fun toString(): String { 14 | return joinTo(StringBuilder()).toString() 15 | } 16 | 17 | private fun encode(sb: StringBuilder, o: String) { 18 | StringBuilderUrlEncoder.encode(sb, o, StandardCharsets.UTF_8) 19 | } 20 | 21 | private fun encodeOptions(sb: StringBuilder) { 22 | if (map.isEmpty()) return 23 | for ((key, value ) in map) { 24 | encode(sb, key) 25 | sb.append('=') 26 | value?.apply { encode(sb, this.toString()) } 27 | sb.append("&") 28 | } 29 | } 30 | 31 | override fun toList(): List> { 32 | return map.toList() 33 | } 34 | 35 | override fun toMap(): Map { 36 | return map 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/iris/connection/query/PairArrayQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.connection.query 2 | 3 | import iris.connection.StringBuilderUrlEncoder 4 | import java.nio.charset.StandardCharsets 5 | import kotlin.math.max 6 | 7 | open class PairArrayQuery(initialCapacity: Int = 10) : MutableQuery { 8 | 9 | private var keys: Array?> = arrayOfNulls(initialCapacity) 10 | private var pointer = 0 11 | 12 | constructor(vararg pairs: Pair) : this(pairs.size) { 13 | ensureCapacity(pairs.size) 14 | for ((key, value) in pairs) { 15 | keys[pointer] = key to value 16 | //values[pointer] = value 17 | pointer++ 18 | } 19 | } 20 | 21 | private fun ensureCapacity(minCapacity: Int) { 22 | if (minCapacity > keys.size) { 23 | val oldCapacity: Int = keys.size 24 | val newCapacity = newLength( 25 | oldCapacity, 26 | minCapacity - oldCapacity, /* minimum growth */ 27 | oldCapacity shr 1 /* preferred growth */ 28 | ) 29 | keys = keys.copyOf(newCapacity) 30 | } 31 | } 32 | 33 | private fun newLength(oldLength: Int, minGrowth: Int, prefGrowth: Int): Int { 34 | val newLength = max(minGrowth, prefGrowth) + oldLength 35 | return if (newLength - Int.MAX_VALUE - 8 <= 0) { 36 | newLength 37 | } else throw OutOfMemoryError() 38 | } 39 | 40 | override fun joinTo(sb: A): A { 41 | encodeOptions(sb) 42 | return sb 43 | } 44 | 45 | override fun toString(): String { 46 | return joinTo(StringBuilder()).toString() 47 | } 48 | 49 | private fun encode(sb: StringBuilder, o: String) { 50 | StringBuilderUrlEncoder.encode(sb, o, StandardCharsets.UTF_8) 51 | } 52 | 53 | private fun encodeOptions(sb: StringBuilder) { 54 | if (pointer == 0) return 55 | for (i in 0 until pointer) { 56 | val key = keys[i]!! 57 | //val value = values[i] 58 | encode(sb, key.first) 59 | sb.append('=') 60 | encode(sb, key.second.toString()) 61 | sb.append("&") 62 | } 63 | } 64 | 65 | override fun set(key: String, value: Any?) { 66 | ensureCapacity(pointer + 1) 67 | keys[pointer] = key to value 68 | //values[pointer] = value 69 | pointer++ 70 | } 71 | 72 | override fun toList(): List> { 73 | val res = ArrayList>(keys.size) 74 | for (i in 0 until pointer) 75 | res += keys[i]!! 76 | return res 77 | } 78 | 79 | override fun toMap(): Map { 80 | val res = HashMap(keys.size) 81 | for (i in 0 until pointer) 82 | res += keys[i]!! 83 | return res 84 | } 85 | } -------------------------------------------------------------------------------- /src/iris/connection/query/PairQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.connection.query 2 | 3 | import iris.connection.StringBuilderUrlEncoder 4 | import java.nio.charset.StandardCharsets 5 | 6 | open class PairQuery(initialCapacity: Int = 5) : MutableQuery { 7 | 8 | private val list: ArrayList> = ArrayList(initialCapacity) 9 | 10 | constructor(vararg pairs: Pair) : this(pairs.size) { 11 | list += pairs 12 | } 13 | 14 | override fun joinTo(sb: A): A { 15 | encodeOptions(sb) 16 | return sb 17 | } 18 | 19 | override fun toString(): String { 20 | return joinTo(StringBuilder()).toString() 21 | } 22 | 23 | private fun encode(sb: StringBuilder, o: String) { 24 | StringBuilderUrlEncoder.encode(sb, o, StandardCharsets.UTF_8) 25 | } 26 | 27 | private fun encodeOptions(sb: StringBuilder) { 28 | if (list.isEmpty()) return 29 | for ((key, value) in list) { 30 | encode(sb, key as String) 31 | sb.append('=') 32 | value?.apply { encode(sb, this.toString()) } 33 | sb.append("&") 34 | } 35 | } 36 | 37 | override fun set(key: String, value: Any?) { 38 | list += key to value 39 | } 40 | 41 | override fun toList(): List> { 42 | return list 43 | } 44 | 45 | override fun toMap(): Map { 46 | return list.toMap() 47 | } 48 | } -------------------------------------------------------------------------------- /src/iris/connection/query/Query.kt: -------------------------------------------------------------------------------- 1 | package iris.connection.query 2 | 3 | import java.net.URLEncoder 4 | import java.nio.charset.StandardCharsets 5 | 6 | /** 7 | * @created 11.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | interface Query { 11 | fun joinTo(sb: A): A 12 | fun toList(): List> 13 | fun toMap(): Map 14 | 15 | companion object { 16 | fun encode(o: String): String? { 17 | return URLEncoder.encode(o, StandardCharsets.UTF_8) 18 | } 19 | } 20 | } 21 | 22 | interface MutableQuery : Query { 23 | operator fun set(key: String, value: Any?) 24 | } 25 | 26 | fun query(key: String, value: Any?): Query = SinglePairQuery(key, value) 27 | 28 | fun query(pair: Pair): Query = SinglePairQuery(pair.first, pair.second) 29 | 30 | fun query(vararg items: Pair): Query { 31 | // Обычно элементов меньше 8, поэтому лучше создать массив под количество передаваемых элементов 32 | return RowArrayQuery(items.size, *items) 33 | } 34 | 35 | fun mutableQuery(): MutableQuery = PairArrayQuery() 36 | 37 | // TODO: А здесь лучше по одному перенести в basic query или так пойдёт? Говорят такое `*items` клонирует массив 38 | fun mutableQuery(vararg items: Pair): MutableQuery = RowArrayQuery(*items) 39 | 40 | fun mutableQuery(initialCapacity: Int, vararg items: Pair): MutableQuery = RowArrayQuery(initialCapacity, *items) 41 | 42 | fun mutableQuery(initialCapacity: Int): MutableQuery = RowArrayQuery(initialCapacity) 43 | -------------------------------------------------------------------------------- /src/iris/connection/query/SinglePairQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.connection.query 2 | 3 | import iris.connection.StringBuilderUrlEncoder 4 | import java.nio.charset.StandardCharsets 5 | 6 | class SinglePairQuery(val key: String, val value: Any?): Query { 7 | 8 | override fun joinTo(sb: A): A { 9 | encodeOptions(sb) 10 | return sb 11 | } 12 | 13 | override fun toString(): String { 14 | return joinTo(StringBuilder()).toString() 15 | } 16 | 17 | private fun encode(sb: StringBuilder, o: String) { 18 | StringBuilderUrlEncoder.encode(sb, o, StandardCharsets.UTF_8) 19 | } 20 | 21 | private fun encodeOptions(sb: StringBuilder) { 22 | encode(sb, key) 23 | sb.append('=') 24 | value?.apply { encode(sb, this.toString()) } 25 | } 26 | 27 | override fun toList(): List> { 28 | return listOf(key to value) 29 | } 30 | 31 | override fun toMap(): Map { 32 | return mapOf(key to value) 33 | } 34 | } -------------------------------------------------------------------------------- /src/iris/tg/TgReadWriteProcessor.kt: -------------------------------------------------------------------------------- 1 | package iris.tg 2 | 3 | import iris.tg.processors.TgUpdateProcessor 4 | 5 | /** 6 | * @created 02.11.2020 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class TgReadWriteProcessor( 10 | private val buffer: TgReadWriteUpdateBuffer, 11 | private val updateProcessor: TgUpdateProcessor 12 | ) : Runnable { 13 | 14 | private var working = true 15 | 16 | override fun run() { 17 | working = true 18 | val thisThread = thread ?: Thread.currentThread() 19 | while (!thisThread.isInterrupted && working) { 20 | val items = buffer.readAll() 21 | if (items.isEmpty()) continue 22 | updateProcessor.processUpdates(items) 23 | } 24 | } 25 | 26 | private var thread: Thread? = null 27 | 28 | fun startPolling() { 29 | stop() 30 | thread = Thread(this).also { it.start() } 31 | } 32 | 33 | fun stop() { 34 | working = false 35 | if (thread != null) { 36 | thread!!.interrupt() 37 | thread = null 38 | } 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /src/iris/tg/TgReadWriteUpdateBuffer.kt: -------------------------------------------------------------------------------- 1 | package iris.tg 2 | 3 | /** 4 | * @created 26.12.2020 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TgReadWriteUpdateBuffer : TgUpdateWriter, TgReadable { 8 | 9 | } -------------------------------------------------------------------------------- /src/iris/tg/TgReadable.kt: -------------------------------------------------------------------------------- 1 | package iris.tg 2 | 3 | /** 4 | * @created 02.12.2019 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TgReadable { 8 | fun readAll(wait: Boolean = true): List 9 | fun read(limit: Int = 0, wait: Boolean = true): List 10 | fun read(dest: MutableList, limit: Int = 0, wait: Boolean = true): Int 11 | } -------------------------------------------------------------------------------- /src/iris/tg/TgUpdateWriter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg 2 | 3 | 4 | interface TgUpdateWriter { 5 | fun write(event: T) 6 | fun write(events: List) 7 | fun write(events: Array) 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/Jsonifier.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api 2 | 3 | import iris.tg.api.items.ChatPermissions 4 | import iris.tg.api.items.InputMedia 5 | import iris.tg.api.items.MessageEntity 6 | import iris.tg.api.items.ReplyMarkup 7 | 8 | interface Jsonifier { 9 | fun entities(entities: List): String 10 | fun replyMarkup(replyMarkup: ReplyMarkup): String 11 | fun chatPermissions(permissions: ChatPermissions): String 12 | fun array2JsonString(array: Array): String 13 | fun array2JsonString(array: List): String 14 | fun inputMedia(inputMedia: List): String 15 | } -------------------------------------------------------------------------------- /src/iris/tg/api/MediaGroupBuilder.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api 2 | 3 | import iris.tg.api.items.InputMedia 4 | import iris.tg.api.items.MessageEntity 5 | import iris.connection.Connection 6 | import iris.tg.pojo.items.InputMediaAnimation_Pojo 7 | import iris.tg.pojo.items.InputMediaDocument_Pojo 8 | import iris.tg.pojo.items.InputMediaPhoto_Pojo 9 | import iris.tg.pojo.items.InputMediaVideo_Pojo 10 | import java.io.File 11 | 12 | /** 13 | * @created 11.02.2022 14 | * @author [Ivan Ivanov](https://t.me/irisism) 15 | */ 16 | class MediaGroupBuilder { 17 | private val items = mutableListOf() 18 | 19 | fun animation(media: String? = null, caption: String? = null, parse_mode: String? = null 20 | , caption_entities: List? = null, data: Connection.BinaryData? = null 21 | , thumb: String? = null, thumbData: Connection.BinaryData? = null 22 | , width: Int, height: Int, duration: Int) { 23 | items += InputMediaAnimation_Pojo(media, caption, parse_mode, caption_entities, data, thumb, thumbData, width, height, duration) 24 | } 25 | fun video(media: String? = null, caption: String? = null, parse_mode: String? = null 26 | , caption_entities: List? = null, data: Connection.BinaryData? = null 27 | , thumb: String? = null, thumbData: Connection.BinaryData? = null 28 | , width: Int = 0, height: Int = 0, duration: Int = 0 29 | , supports_streaming: Boolean? = null 30 | ) { 31 | items += InputMediaVideo_Pojo(media, caption, parse_mode, caption_entities, data, thumb, thumbData, width, height, duration, supports_streaming) 32 | } 33 | fun document(media: String? = null, caption: String? = null, parse_mode: String? = null 34 | , caption_entities: List? = null, data: Connection.BinaryData? = null 35 | , thumb: String? = null, thumbData: Connection.BinaryData? = null 36 | , disable_content_type_detection: Boolean = false 37 | ) { 38 | items += InputMediaDocument_Pojo(media, caption, parse_mode, caption_entities, data, thumb, thumbData, disable_content_type_detection) 39 | } 40 | fun photo(media: String? = null, caption: String? = null, parse_mode: String? = null 41 | , caption_entities: List? = null, data: Connection.BinaryData? = null 42 | ) { 43 | items += InputMediaPhoto_Pojo(media, caption, parse_mode, caption_entities, data) 44 | } 45 | 46 | fun other(item: InputMedia) { 47 | items += item 48 | } 49 | 50 | fun binary(bytes: ByteArray) : Connection.BinaryData { 51 | return Connection.BinaryDataByteArray(bytes) 52 | } 53 | 54 | fun binary(file: String) : Connection.BinaryData { 55 | return binary(File(file)) 56 | } 57 | 58 | fun binary(file: File) : Connection.BinaryData { 59 | return Connection.BinaryDataFile(file) 60 | } 61 | 62 | fun build(initializer: MediaGroupBuilder.() -> Unit): List { 63 | return MediaGroupBuilder().apply(initializer).items 64 | } 65 | } -------------------------------------------------------------------------------- /src/iris/tg/api/ResponseHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api 2 | 3 | import java.io.InputStream 4 | 5 | interface ResponseHandler { 6 | fun process(method: String, data: String?): ResponseType 7 | fun process(method: String, inputStream: InputStream): ResponseType 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/SendDefaults.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api 2 | 3 | /** 4 | * @created 12.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | class SendDefaults { 8 | var parseMode: String? = null 9 | var disableWebPagePreview = false 10 | var disableNotification = false 11 | var protectContent = false 12 | var allowSendingWithoutReply = false 13 | } -------------------------------------------------------------------------------- /src/iris/tg/api/TgApi.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api 2 | 3 | import iris.connection.Connection 4 | import iris.connection.ConnectionHttpClientDefault 5 | import iris.connection.query.Query 6 | import java.net.http.HttpClient 7 | 8 | /** 9 | * @created 25.01.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class TgApi(token: String, 13 | private val responseHandler: ResponseHandler, 14 | apiPath: String? = null, 15 | connection: Connection? = null 16 | ) : TgApiAbstract(token, apiPath) { 17 | 18 | private val connection = connection ?: ConnectionHttpClientDefault(HttpClient.newHttpClient()) 19 | 20 | override fun requestImpl(url: String, method: String, options: Query?): T { 21 | return connection.request(url, options) 22 | .let { responseHandler.process(method, it) } 23 | } 24 | 25 | override fun requestUploadImpl(url: String, method: String, files: Map, options: Query?): T { 26 | return connection.requestUpload(url, files, options) 27 | .let { responseHandler.process(method, it) } 28 | } 29 | } -------------------------------------------------------------------------------- /src/iris/tg/api/TgApiFuture.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api 2 | 3 | import iris.connection.Connection 4 | import iris.connection.ConnectionHttpClientFuture 5 | import iris.connection.query.Query 6 | import java.net.http.HttpClient 7 | import java.util.concurrent.CompletableFuture 8 | 9 | /** 10 | * @created 25.01.2022 11 | * @author [Ivan Ivanov](https://t.me/irisism) 12 | */ 13 | open class TgApiFuture(token: String, 14 | private val responseHandler: ResponseHandler, 15 | apiPath: String? = null, 16 | connection: Connection, CompletableFuture>? = null 17 | ) : TgApiAbstract>(token, apiPath) { 18 | 19 | private val connection = connection ?: ConnectionHttpClientFuture(HttpClient.newHttpClient()) 20 | 21 | override fun requestImpl(url: String, method: String, options: Query?): CompletableFuture { 22 | return connection.request(url, options) 23 | .thenApply {responseHandler.process(method, it) } 24 | } 25 | 26 | override fun requestUploadImpl(url: String, method: String, files: Map, options: Query?): CompletableFuture { 27 | return connection.requestUpload(url, files, options) 28 | .thenApply {responseHandler.process(method, it) } 29 | } 30 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Animation.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Animation { 8 | val file_id: String 9 | val file_unique_id: String 10 | /** Video width as defined by sender */ 11 | val width: Int 12 | /** Video height as defined by sender */ 13 | val height: Int 14 | /** Duration of the video in seconds as defined by sender */ 15 | val duration: Int 16 | /** Optional. Animation thumbnail as defined by sender */ 17 | val thumb: PhotoSize? 18 | /** Optional. Original animation filename as defined by sender */ 19 | val file_name: String? 20 | /** Optional. MIME type of the file as defined by sender */ 21 | val mime_type: String? 22 | /** Optional. File size in bytes */ 23 | val file_size: Int 24 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Audio.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Audio { 8 | /** Identifier for this file, which can be used to download or reuse the file */ 9 | val file_id: String 10 | 11 | /** Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file. */ 12 | val file_unique_id: String 13 | 14 | /** Duration of the audio in seconds as defined by sender */ 15 | val duration: Int 16 | 17 | /** Optional. Performer of the audio as defined by sender or by audio tags */ 18 | val performer: String? 19 | 20 | /** Optional. Title of the audio as defined by sender or by audio tags */ 21 | val title: String? 22 | 23 | /** Optional. Original filename as defined by sender */ 24 | val file_name: String? 25 | 26 | /** Optional. MIME type of the file as defined by sender */ 27 | val mime_type: String? 28 | 29 | /** Optional. File size in bytes */ 30 | val file_size: Int 31 | 32 | /** Optional. Thumbnail of the album cover to which the music file belongs */ 33 | val thumb: PhotoSize? 34 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/CallbackGame.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface CallbackGame { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/CallbackQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface CallbackQuery { 8 | val id: String 9 | val from: User 10 | val message: Message? 11 | val inlineMessageId: String? 12 | val chatInstance: String 13 | val data: String? 14 | val gameShortName: String? 15 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Chat.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Chat { 8 | val id: Long 9 | val type: String 10 | val title: String? 11 | val username: String? 12 | val firstName: String? 13 | val lastName: String? 14 | val photo: ChatPhoto? 15 | val bio: String? 16 | val hasPrivateForwards: Boolean 17 | val description: String? 18 | val inviteLink: String? 19 | val pinnedMessage: Message? 20 | val permissions: ChatPermissions? 21 | val slowModeDelay: Int 22 | val messageAutoDeleteTime: Int 23 | val hasProtectedContent: Boolean 24 | val stickerSetName: String? 25 | val canSetStickerSet: Boolean 26 | val linkedChatId: Long 27 | val location: ChatLocation? 28 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChatInviteLink.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ChatInviteLink { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChatJoinRequest.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ChatJoinRequest { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChatLocation.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface ChatLocation { 4 | /** The location to which the supergroup is connected. Can't be a live location. */ 5 | val location: Location 6 | 7 | /** Location address; 1-64 characters, as defined by the chat owner */ 8 | val address: String 9 | } 10 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChatMember.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.irisjson.items.* 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | interface ChatMember { 11 | val status: String 12 | val user: User 13 | } 14 | 15 | interface ChatMemberOwner : ChatMember { 16 | val isAnonymous: Boolean 17 | val customTitle: String? 18 | } 19 | 20 | interface ChatMemberAdministrator : ChatMember { 21 | val canBeEdited: Boolean 22 | val isAnonymous: Boolean 23 | val canManageChat: Boolean 24 | val canDeleteMessages: Boolean 25 | val canManageVoiceChats: Boolean 26 | val canRestrictMembers: Boolean 27 | val canPromoteMembers: Boolean 28 | val canChangeInfo: Boolean 29 | val canInviteUsers: Boolean 30 | val canPostMessages: Boolean 31 | val canEditMessages: Boolean 32 | val canPinMessages: Boolean 33 | val customTitle: Boolean 34 | } 35 | 36 | interface ChatMemberMember : ChatMember { 37 | 38 | } 39 | 40 | interface ChatMemberRestricted: ChatMember { 41 | val isMember: Boolean 42 | val canChangeInfo: Boolean 43 | val canInviteUsers: Boolean 44 | val canPinMessages: Boolean 45 | val canSendMessages: Boolean 46 | val canSendMediaMessages: Boolean 47 | val canSendPolls: Boolean 48 | val canSendOtherMessages: Boolean 49 | val canAddWebPagePreviews: Boolean 50 | val untilDate: Long 51 | } 52 | 53 | interface ChatMemberLeft : ChatMember { 54 | 55 | } 56 | 57 | interface ChatMemberBanned: ChatMember { 58 | val untilDate: Long 59 | } 60 | 61 | object IrisJsonChatMemberFactory { 62 | fun create(it: JsonItem): IrisJsonChatMember = when (it["status"].asString()) { 63 | "creator" -> IrisJsonChatMemberOwner(it) 64 | "administrator" -> IrisJsonChatMemberAdministrator(it) 65 | "member" -> IrisJsonChatMemberMember(it) 66 | "restricted" -> IrisJsonChatMemberRestricted(it) 67 | "left" -> IrisJsonChatMemberLeft(it) 68 | "kicked" -> IrisJsonChatMemberBanned(it) 69 | else -> throw IllegalArgumentException("") 70 | } 71 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChatMemberUpdated.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface ChatMemberUpdated { 4 | val chat: Chat 5 | val from: User 6 | val date: Long 7 | val oldChatMember: ChatMember 8 | val newChatMember: ChatMember 9 | val invite_link: ChatInviteLink? 10 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChatPermissions.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface ChatPermissions { 4 | /** Optional. True, if the user is allowed to send text messages, contacts, locations and venues */ 5 | val can_send_messages: Boolean? 6 | 7 | /** Optional. True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages */ 8 | val can_send_media_messages: Boolean? 9 | 10 | /** Optional. True, if the user is allowed to send polls, implies can_send_messages */ 11 | val can_send_polls: Boolean? 12 | 13 | /** Optional. True, if the user is allowed to send animations, games, stickers and use inline bots, implies can_send_media_messages */ 14 | val can_send_other_messages: Boolean? 15 | 16 | /** Optional. True, if the user is allowed to add web page previews to their messages, implies can_send_media_messages */ 17 | val can_add_web_page_previews: Boolean? 18 | 19 | /** Optional. True, if the user is allowed to change the chat title, photo and other settings. Ignored in public supergroups */ 20 | val can_change_info: Boolean? 21 | 22 | /** Optional. True, if the user is allowed to invite new users to the chat */ 23 | val can_invite_users: Boolean? 24 | 25 | /** Optional. True, if the user is allowed to pin messages. Ignored in public supergroups */ 26 | val can_pin_messages: Boolean? 27 | } 28 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChatPhoto.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface ChatPhoto { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/ChosenInlineResult.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ChosenInlineResult { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Contact.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Contact { 8 | /** Contact's phone number */ 9 | val phone_number: String 10 | 11 | /** Contact's first name */ 12 | val first_name: String 13 | 14 | /** Optional. Contact's last name */ 15 | val last_name: String? 16 | 17 | /** Optional. Contact's user identifier in Telegram. This number may have more than 32 significant bits and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a 64-bit integer or double-precision float type are safe for storing this identifier. */ 18 | val user_id: Long 19 | 20 | /** Optional. Additional data about the contact in the form of a vCard */ 21 | val vcard: String? 22 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Dice.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Dice { 8 | /** Emoji on which the dice throw animation is based */ 9 | val emoji: String 10 | 11 | /** Value of the dice, 1-6 for “🎲”, “🎯” and “🎳” base emoji, 1-5 for “🏀” and “⚽” base emoji, 1-64 for “🎰” base emoji */ 12 | val value: Int 13 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Document.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Document { 8 | /** Identifier for this file, which can be used to download or reuse the file */ 9 | val file_id: String 10 | 11 | /** Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file. */ 12 | val file_unique_id: String 13 | 14 | /** Optional. Document thumbnail as defined by sender */ 15 | val thumb: PhotoSize? 16 | 17 | /** Optional. Original filename as defined by sender */ 18 | val file_name: String? 19 | 20 | /** Optional. MIME type of the file as defined by sender */ 21 | val mime_type: String? 22 | 23 | /** Optional. File size in bytes */ 24 | val file_size: Int 25 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/EncryptedCredentials.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface EncryptedCredentials { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/EncryptedPassportElement.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface EncryptedPassportElement { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/Error.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Error { 8 | val errorCode: Int 9 | val description: String 10 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/File.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface File { 8 | val fileId: String 9 | val fileUniqueId: String 10 | val fileSize: Int 11 | val filePath: String? 12 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ForceReply.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 07.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ForceReply : ReplyMarkup { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Game.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Game { 8 | /** Title of the game */ 9 | val title: String 10 | 11 | /** Description of the game */ 12 | val description: String 13 | 14 | /** Photo that will be displayed in the game message in chats. */ 15 | val photo: List 16 | 17 | /** Optional. Brief description of the game or high scores included in the game message. Can be automatically edited to include current high scores for the game when the botData calls setGameScore, or manually edited using editMessageText. 0-4096 characters. */ 18 | val text: String? 19 | 20 | /** Optional. Special entities that appear in text, such as usernames, URLs, botData commands, etc. */ 21 | val text_entities: List? 22 | 23 | /** Optional. Animation that will be displayed in the game message in chats. Upload via BotFather */ 24 | val animation: Animation? 25 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/InlineKeyboardButton.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface InlineKeyboardButton { 4 | 5 | /** Label text on the button */ 6 | val text: String 7 | 8 | /** Optional. HTTP or tg:// url to be opened when the button is pressed. Links tg://user?id= can be used to mention a user by their ID without using a username, if this is allowed by their privacy settings. */ 9 | val url: String? 10 | 11 | /** Optional. An HTTP URL used to automatically authorize the user. Can be used as a replacement for the Telegram Login Widget. */ 12 | val login_url: LoginUrl? 13 | 14 | /** Optional. Data to be sent in a callback query to the botData when button is pressed, 1-64 bytes */ 15 | val callback_data: String? 16 | 17 | /** Optional. If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the botData's username and the specified inline query in the input field. Can be empty, in which case just the botData's username will be inserted. 18 | 19 | Note: This offers an easy way for users to start using your botData in inline mode when they are currently in a private chat with it. Especially useful when combined with switch_pm… actions – in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen. 20 | switch_inline_query_current_chat String Optional. If set, pressing the button will insert the botData's username and the specified inline query in the current chat's input field. Can be empty, in which case only the botData's username will be inserted. 21 | 22 | This offers a quick way for the user to open your botData in inline mode in the same chat – good for selecting something from multiple options. */ 23 | val switch_inline_query: String? 24 | 25 | /** Optional. Description of the game that will be launched when the user presses the button. 26 | 27 | NOTE: This type of button must always be the first button in the first row. 28 | */ 29 | val callback_game: CallbackGame? 30 | 31 | 32 | /** Optional. Specify True, to send a Pay button. 33 | 34 | NOTE: This type of button must always be the first button in the first row and can only be used in invoice messages. */ 35 | val pay: Boolean 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/InlineKeyboardMarkup.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface InlineKeyboardMarkup : ReplyMarkup { 8 | /** Array of button rows, each represented by an Array of InlineKeyboardButton objects */ 9 | val inline_keyboard: List> 10 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/InlineQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface InlineQuery { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/InputMediaAudio.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | import iris.connection.Connection 4 | 5 | /** 6 | * @created 10.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | 10 | interface InputMedia { 11 | /** Type of the result, must be photo */ 12 | val type: String 13 | 14 | /** File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass “attach://” to upload a new one using multipart/form-data under name. More info on Sending Files » */ 15 | var media: String? 16 | 17 | /** Optional. Caption of the photo to be sent, 0-1024 characters after entities parsing */ 18 | val caption: String? 19 | 20 | /** Optional. Mode for parsing entities in the photo caption. See formatting options for more details. */ 21 | val parse_mode: String? 22 | 23 | /** Optional. List of special entities that appear in the caption, which can be specified instead of parse_mode */ 24 | val caption_entities: List? 25 | 26 | 27 | /** Iris-TG-Api specific field */ 28 | val data: Connection.BinaryData? 29 | } 30 | 31 | interface InputMediaThumbable : InputMedia { 32 | /** Optional. Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under . More info on Sending Files » */ 33 | var thumb: String? 34 | 35 | /** Iris-TG-Api specific field */ 36 | val thumbData: Connection.BinaryData? 37 | } 38 | 39 | interface InputMediaAudio : InputMediaThumbable { 40 | 41 | /** Optional. Duration of the audio in seconds */ 42 | val duration: Int 43 | 44 | /** Optional. Performer of the audio */ 45 | val performer: String? 46 | 47 | /** Optional. Title of the audio */ 48 | val title: String? 49 | } 50 | 51 | interface InputMediaDocument : InputMediaThumbable { 52 | /** Optional. Disables automatic server-side content type detection for files uploaded using multipart/form-data. Always True, if the document is sent as part of an album. */ 53 | val disable_content_type_detection: Boolean 54 | } 55 | 56 | interface InputMediaPhoto : InputMedia { 57 | 58 | 59 | 60 | } 61 | 62 | interface InputMediaAnimation : InputMediaThumbable { 63 | /** Optional. Video width */ 64 | val width: Int 65 | 66 | /** Optional. Video height */ 67 | val height: Int 68 | 69 | /** Optional. Video duration in seconds */ 70 | val duration: Int 71 | } 72 | 73 | interface InputMediaVideo : InputMediaAnimation { 74 | 75 | /** Optional. Pass True, if the uploaded video is suitable for streaming */ 76 | val supports_streaming: Boolean? 77 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Invoice.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Invoice { 8 | /** Product name */ 9 | val title: String 10 | 11 | /** Product description */ 12 | val description: String 13 | 14 | /** Unique botData deep-linking parameter that can be used to generate this invoice */ 15 | val start_parameter: String 16 | 17 | /** Three-letter ISO 4217 currency code */ 18 | val currency: String 19 | 20 | /** Total price in the smallest units of the currency (integer, not float/double). For example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in currencies.json, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). */ 21 | val total_amount: Int 22 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Location.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Location { 8 | 9 | /** Longitude as defined by sender */ 10 | val longitude: Float 11 | 12 | /** Latitude as defined by sender */ 13 | val latitude: Float 14 | 15 | /** Optional. The radius of uncertainty for the location, measured in meters; 0-1500 */ 16 | val horizontal_accuracy: Float 17 | 18 | /** Optional. Time relative to the message sending date, during which the location can be updated; in seconds. For active live locations only. */ 19 | val live_period: Int 20 | 21 | /** Optional. The direction in which user is moving, in degrees; 1-360. For active live locations only. */ 22 | val heading: Int 23 | 24 | /** Optional. Maximum distance for proximity alerts about approaching another chat member, in meters. For sent live locations only. */ 25 | val proximity_alert_radius: Int 26 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/LoginUrl.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface LoginUrl { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/MaskPosition.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface MaskPosition: TgItem { 4 | val point: String 5 | val x_shift: Float 6 | val y_shift: Float 7 | val scale: Float 8 | } 9 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/Message.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Message : TgItem { 8 | val messageId: Int 9 | val from: User? 10 | val senderChat: Chat? 11 | val date: Long 12 | val chat: Chat 13 | val forwardFrom: User? 14 | val forwardFromChat: Chat? 15 | val forwardFromMessageId: Int 16 | val forwardSignature: String? 17 | val forwardSenderName: String? 18 | val forwardDate: Int 19 | val isAutomaticForward: Boolean 20 | val replyToMessage: Message? 21 | val viaBot: User? 22 | val editDate: Int 23 | val hasProtectedContent: Boolean 24 | val mediaGroupId: String? 25 | val authorSignature: String? 26 | val text: String? 27 | val entities: List? 28 | val animation: Animation? 29 | val audio: Audio? 30 | val document: Document? 31 | val photo: List? 32 | val sticker: Sticker? 33 | val video: Video? 34 | val videoNote: VideoNote? 35 | val voice: Voice? 36 | val caption: String? 37 | val captionEntities: List? 38 | val contact: Contact? 39 | val dice: Dice? 40 | val game: Game? 41 | val poll: Poll? 42 | val venue: Venue? 43 | val location: Location? 44 | val newChatMembers: List? 45 | val leftChatMember: User? 46 | val newChatTitle: String? 47 | val newChatPhoto: List? 48 | val deleteChatPhoto: Boolean 49 | val groupChatCreated: Boolean 50 | val supergroupChatCreated: Boolean 51 | val channelChatCreated: Boolean 52 | val messageAutoDeleteTimerChanged: MessageAutoDeleteTimerChanged? 53 | val migrateToChatId: Long 54 | val migrateFromChatId: Long 55 | val pinnedMessage: Message? 56 | val invoice: Invoice? 57 | val successfulPayment: SuccessfulPayment? 58 | val connectedWebsite: String? 59 | val passportData: PassportData? 60 | val proximityAlertTriggered: ProximityAlertTriggered? 61 | val voiceChatScheduled: VoiceChatScheduled? 62 | val voiceChatStarted: VoiceChatStarted? 63 | val voiceChatEnded: VoiceChatEnded? 64 | val voiceChatParticipantsInvited: VoiceChatParticipantsInvited? 65 | val replyMarkup: InlineKeyboardMarkup? 66 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/MessageAutoDeleteTimerChanged.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface MessageAutoDeleteTimerChanged { 8 | /** New auto-delete time for messages in the chat; in seconds */ 9 | val message_auto_delete_time: Int 10 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/MessageEntity.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface MessageEntity : TgItem { 8 | val type: String 9 | val offset: Int 10 | val length: Int 11 | val url: String? 12 | val user: User? 13 | val language: String? 14 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/PassportData.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface PassportData { 8 | 9 | /** Array with information about documents and other Telegram Passport elements that was shared with the botData */ 10 | val data: List 11 | 12 | /** Encrypted credentials required to decrypt the data */ 13 | val credentials: EncryptedCredentials 14 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/PhotoSize.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface PhotoSize { 8 | val fileId: String 9 | val fileUniqueId: String 10 | val width: Int 11 | val height: Int 12 | val fileSize: Int 13 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Poll.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Poll { 8 | /** Unique poll identifier */ 9 | val id: String 10 | 11 | /** Poll question, 1-300 characters */ 12 | val question: String 13 | 14 | /** List of poll options */ 15 | val options: List 16 | 17 | /** Total number of users that voted in the poll */ 18 | val total_voter_count: Int 19 | 20 | /** True, if the poll is closed */ 21 | val is_closed: Boolean 22 | 23 | /** True, if the poll is anonymous */ 24 | val is_anonymous: Boolean 25 | 26 | /** Poll type, currently can be “regular” or “quiz” */ 27 | val type: String 28 | 29 | /** True, if the poll allows multiple answers */ 30 | val allows_multiple_answers: Boolean 31 | 32 | /** Optional. 0-based identifier of the correct answer option. Available only for polls in the quiz mode, which are closed, or was sent (not forwarded) by the botData or to the private chat with the botData. */ 33 | val correct_option_id: Int 34 | 35 | /** Optional. Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters */ 36 | val explanation: String? 37 | 38 | /** Optional. Special entities like usernames, URLs, botData commands, etc. that appear in the explanation */ 39 | val explanation_entities: List? 40 | 41 | /** Optional. Amount of time in seconds the poll will be active after creation */ 42 | val open_period: Int 43 | 44 | /** Optional. Point in time (Unix timestamp) when the poll will be automatically closed */ 45 | val close_date: Int 46 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/PollAnswer.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface PollAnswer { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/PollOption.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface PollOption { 4 | /** Option text, 1-100 characters */ 5 | val text: String 6 | /** Number of users that voted for this option */ 7 | val voter_count: Int 8 | } 9 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/PreCheckoutQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface PreCheckoutQuery { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ProximityAlertTriggered.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ProximityAlertTriggered { 8 | 9 | /** User that triggered the alert */ 10 | val traveler: User 11 | 12 | /** User that set the alert */ 13 | val watcher: User 14 | 15 | /** The distance between the users */ 16 | val distance: Int 17 | 18 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ReplyKeyboardMarkup.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 07.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ReplyKeyboardMarkup : ReplyMarkup { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ReplyKeyboardRemove.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 07.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ReplyKeyboardRemove : ReplyMarkup { 8 | val remove_keyboard: Boolean 9 | val selective: Boolean 10 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/ReplyMarkup.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | interface ReplyMarkup { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/iris/tg/api/items/ShippingQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface ShippingQuery { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Sticker.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Sticker { 8 | val file_id: String 9 | val file_unique_id: String 10 | val width: Int 11 | val height: Int 12 | val is_animated: Boolean 13 | val is_video: Boolean 14 | val thumb: PhotoSize? 15 | val emoji: String? 16 | val set_name: String? 17 | val mask_position: MaskPosition? 18 | val file_size: Int 19 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/SuccessfulPayment.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface SuccessfulPayment { 8 | 9 | /** Three-letter ISO 4217 currency code */ 10 | val currency: String 11 | 12 | /** Total price in the smallest units of the currency (integer, not float/double). For example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in currencies.json, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). */ 13 | val total_amount: Int 14 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/TgItem.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TgItem { 8 | 9 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Update.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Update : TgItem { 8 | val updateId: Long 9 | val message: Message? 10 | val editedMessage: Message? 11 | val channelPost: Message? 12 | val editedChannelPost: Message? 13 | val inlineQuery: InlineQuery? 14 | val chosenInlineResult: ChosenInlineResult? 15 | val callbackQuery: CallbackQuery? 16 | val shippingQuery: ShippingQuery? 17 | val preCheckoutQuery: PreCheckoutQuery? 18 | val poll: Poll? 19 | val pollAnswer: PollAnswer? 20 | val myChatMember: ChatMemberUpdated? 21 | val chatMember: ChatMemberUpdated? 22 | val chatJoinRequest: ChatJoinRequest? 23 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/UpdateExt.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | import iris.tg.webhook.BotSource 4 | 5 | /** 6 | * @created 04.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class UpdateExt(val update: Update, val forBot: BotSource.BotData) -------------------------------------------------------------------------------- /src/iris/tg/api/items/User.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface User { 8 | val id: Long 9 | val isBot: Boolean 10 | val firstName: String 11 | val lastName: String? 12 | val username: String? 13 | val languageCode: String? 14 | val canJoinGroups: Boolean 15 | val canReadAllGroupMessages: Boolean 16 | val supportsInlineQueries: Boolean 17 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Venue.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Venue { 8 | /** Venue location. Can't be a live location*/ 9 | val location: Location 10 | 11 | /** Name of the venue */ 12 | val title: String 13 | 14 | /** Address of the venue */ 15 | val address: String 16 | 17 | /** Optional. Foursquare identifier of the venue */ 18 | val foursquare_id: String? 19 | 20 | /** Optional. Foursquare type of the venue. (For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.) */ 21 | val foursquare_type: String? 22 | 23 | /** Optional. Google Places identifier of the venue */ 24 | val google_place_id: String? 25 | 26 | /** Optional. Google Places type of the venue. (See supported types.) */ 27 | val google_place_type: String? 28 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Video.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Video { 8 | /** Identifier for this file, which can be used to download or reuse the file */ 9 | val file_id: String 10 | 11 | /** Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file. */ 12 | val file_unique_id: String 13 | 14 | /** Video width as defined by sender */ 15 | val width: Int 16 | 17 | /** Video height as defined by sender */ 18 | val height: Int 19 | 20 | /** Duration of the video in seconds as defined by sender */ 21 | val duration: Int 22 | 23 | /** Optional. Video thumbnail */ 24 | val thumb: PhotoSize? 25 | 26 | /** Optional. Original filename as defined by sender */ 27 | val file_name: String? 28 | 29 | /** Optional. Mime type of a file as defined by sender */ 30 | val mime_type: String? 31 | 32 | /** Optional. File size in bytes */ 33 | val file_size: Int 34 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/VideoNote.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface VideoNote { 8 | /** Identifier for this file, which can be used to download or reuse the file*/ 9 | val file_id: String 10 | 11 | /** Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file.*/ 12 | val file_unique_id: String 13 | 14 | /** Video width and height (diameter of the video message) as defined by sender*/ 15 | val length: Int 16 | 17 | /** Duration of the video in seconds as defined by sender*/ 18 | val duration: Int 19 | 20 | /** Optional. Video thumbnail*/ 21 | val thumb: PhotoSize? 22 | 23 | /** Optional. File size in bytes */ 24 | val file_size: Int 25 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/Voice.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface Voice { 8 | /** Identifier for this file, which can be used to download or reuse the file */ 9 | val file_id: String 10 | 11 | /** Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file. */ 12 | val file_unique_id: String 13 | 14 | /** Duration of the audio in seconds as defined by sender */ 15 | val duration: Int 16 | 17 | /** Optional. MIME type of the file as defined by sender */ 18 | val mime_type: String? 19 | 20 | /** Optional. File size in bytes */ 21 | val file_size: Int 22 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/VoiceChatEnded.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface VoiceChatEnded { 8 | /** Voice chat duration in seconds */ 9 | val duration: Int 10 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/VoiceChatParticipantsInvited.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface VoiceChatParticipantsInvited { 8 | /** Optional. New members that were invited to the voice chat */ 9 | val users: List 10 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/VoiceChatScheduled.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface VoiceChatScheduled { 8 | 9 | /** Point in time (Unix timestamp) when the voice chat is supposed to be started by a chat administrator */ 10 | val start_date: Int 11 | } -------------------------------------------------------------------------------- /src/iris/tg/api/items/VoiceChatStarted.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.items 2 | 3 | /** 4 | * @created 01.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface VoiceChatStarted { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/AnswerCallbackQueryResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | sealed interface AnswerCallbackQueryResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/BanChatMemberResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface BanChatMemberResponse: BooleanResponse { 8 | 9 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/BooleanResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | interface BooleanResponse: TgResponse { 4 | override val result: Boolean 5 | } 6 | -------------------------------------------------------------------------------- /src/iris/tg/api/response/DeleteMessageResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface DeleteMessageResponse : BooleanResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/GetChatAdministratorsResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface GetChatAdministratorsResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/GetChatMemberCountResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface GetChatMemberCountResponse : IntegerResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/GetChatMemberResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | import iris.tg.api.items.ChatMember 4 | 5 | /** 6 | * @created 02.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface GetChatMemberResponse : TgResponse { 10 | override val result: ChatMember? 11 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/GetChatResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | import iris.tg.api.items.Chat 4 | 5 | /** 6 | * @created 02.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface GetChatResponse : TgResponse { 10 | override val result: Chat? 11 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/GetFileResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface GetFileResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/GetPathResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface GetPathResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/GetUpdatesResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | import iris.tg.api.items.Update 4 | 5 | /** 6 | * @created 01.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface GetUpdatesResponse: TgResponse { 10 | override val result : List? 11 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/IntegerResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface IntegerResponse : TgResponse { 8 | override val result: Int 9 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/KickChatMemberResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface KickChatMemberResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/RestrictChatMemberResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface RestrictChatMemberResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/SendMessageResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | import iris.tg.api.items.Message 4 | 5 | /** 6 | * @created 02.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface SendMessageResponse : TgResponse { 10 | override val result: Message? 11 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/SendPhotoResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface SendPhotoResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/TgResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | import iris.tg.api.items.Error 4 | 5 | /** 6 | * @created 01.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgResponse { 10 | val ok: Boolean 11 | val error: Error? 12 | val result: Any? 13 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/UnbanChatMember.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface UnbanChatMember : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/api/response/UnbanChatMemberResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.api.response 2 | 3 | /** 4 | * @created 02.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface UnbanChatMemberResponse : TgResponse { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/command/Command.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.command 2 | 3 | import iris.tg.api.items.Message 4 | 5 | /** 6 | * @created 27.10.2020 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | 10 | interface Command { 11 | fun run(message: M) 12 | } -------------------------------------------------------------------------------- /src/iris/tg/command/CommandExtractor.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.command 2 | 3 | import iris.tg.api.items.Message 4 | 5 | 6 | /** 7 | * @created 27.10.2020 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | interface CommandExtractor { 11 | fun extractCommand(message: Message): String? 12 | } -------------------------------------------------------------------------------- /src/iris/tg/command/CommandExtractorDefault.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.command 2 | 3 | import iris.tg.api.items.Message 4 | 5 | 6 | /** 7 | * @created 27.10.2020 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | class CommandExtractorDefault(private val prefixes: String?) : CommandExtractor { 11 | 12 | override fun extractCommand(message: Message): String? { 13 | val text = message.text ?: return null 14 | if (text.isEmpty()) return null 15 | 16 | val offset = if (prefixes != null) { 17 | val first = text.first() 18 | if (!prefixes.contains(first)) 19 | return null 20 | 1 21 | } else 22 | 0 23 | 24 | 25 | val ind = text.indexOf('\n') 26 | return when { 27 | ind == -1 -> if (text.length <= 150) correctText(text, offset) else null 28 | ind <= 150 -> text.substring(offset, ind) 29 | else -> null 30 | }?.lowercase() 31 | } 32 | 33 | private fun correctText(text: String, startIndex: Int): String { 34 | return if (startIndex == 0) text else text.substring(startIndex) 35 | } 36 | } -------------------------------------------------------------------------------- /src/iris/tg/command/CommandMatcher.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.command 2 | 3 | import iris.tg.api.items.Message 4 | 5 | 6 | /** 7 | * @created 27.10.2020 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | interface CommandMatcher { 11 | fun testAndExecute(command: String, message: M): Boolean 12 | } -------------------------------------------------------------------------------- /src/iris/tg/command/CommandMatcherRegex.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.command 2 | 3 | import iris.tg.api.items.Message 4 | 5 | /** 6 | * @created 27.10.2020 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | open class CommandMatcherRegex(private val commandPattern: Regex, private val runCommand: CommandRegex): CommandMatcherWithHash { 10 | 11 | constructor(commandPattern: String, runCommand: (message: M, params: List) -> Unit) : this(Regex(commandPattern), runCommand) 12 | 13 | constructor(commandPattern: Regex, runCommand: (message: M, params: List) -> Unit) : this(commandPattern, object : CommandRegex { 14 | override fun run(message: M, groupValues: List) { 15 | runCommand(message, groupValues) 16 | } 17 | }) 18 | 19 | override fun testAndExecute(command: String, message: M): Boolean { 20 | val matcher = commandPattern.matchEntire(command)?: return false 21 | runCommand.run(message, matcher.groupValues) 22 | return false 23 | } 24 | 25 | override fun hashChars(): CharArray? { 26 | return commandPattern.pattern.firstOrNull()?.let { 27 | if (it.isLetterOrDigit()) 28 | charArrayOf(it) 29 | else 30 | null 31 | } 32 | } 33 | 34 | interface CommandRegex { 35 | fun run(message: M, groupValues: List) 36 | } 37 | } -------------------------------------------------------------------------------- /src/iris/tg/command/CommandMatcherSimple.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.command 2 | 3 | import iris.tg.api.items.Message 4 | 5 | 6 | open class CommandMatcherSimple(private val commandTemplate: String, private val runCommand: Command) : CommandMatcherWithHash { 7 | 8 | constructor(commandPattern: String, runCommand: (message: M) -> Unit) : this(commandPattern, object : Command { 9 | override fun run(message: M) { 10 | runCommand(message) 11 | } 12 | } ) 13 | 14 | override fun testAndExecute(command: String, message: M): Boolean { 15 | if (commandTemplate != command) return false 16 | runCommand.run(message) 17 | return true 18 | } 19 | 20 | override fun hashChars() = commandTemplate.firstOrNull()?.let { charArrayOf(it) } 21 | 22 | 23 | } -------------------------------------------------------------------------------- /src/iris/tg/command/CommandMatcherWithHash.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.command 2 | 3 | /** 4 | * @created 27.10.2020 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface CommandMatcherWithHash : CommandMatcher { 8 | fun hashChars(): CharArray? 9 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/ResponseHandler_IrisJson.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson 2 | 3 | import iris.json.JsonItem 4 | import iris.json.flow.JsonFlowParser 5 | import iris.tg.api.ResponseHandler 6 | import java.io.InputStream 7 | 8 | /** 9 | * @created 25.01.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class ResponseHandler_IrisJson : ResponseHandler { 13 | override fun process(method: String, data: String?): JsonItem? { 14 | if (data == null) return null 15 | return JsonFlowParser.start(data) 16 | } 17 | 18 | override fun process(method: String, inputStream: InputStream): JsonItem? { 19 | return process(method, inputStream.reader(Charsets.UTF_8).readText()) 20 | } 21 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/ResponseHandler_IrisJsonObj.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson 2 | 3 | import iris.json.flow.JsonFlowParser 4 | import iris.tg.api.ResponseHandler 5 | import iris.tg.irisjson.response.* 6 | import java.io.InputStream 7 | 8 | /** 9 | * @created 02.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class ResponseHandler_IrisJsonObj : ResponseHandler { 13 | override fun process(method: String, data: String?): IrisJsonResponse { 14 | data ?: throw NullPointerException("data is null") 15 | val json = JsonFlowParser.start(data) 16 | return when (method) { 17 | "getUpdates" -> IrisJsonGetUpdatesResponse(json) 18 | "sendMessage" -> IrisJsonSendMessageResponse(json) 19 | "editMessageText" -> IrisJsonSendMessageResponse(json) 20 | 21 | "getChatMember" -> IrisJsonGetChatMemberResponse(json) 22 | "getChatAdministrators" -> IrisJsonGetChatAdministratorsResponse(json) 23 | "getChatMemberCount" -> IrisJsonGetChatMemberCountResponse(json) 24 | "banChatMember" -> IrisJsonBanChatMemberResponse(json) 25 | "unbanChatMember" -> IrisJsonBooleanResponse(json) 26 | "getChat" -> IrisJsonGetChatResponse(json) 27 | "deleteMessage" -> IrisJsonBooleanResponse(json) 28 | "sendPhoto" -> IrisJsonSendMessageResponse(json) 29 | "getFile" -> IrisJsonGetFileResponse(json) 30 | "answerCallbackQuery" -> IrisJsonBooleanResponse(json) 31 | "restrictChatMember" -> IrisJsonBooleanResponse(json) 32 | else -> IrisJsonResponseDefault(json) 33 | } 34 | } 35 | 36 | override fun process(method: String, inputStream: InputStream): IrisJsonResponse { 37 | TODO("Not yet implemented") 38 | } 39 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/TgApiFuture_IrisJson.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson 2 | 3 | import iris.tg.api.TgApiObjFuture 4 | import iris.connection.Connection 5 | import java.util.concurrent.CompletableFuture 6 | 7 | /** 8 | * @created 02.02.2022 9 | * @author [Ivan Ivanov](https://t.me/irisism) 10 | */ 11 | open class TgApiFuture_IrisJson(token: String, apiPath: String? = null, connection: Connection, CompletableFuture>? = null 12 | ) : TgApiObjFuture(token, ResponseHandler_IrisJsonObj(), apiPath, connection) { 13 | 14 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/TgApi_IrisJson.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson 2 | 3 | import iris.tg.api.TgApiObject 4 | import iris.connection.Connection 5 | 6 | open class TgApi_IrisJson(token: String, apiPath: String? = null, connection: Connection? = null 7 | ) : TgApiObject(token, ResponseHandler_IrisJsonObj(), apiPath, connection) { 8 | 9 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/TgLongPoll_IrisJson.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson 2 | 3 | import iris.tg.api.TgApiObject 4 | import iris.tg.api.items.Update 5 | import iris.tg.api.response.TgResponse 6 | import iris.tg.longpoll.GetUpdateExceptionHandler 7 | import iris.tg.longpoll.TgLongPoll 8 | import iris.tg.processors.TgUpdateProcessor 9 | import iris.tg.processors.pack.TgEventPackHandler 10 | import iris.tg.processors.pack.TgEventPackHandlerBasicTypes 11 | import iris.tg.processors.pack.TgUpdateProcessorPack 12 | import iris.tg.processors.single.TgEventSingleHandler 13 | import iris.tg.processors.single.TgEventSingleHandlerBasicTypes 14 | import iris.tg.processors.single.TgUpdateProcessorSingle 15 | 16 | /** 17 | * @created 30.10.2020 18 | * @author [Ivan Ivanov](https://t.me/irisism) 19 | */ 20 | open class TgLongPoll_IrisJson(api: TgApiObject, updateProcessor: TgUpdateProcessor, exceptionHandler: GetUpdateExceptionHandler? = null 21 | ) : TgLongPoll(api, updateProcessor, exceptionHandler) { 22 | 23 | constructor(token: String, handler: TgEventSingleHandlerBasicTypes, exceptionHandler: GetUpdateExceptionHandler? = null) 24 | : this(TgApi_IrisJson(token), TgUpdateProcessorSingle(handler), exceptionHandler) 25 | 26 | constructor(token: String, handler: TgEventPackHandlerBasicTypes, exceptionHandler: GetUpdateExceptionHandler? = null) 27 | : this(TgApi_IrisJson(token), TgUpdateProcessorPack(handler), exceptionHandler) 28 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonAnimation.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Animation 5 | import iris.tg.api.items.PhotoSize 6 | 7 | open class IrisJsonAnimation(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Animation { 8 | override val file_id: String 9 | get() = source["file_id"].asString() 10 | override val file_unique_id: String 11 | get() = source["file_unique_id"].asString() 12 | override val width: Int 13 | get() = source["width"].asInt() 14 | override val height: Int 15 | get() = source["height"].asInt() 16 | override val duration: Int 17 | get() = source["duration"].asInt() 18 | override val thumb: PhotoSize? 19 | get() = itemOrNull(source["thumb"]) { IrisJsonPhotoSize(it) } 20 | override val file_name: String? 21 | get() = source["file_name"].asStringOrNull() 22 | override val mime_type: String? 23 | get() = source["mime_type"].asStringOrNull() 24 | override val file_size: Int 25 | get() = source["file_size"].asIntOrNull() ?: 0 26 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonAudio.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Audio 5 | import iris.tg.api.items.PhotoSize 6 | 7 | open class IrisJsonAudio(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Audio { 8 | override val file_id: String 9 | get() = source["file_id"].asString() 10 | override val file_unique_id: String 11 | get() = source["file_unique_id"].asString() 12 | override val duration: Int 13 | get() = source["duration"].asInt() 14 | override val performer: String? 15 | get() = source["performer"].asStringOrNull() 16 | override val title: String? 17 | get() = source["title"].asStringOrNull() 18 | override val file_name: String? 19 | get() = source["file_name"].asStringOrNull() 20 | override val mime_type: String? 21 | get() = source["mime_type"].asStringOrNull() 22 | override val file_size: Int 23 | get() = source["file_size"].asIntOrNull() ?: 0 24 | override val thumb: PhotoSize? 25 | get() = itemOrNull(source["thumb"]) { IrisJsonPhotoSize(it) } 26 | } 27 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonCallbackQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.CallbackQuery 5 | import iris.tg.api.items.Message 6 | import iris.tg.api.items.User 7 | 8 | /** 9 | * @created 07.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class IrisJsonCallbackQuery(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), CallbackQuery { 13 | override val id: String by lazyItem { source["id"].asString() } 14 | 15 | override val from: User by lazyItem { IrisJsonUser(source["from"]) } 16 | 17 | override val message: Message? by lazyItemOrNull("message") { IrisJsonMessage(it) } 18 | 19 | override val inlineMessageId: String? 20 | get() = source["inline_message_id"].asStringOrNull() 21 | override val chatInstance: String 22 | get() = source["chat_instance"].asString() 23 | override val data: String? 24 | get() = source["data"].asStringOrNull() 25 | override val gameShortName: String? 26 | get() = source["game_short_name"].asStringOrNull() 27 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonChat.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.* 5 | 6 | /** 7 | * @created 01.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonChat(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Chat { 11 | override val id: Long by lazyItem() { source["id"].asLong() } 12 | override val type: String by lazyItem() { source["type"].asString() } 13 | override val title: String? by lazyItemOrNull("title") { it.asString() } 14 | override val username: String? by lazyItemOrNull("username") { it.asString() } 15 | override val firstName: String? by lazyItemOrNull("first_name") { it.asString() } 16 | override val lastName: String? by lazyItemOrNull("last_name") { it.asString() } 17 | override val photo: ChatPhoto? = null 18 | override val bio: String? by lazyItemOrNull("bio") { it.asString() } 19 | override val hasPrivateForwards: Boolean by lazyItem() { sourceItem["has_private_forwards"].asBooleanOrNull() ?: false } 20 | override val description: String? by lazyItemOrNull("description") { it.asString() } 21 | override val inviteLink: String? by lazyItemOrNull("inviteLink") { it.asString() } 22 | override val pinnedMessage: Message? by lazyItemOrNull("pinned_message") { IrisJsonMessage(it) } 23 | override val permissions: ChatPermissions? 24 | get() = itemOrNull(source["permissions"]) { IrisJsonChatPermissions(it) } 25 | 26 | override val slowModeDelay: Int 27 | get() = source["permissions"].asIntOrNull() ?: 0 28 | override val messageAutoDeleteTime: Int 29 | get() = source["message_auto_delete_time"].asIntOrNull() ?: 0 30 | override val hasProtectedContent: Boolean 31 | get() = source["has_protected_content"].asBooleanOrNull() ?: false 32 | override val stickerSetName: String? 33 | get() = source["sticker_set_name"].asStringOrNull() 34 | override val canSetStickerSet: Boolean 35 | get() = source["can_set_sticker_set"].asBooleanOrNull() ?: false 36 | override val linkedChatId: Long 37 | get() = source["linked_chat_id"].asLongOrNull() ?: 0L 38 | override val location: ChatLocation? 39 | get() = itemOrNull(source["location"]) { IrisJsonChatLocation(it) } 40 | 41 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonChatLocation.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.ChatLocation 5 | import iris.tg.pojo.items.ChatLocation_Pojo 6 | 7 | class IrisJsonChatLocation(it: JsonItem) : IrisJsonTgItem(it), ChatLocation { 8 | override val location 9 | get() = IrisJsonLocation(source["location"]) 10 | override val address 11 | get() = source["address"].asString() 12 | 13 | override fun pojo() : ChatLocation { 14 | return ChatLocation_Pojo(location.pojo(), address) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonChatMemberUpdated.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.* 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonChatMemberUpdated(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), ChatMemberUpdated { 11 | 12 | override val chat: Chat by lazyItem { IrisJsonChat(source["chat"]) } 13 | 14 | override val from: User by lazyItem { IrisJsonUser(source["user"]) } 15 | 16 | override val date: Long get() = source["date"].asLongOrNull() ?: 0L 17 | 18 | override val oldChatMember: ChatMember by lazyItem { IrisJsonChatMemberFactory.create(source["old_chat_member"]) } 19 | 20 | override val newChatMember: ChatMember by lazyItem { IrisJsonChatMemberFactory.create(source["new_chat_member"]) } 21 | 22 | override val invite_link: ChatInviteLink? 23 | get() = TODO("Not yet implemented") 24 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonChatPermissions.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.ChatPermissions 5 | import iris.tg.pojo.items.ChatPermissions_Pojo 6 | 7 | /** 8 | * @created 10.02.2022 9 | * @author [Ivan Ivanov](https://t.me/irisism) 10 | */ 11 | class IrisJsonChatPermissions(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), ChatPermissions { 12 | override val can_send_messages: Boolean? 13 | get() = source["can_send_messages"].asBooleanOrNull() 14 | override val can_send_media_messages: Boolean? 15 | get() = source["can_send_media_messages"].asBooleanOrNull() 16 | override val can_send_polls: Boolean? 17 | get() = source["can_send_polls"].asBooleanOrNull() 18 | override val can_send_other_messages: Boolean? 19 | get() = source["can_send_other_messages"].asBooleanOrNull() 20 | override val can_add_web_page_previews: Boolean? 21 | get() = source["can_add_web_page_previews"].asBooleanOrNull() 22 | override val can_change_info: Boolean? 23 | get() = source["can_change_info"].asBooleanOrNull() 24 | override val can_invite_users: Boolean? 25 | get() = source["can_invite_users"].asBooleanOrNull() 26 | override val can_pin_messages: Boolean? 27 | get() = source["can_pin_messages"].asBooleanOrNull() 28 | 29 | override fun pojo(): ChatPermissions { 30 | return ChatPermissions_Pojo(can_send_messages, can_send_media_messages, can_send_polls, can_send_other_messages, can_add_web_page_previews, can_change_info, can_invite_users, can_pin_messages) 31 | } 32 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonContact.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Contact 5 | 6 | open class IrisJsonContact(sourceItem: JsonItem): IrisJsonTgItem(sourceItem), Contact { 7 | override val phone_number: String 8 | get() = source["phone_number"].asString() 9 | override val first_name: String 10 | get() = source["first_name"].asString() 11 | override val last_name: String? 12 | get() = source["last_name"].asStringOrNull() 13 | override val user_id: Long 14 | get() = source["user_id"].asLongOrNull() ?: 0L 15 | override val vcard: String? 16 | get() = source["vcard"].asStringOrNull() 17 | } 18 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonDice.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Dice 5 | 6 | open class IrisJsonDice(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Dice { 7 | override val emoji: String 8 | get() = source["emoji"].asString() 9 | override val value: Int 10 | get() = source["value"].asInt() 11 | } 12 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonDocument.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Document 5 | import iris.tg.api.items.PhotoSize 6 | 7 | /** 8 | * @created 02.02.2022 9 | * @author [Ivan Ivanov](https://t.me/irisism) 10 | */ 11 | open class IrisJsonDocument(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Document { 12 | override val file_id: String 13 | get() = source["file_id"].asString() 14 | override val file_unique_id: String 15 | get() = source["file_unique_id"].asString() 16 | override val thumb: PhotoSize? 17 | get() = itemOrNull(source["thumb"]) { IrisJsonPhotoSize(it) } 18 | override val file_name: String? 19 | get() = source["file_name"].asStringOrNull() 20 | override val mime_type: String? 21 | get() = source["mime_type"].asStringOrNull() 22 | override val file_size: Int 23 | get() = source["file_size"].asIntOrNull() ?: 0 24 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonError.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Error 5 | 6 | /** 7 | * @created 01.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonError(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Error { 11 | override val errorCode: Int = source["error_code"].asInt() 12 | override val description: String = source["description"].asString() 13 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonFile.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.File 5 | 6 | open class IrisJsonFile(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), File { 7 | override val fileId: String 8 | get() = source["file_id"].asString() 9 | override val fileUniqueId: String 10 | get() = source["file_unique_id"].asString() 11 | override val fileSize: Int 12 | get() = source["file_size"].asInt() 13 | override val filePath: String? 14 | get() = source["file_path"].asStringOrNull() 15 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonGame.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Animation 5 | import iris.tg.api.items.Game 6 | import iris.tg.api.items.MessageEntity 7 | import iris.tg.api.items.PhotoSize 8 | 9 | open class IrisJsonGame(sourceItem: JsonItem): IrisJsonTgItem(sourceItem), Game { 10 | override val title: String 11 | get() = source["title"].asString() 12 | override val description: String 13 | get() = source["description"].asString() 14 | override val photo: List 15 | get() = source["photo"].iterable().map { IrisJsonPhotoSize(it) } 16 | override val text: String? 17 | get() = source["text"].asStringOrNull() 18 | override val text_entities: List? 19 | get() = itemOrNull(source["text_entities"]) { it.iterable().map { IrisMessageEntry(it) } } 20 | override val animation: Animation? 21 | get() = itemOrNull(source["animation"]) { IrisJsonAnimation(it) } 22 | } 23 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonInlineKeyboardMarkup.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.CallbackGame 5 | import iris.tg.api.items.InlineKeyboardButton 6 | import iris.tg.api.items.InlineKeyboardMarkup 7 | import iris.tg.api.items.LoginUrl 8 | 9 | open class IrisJsonInlineKeyboardMarkup(it: JsonItem): IrisJsonTgItem(it), InlineKeyboardMarkup { 10 | override val inline_keyboard: List> 11 | by lazyItem { source["inline_keyboard"].iterable().map { 12 | it.iterable().map { IrisJsonInlineKeyboardButton(it) } 13 | } } 14 | } 15 | 16 | open class IrisJsonInlineKeyboardButton(it: JsonItem) : IrisJsonTgItem(it), InlineKeyboardButton { 17 | 18 | override val text: String by lazyItem { source["text"].asString() } 19 | 20 | override val url: String? by lazyItem { source["url"].asStringOrNull() } 21 | 22 | override val login_url: LoginUrl? 23 | get() = TODO("Not yet implemented") 24 | 25 | override val callback_data: String? 26 | get() = source["callback_data"].asStringOrNull() 27 | 28 | override val switch_inline_query: String? 29 | get() = source["switch_inline_query"].asStringOrNull() 30 | 31 | override val callback_game: CallbackGame? 32 | get() = TODO("Not yet implemented") 33 | 34 | override val pay: Boolean 35 | get() = source["pay"].asBooleanOrNull() ?: false 36 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonInvoice.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Invoice 5 | 6 | open class IrisJsonInvoice(it: JsonItem): IrisJsonTgItem(it), Invoice { 7 | override val title: String by lazyItem { source["title"].asString() } 8 | override val description: String by lazyItem { source["description"].asString() } 9 | 10 | override val start_parameter: String by lazyItem { source["start_parameter"].asString() } 11 | override val currency: String by lazyItem { source["currency"].asString() } 12 | override val total_amount: Int by lazyItem { source["total_amount"].asInt() } 13 | } 14 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonLocation.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Location 5 | import iris.tg.pojo.items.Location_Pojo 6 | 7 | open class IrisJsonLocation(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Location { 8 | override val longitude: Float 9 | get() = source["longitude"].asFloat() 10 | override val latitude: Float 11 | get() = source["latitude"].asFloat() 12 | override val horizontal_accuracy: Float 13 | get() = source["horizontal_accuracy"].asFloatOrNull() ?: 0f 14 | override val live_period: Int 15 | get() = source["live_period"].asIntOrNull() ?: 0 16 | override val heading: Int 17 | get() = source["heading"].asIntOrNull() ?: 0 18 | override val proximity_alert_radius: Int 19 | get() = source["proximity_alert_radius"].asIntOrNull() ?: 0 20 | 21 | override fun pojo(): Location_Pojo { 22 | return Location_Pojo(longitude, latitude, horizontal_accuracy, live_period, heading, proximity_alert_radius) 23 | } 24 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonMaskPosition.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.MaskPosition 5 | 6 | open class IrisJsonMaskPosition(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), MaskPosition { 7 | override val point: String 8 | get() = source["point"].asString() 9 | override val x_shift: Float 10 | get() = source["x_shift"].asFloat() 11 | override val y_shift: Float 12 | get() = source["y_shift"].asFloat() 13 | override val scale: Float 14 | get() = source["scale"].asFloat() 15 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonMessageAutoDeleteTimerChanged.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.MessageAutoDeleteTimerChanged 5 | 6 | open class IrisJsonMessageAutoDeleteTimerChanged(it: JsonItem): IrisJsonTgItem(it), MessageAutoDeleteTimerChanged { 7 | override val message_auto_delete_time: Int 8 | get() = source["message_auto_delete_time"].asInt() 9 | } 10 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonPassportData.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.EncryptedCredentials 5 | import iris.tg.api.items.EncryptedPassportElement 6 | import iris.tg.api.items.PassportData 7 | 8 | open class IrisJsonPassportData(it: JsonItem): IrisJsonTgItem(it), PassportData { 9 | override val data: List 10 | get() = TODO("Not yet implemented") 11 | override val credentials: EncryptedCredentials 12 | get() = TODO("Not yet implemented") 13 | } 14 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonPhotoSize.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.PhotoSize 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonPhotoSize(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), PhotoSize { 11 | override val fileId: String 12 | get() = source["file_id"].asString() 13 | 14 | override val fileUniqueId: String 15 | get() = source["file_unique_id"].asString() 16 | 17 | override val width: Int 18 | get() = source["width"].asInt() 19 | 20 | override val height: Int 21 | get() = source["height"].asInt() 22 | 23 | override val fileSize: Int 24 | get() = source["file_size"].asIntOrNull() ?: 0 25 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonPoll.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.MessageEntity 5 | import iris.tg.api.items.Poll 6 | import iris.tg.api.items.PollOption 7 | 8 | open class IrisJsonPoll(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Poll { 9 | override val id: String by lazyItem { source["id"].asString() } 10 | 11 | override val question: String by lazyItem { source["question"].asString() } 12 | 13 | override val options: List 14 | get() = source["options"].iterable().map { IrisJsonPollOption(it) } 15 | 16 | override val total_voter_count: Int 17 | get() = source["total_voter_count"].asInt() 18 | override val is_closed: Boolean 19 | get() = source["is_closed"].asBooleanOrNull() ?: false 20 | override val is_anonymous: Boolean 21 | get() = source["is_anonymous"].asBooleanOrNull() ?: false 22 | override val type: String 23 | get() = source["type"].asString() 24 | override val allows_multiple_answers: Boolean 25 | get() = source["allows_multiple_answers"].asBooleanOrNull() ?: false 26 | override val correct_option_id: Int 27 | get() = source["correct_option_id"].asIntOrNull() ?: 0 28 | override val explanation: String? 29 | get() = source["explanation"].asStringOrNull() 30 | 31 | override val explanation_entities: List? 32 | get() = itemOrNull(source["explanation_entities"]) { it.iterable().map { IrisMessageEntry(it) } } 33 | 34 | override val open_period: Int 35 | get() = source["open_period"].asInt() 36 | override val close_date: Int 37 | get() = source["close_date"].asInt() 38 | } 39 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonPollOption.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.PollOption 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonPollOption(sourceItem: JsonItem): IrisJsonTgItem(sourceItem), PollOption { 11 | override val text: String 12 | get() = source["text"].asString() 13 | override val voter_count: Int 14 | get() = source["voter_count"].asInt() 15 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonProximityAlertTriggered.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.ProximityAlertTriggered 5 | import iris.tg.api.items.User 6 | 7 | open class IrisJsonProximityAlertTriggered(it: JsonItem): IrisJsonTgItem(it), ProximityAlertTriggered { 8 | 9 | override val traveler: User by lazyItem { IrisJsonUser(source["traveler"]) } 10 | 11 | override val watcher: User by lazyItem { IrisJsonUser(source["watcher"]) } 12 | 13 | override val distance: Int 14 | get() = source["distance"].asInt() 15 | } 16 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonSticker.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.MaskPosition 5 | import iris.tg.api.items.PhotoSize 6 | import iris.tg.api.items.Sticker 7 | 8 | /** 9 | * @created 02.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class IrisJsonSticker(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Sticker { 13 | override val file_id: String 14 | get() = source["file_id"].asString() 15 | override val file_unique_id: String 16 | get() = source["file_unique_id"].asString() 17 | override val width: Int 18 | get() = source["width"].asInt() 19 | override val height: Int 20 | get() = source["height"].asInt() 21 | override val is_animated: Boolean 22 | get() = source["is_animated"].asBooleanOrNull() ?: false 23 | override val is_video: Boolean 24 | get() = source["is_video"].asBooleanOrNull() ?: false 25 | 26 | override val thumb: PhotoSize? 27 | get() = itemOrNull(source["thumb"]) { IrisJsonPhotoSize(it) } 28 | 29 | override val emoji: String? 30 | get() = source["emoji"].asStringOrNull() 31 | override val set_name: String? 32 | get() = source["set_name"].asStringOrNull() 33 | 34 | override val mask_position: MaskPosition? 35 | get() = TODO("Not yet implemented") 36 | 37 | override val file_size: Int 38 | get() = TODO("Not yet implemented") 39 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonSuccessfulPayment.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.SuccessfulPayment 5 | 6 | open class IrisJsonSuccessfulPayment(it: JsonItem): IrisJsonTgItem(it), SuccessfulPayment { 7 | override val currency: String 8 | get() = source["currency"].asString() 9 | override val total_amount: Int 10 | get() = source["total_amount"].asInt() 11 | } 12 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonTgItem.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.TgItem 5 | 6 | /** 7 | * @created 01.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonTgItem(val source: JsonItem) : TgItem { 11 | 12 | protected inline fun lazyItemOrNull(field: String, crossinline factory: (item: JsonItem) -> T): Lazy { 13 | return lazy(LazyThreadSafetyMode.NONE) { 14 | itemOrNull(source[field], factory) 15 | } 16 | } 17 | 18 | protected inline fun itemOrNull(item: JsonItem, factory: (item: JsonItem) -> T?): T? { 19 | return if (item.isNull()) null else factory(item) 20 | } 21 | 22 | protected inline fun lazyItem(crossinline factory: () -> T): Lazy { 23 | return lazy(LazyThreadSafetyMode.NONE) { factory() } 24 | } 25 | 26 | override fun toString(): String { 27 | return source.toJsonString() 28 | } 29 | 30 | open fun pojo(): Any 31 | = throw UnsupportedOperationException("pojo method not implemented") 32 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonUpdate.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.* 5 | 6 | /** 7 | * @created 01.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonUpdate(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Update { 11 | 12 | override val updateId: Long 13 | get() = source["update_id"].asLong() 14 | 15 | override val message: Message? by lazyItemOrNull("message") { IrisJsonMessage(it) } 16 | override val editedMessage: Message? by lazyItemOrNull("edited_message") { IrisJsonMessage(it) } 17 | override val channelPost: Message? by lazyItemOrNull("channel_post") { IrisJsonMessage(it) } 18 | override val editedChannelPost: Message? by lazyItemOrNull("edited_channel_post") { IrisJsonMessage(it) } 19 | override val inlineQuery: InlineQuery? = null 20 | override val chosenInlineResult: ChosenInlineResult? = null 21 | override val callbackQuery: CallbackQuery? by lazyItemOrNull("callback_query") { IrisJsonCallbackQuery(it) } 22 | override val shippingQuery: ShippingQuery? = null 23 | override val preCheckoutQuery: PreCheckoutQuery? = null 24 | override val poll: Poll? = null 25 | override val pollAnswer: PollAnswer? = null 26 | override val myChatMember: ChatMemberUpdated? = null 27 | override val chatMember: ChatMemberUpdated? by lazyItemOrNull("chat_member") { IrisJsonChatMemberUpdated(it) } 28 | override val chatJoinRequest: ChatJoinRequest? = null 29 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonUser.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.User 5 | 6 | /** 7 | * @created 01.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonUser(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), User { 11 | 12 | override val id: Long by lazyItem { source["id"].asLong() } 13 | 14 | override val isBot: Boolean by lazyItem { source["is_bot"].asBooleanOrNull() ?: false } 15 | 16 | override val firstName: String by lazyItem { source["first_name"].asString() } 17 | 18 | override val lastName: String? by lazyItem { source["last_name"].asStringOrNull() } 19 | 20 | override val username: String? by lazyItem { source["username"].asStringOrNull() } 21 | 22 | override val languageCode: String? 23 | get() = source["language_code"].asStringOrNull() 24 | 25 | override val canJoinGroups: Boolean 26 | get() = source["can_join_groups"].asBooleanOrNull() ?: false 27 | 28 | override val canReadAllGroupMessages: Boolean 29 | get() = source["can_read_all_group_messages"].asBooleanOrNull() ?: false 30 | 31 | override val supportsInlineQueries: Boolean 32 | get() = source["supports_inline_queries"].asBooleanOrNull() ?: false 33 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVenue.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Location 5 | import iris.tg.api.items.Venue 6 | 7 | open class IrisJsonVenue(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Venue { 8 | override val location: Location 9 | get() = IrisJsonLocation(source["location"]) 10 | override val title: String 11 | get() = TODO("Not yet implemented") 12 | override val address: String 13 | get() = TODO("Not yet implemented") 14 | override val foursquare_id: String? 15 | get() = TODO("Not yet implemented") 16 | override val foursquare_type: String? 17 | get() = TODO("Not yet implemented") 18 | override val google_place_id: String? 19 | get() = TODO("Not yet implemented") 20 | override val google_place_type: String? 21 | get() = TODO("Not yet implemented") 22 | } 23 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVideo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.PhotoSize 5 | import iris.tg.api.items.Video 6 | 7 | open class IrisJsonVideo(sourceItem: JsonItem): IrisJsonTgItem(sourceItem), Video { 8 | override val file_id: String 9 | get() = source["file_id"].asString() 10 | override val file_unique_id: String 11 | get() = source["file_unique_id"].asString() 12 | override val width: Int 13 | get() = source["width"].asInt() 14 | override val height: Int 15 | get() = source["height"].asInt() 16 | override val duration: Int 17 | get() = source["duration"].asIntOrNull() ?: 0 18 | override val thumb: PhotoSize? 19 | get() = itemOrNull(source["thumb"]) { IrisJsonPhotoSize(it) } 20 | override val file_name: String? 21 | get() = source["file_name"].asStringOrNull() 22 | override val mime_type: String? 23 | get() = source["mime_type"].asStringOrNull() 24 | override val file_size: Int 25 | get() = source["file_size"].asIntOrNull() ?: 0 26 | } 27 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVideoNote.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.PhotoSize 5 | import iris.tg.api.items.VideoNote 6 | 7 | open class IrisJsonVideoNote(sourceItem: JsonItem): IrisJsonTgItem(sourceItem), VideoNote { 8 | override val file_id: String 9 | get() = source["file_id"].asString() 10 | override val file_unique_id: String 11 | get() = source["file_unique_id"].asString() 12 | override val length: Int 13 | get() = source["length"].asInt() 14 | override val duration: Int 15 | get() = source["duration"].asInt() 16 | override val thumb: PhotoSize? 17 | get() = itemOrNull(source["thumb"]) { IrisJsonPhotoSize(it) } 18 | override val file_size: Int 19 | get() = source["file_size"].asIntOrNull() ?: 0 20 | } 21 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVoice.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Voice 5 | 6 | open class IrisJsonVoice(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), Voice { 7 | override val file_id: String 8 | get() = source["file_id"].asString() 9 | override val file_unique_id: String 10 | get() = source["file_unique_id"].asString() 11 | override val duration: Int 12 | get() = source["duration"].asInt() 13 | override val mime_type: String? 14 | get() = source["mime_type"].asStringOrNull() 15 | override val file_size: Int 16 | get() = source["file_size"].asIntOrNull() ?: 0 17 | } 18 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVoiceChatEnded.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.VoiceChatEnded 5 | 6 | open class IrisJsonVoiceChatEnded(it: JsonItem): IrisJsonTgItem(it), VoiceChatEnded { 7 | override val duration: Int 8 | get() = source["duration"].asInt() 9 | } 10 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVoiceChatParticipantsInvited.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.User 5 | import iris.tg.api.items.VoiceChatParticipantsInvited 6 | 7 | open class IrisJsonVoiceChatParticipantsInvited(it: JsonItem): IrisJsonTgItem(it), VoiceChatParticipantsInvited { 8 | override val users: List by lazyItem { source["users"].iterable().map { IrisJsonUser(it) } } 9 | } 10 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVoiceChatScheduled.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.VoiceChatScheduled 5 | 6 | open class IrisJsonVoiceChatScheduled(it: JsonItem): IrisJsonTgItem(it), VoiceChatScheduled { 7 | override val start_date: Int 8 | get() = source["start_date"].asInt() 9 | } 10 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisJsonVoiceChatStarted.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.VoiceChatStarted 5 | 6 | open class IrisJsonVoiceChatStarted(it: JsonItem): IrisJsonTgItem(it), VoiceChatStarted { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/iris/tg/irisjson/items/IrisMessageEntry.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.MessageEntity 5 | import iris.tg.api.items.User 6 | 7 | /** 8 | * @created 02.02.2022 9 | * @author [Ivan Ivanov](https://t.me/irisism) 10 | */ 11 | open class IrisMessageEntry(sourceItem: JsonItem) : IrisJsonTgItem(sourceItem), MessageEntity { 12 | override val type: String get() = source["type"].asString() 13 | 14 | override val offset: Int get() = source["offset"].asInt() 15 | override val length: Int get() = source["length"].asInt() 16 | override val url: String? get() = source["url"].asStringOrNull() 17 | 18 | override val user: User? get() = with(source["user"]) { if (this.isNull()) null else IrisJsonUser(this) } 19 | 20 | override val language: String? get() = source["url"].asStringOrNull() 21 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonBanChatMemberResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.response.BanChatMemberResponse 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonBanChatMemberResponse(source: JsonItem) : IrisJsonBooleanResponse(source), BanChatMemberResponse { 11 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonBooleanResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.response.BooleanResponse 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonBooleanResponse(source: JsonItem) : IrisJsonResponse(source), BooleanResponse { 11 | override val result: Boolean 12 | get() = this.source["result"].asBooleanOrNull() ?: false 13 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonGetChatAdministratorsResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.ChatMemberAdministrator 5 | import iris.tg.api.response.GetChatAdministratorsResponse 6 | import iris.tg.irisjson.items.IrisJsonChatMemberAdministrator 7 | 8 | /** 9 | * @created 02.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class IrisJsonGetChatAdministratorsResponse(source: JsonItem) : IrisJsonResponse(source), GetChatAdministratorsResponse { 13 | override val result: List? by lazyItemOrNull("result") { it.iterable().map { IrisJsonChatMemberAdministrator(it) } } 14 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonGetChatMemberCountResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.response.GetChatMemberCountResponse 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonGetChatMemberCountResponse(source: JsonItem) : IrisJsonIntegerResponse(source), GetChatMemberCountResponse { 11 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonGetChatMemberResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.ChatMember 5 | import iris.tg.api.items.IrisJsonChatMemberFactory 6 | import iris.tg.api.response.GetChatMemberResponse 7 | 8 | /** 9 | * @created 02.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class IrisJsonGetChatMemberResponse(sourceItem: JsonItem) : IrisJsonResponse(sourceItem), GetChatMemberResponse { 13 | override val result: ChatMember? by lazyItemOrNull("result") { IrisJsonChatMemberFactory.create(it) } 14 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonGetChatResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Chat 5 | import iris.tg.api.response.GetChatResponse 6 | import iris.tg.irisjson.items.IrisJsonChat 7 | 8 | /** 9 | * @created 02.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class IrisJsonGetChatResponse(sourceItem: JsonItem) : IrisJsonResponse(sourceItem), GetChatResponse { 13 | override val result: Chat? by lazyItemOrNull("result") { IrisJsonChat(it) } 14 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonGetFileResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.File 5 | import iris.tg.api.response.GetFileResponse 6 | import iris.tg.irisjson.items.IrisJsonFile 7 | 8 | /** 9 | * @created 02.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class IrisJsonGetFileResponse(sourceItem: JsonItem) : IrisJsonResponse(sourceItem), GetFileResponse { 13 | override val result: File? by lazyItemOrNull("result") { IrisJsonFile(it) } 14 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonGetUpdatesResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Update 5 | import iris.tg.api.response.GetUpdatesResponse 6 | import iris.tg.irisjson.items.IrisJsonUpdate 7 | 8 | /** 9 | * @created 01.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | open class IrisJsonGetUpdatesResponse(sourceItem: JsonItem) : IrisJsonResponse(sourceItem), GetUpdatesResponse { 13 | override val result: List? by lazyItemOrNull("result") { it.iterable().map { IrisJsonUpdate(it) } } 14 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonIntegerResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.response.IntegerResponse 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonIntegerResponse(source: JsonItem) : IrisJsonResponse(source), IntegerResponse { 11 | override val result: Int = this.source["result"].asIntOrNull() ?: 0 12 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Error 5 | import iris.tg.api.response.TgResponse 6 | import iris.tg.irisjson.items.IrisJsonError 7 | import iris.tg.irisjson.items.IrisJsonTgItem 8 | 9 | /** 10 | * @created 01.02.2022 11 | * @author [Ivan Ivanov](https://t.me/irisism) 12 | */ 13 | abstract class IrisJsonResponse(source: JsonItem) : IrisJsonTgItem(source), TgResponse { 14 | 15 | override val ok: Boolean by lazyItem { source["ok"].asBooleanOrNull() ?: true } 16 | 17 | override val error: Error by lazyItem { if (!ok) IrisJsonError(source) else throw IllegalStateException("Response was ok") } 18 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonResponseDefault.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.irisjson.items.IrisJsonTgItem 5 | 6 | /** 7 | * @created 02.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class IrisJsonResponseDefault(source: JsonItem) : IrisJsonResponse(source) { 11 | override val result: IrisJsonTgItem by lazyItem { IrisJsonTgItem(this.source["result"]) } 12 | } -------------------------------------------------------------------------------- /src/iris/tg/irisjson/response/IrisJsonSendMessageResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.irisjson.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.response.SendMessageResponse 5 | import iris.tg.irisjson.items.IrisJsonMessage 6 | 7 | /** 8 | * @created 02.02.2022 9 | * @author [Ivan Ivanov](https://t.me/irisism) 10 | */ 11 | open class IrisJsonSendMessageResponse(source: JsonItem) : IrisJsonResponse(source), SendMessageResponse { 12 | override val result by lazyItemOrNull("result") { IrisJsonMessage(it) } 13 | } -------------------------------------------------------------------------------- /src/iris/tg/longpoll/GetUpdateExceptionHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.longpoll 2 | 3 | /** 4 | * @created 03.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface GetUpdateExceptionHandler { 8 | fun handle(e: Throwable): Boolean 9 | //fun nullUpdates(): Boolean 10 | fun notOk(errorItem: T): Boolean 11 | } -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/ChatLocation_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.ChatLocation 4 | import iris.tg.api.items.Location 5 | 6 | /** 7 | * @created 10.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class ChatLocation_Pojo(override val location: Location 11 | , override val address: String 12 | ): ChatLocation -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/ChatPermissions_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.ChatPermissions 4 | 5 | /** 6 | * @created 10.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | open class ChatPermissions_Pojo( 10 | override val can_send_messages: Boolean?, 11 | override val can_send_media_messages: Boolean?, 12 | override val can_send_polls: Boolean?, 13 | override val can_send_other_messages: Boolean?, 14 | override val can_add_web_page_previews: Boolean?, 15 | override val can_change_info: Boolean?, 16 | override val can_invite_users: Boolean?, 17 | override val can_pin_messages: Boolean?, 18 | ): ChatPermissions -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/Chat_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.* 4 | 5 | /** 6 | * @created 09.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | open class Chat_Pojo( 10 | override val id: Long, 11 | override val type: String, 12 | override val title: String? = null, 13 | override val username: String? = null, 14 | override val firstName: String? = null, 15 | override val lastName: String? = null, 16 | override val photo: ChatPhoto? = null, 17 | override val bio: String? = null, 18 | override val hasPrivateForwards: Boolean = false, 19 | override val description: String? = null, 20 | override val inviteLink: String? = null, 21 | override val pinnedMessage: Message? = null, 22 | override val permissions: ChatPermissions? = null, 23 | override val slowModeDelay: Int = 0, 24 | override val messageAutoDeleteTime: Int = 0, 25 | override val hasProtectedContent: Boolean = false, 26 | override val stickerSetName: String? = null, 27 | override val canSetStickerSet: Boolean = false, 28 | override val linkedChatId: Long = 0L, 29 | override val location: ChatLocation? = null, 30 | ): Chat -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/InlineKeyboardButton_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.CallbackGame 4 | import iris.tg.api.items.InlineKeyboardButton 5 | import iris.tg.api.items.LoginUrl 6 | 7 | open class InlineKeyboardButton_Pojo( 8 | override val text: String, 9 | override val url: String? = null, 10 | override val login_url: LoginUrl? = null, 11 | override val callback_data: String? = null, 12 | override val switch_inline_query: String? = null, 13 | override val callback_game: CallbackGame? = null, 14 | override val pay: Boolean = false 15 | ) : InlineKeyboardButton 16 | 17 | -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/InlineKeyboardMarkup_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.InlineKeyboardButton 4 | import iris.tg.api.items.InlineKeyboardMarkup 5 | 6 | /** 7 | * @created 07.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class InlineKeyboardMarkup_Pojo( 11 | override val inline_keyboard: List> 12 | ) : InlineKeyboardMarkup -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/Location_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.Location 4 | 5 | /** 6 | * @created 10.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | open class Location_Pojo( 10 | override val longitude: Float, 11 | override val latitude: Float, 12 | override val horizontal_accuracy: Float, 13 | override val live_period: Int, 14 | override val heading: Int, 15 | override val proximity_alert_radius: Int 16 | ): Location -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/MessageEntity_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.MessageEntity 4 | import iris.tg.api.items.User 5 | 6 | open class MessageEntity_Pojo( 7 | override val type: String 8 | , override val offset: Int 9 | , override val length: Int 10 | , override val url: String? = null 11 | , override val user: User? = null 12 | , override val language: String? = null 13 | ) : MessageEntity -------------------------------------------------------------------------------- /src/iris/tg/pojo/items/ReplyKeyboardRemove_Pojo.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.pojo.items 2 | 3 | import iris.tg.api.items.ReplyKeyboardRemove 4 | 5 | /** 6 | * @created 21.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class ReplyKeyboardRemove_Pojo( 10 | override val selective: Boolean 11 | ) : ReplyKeyboardRemove { 12 | override val remove_keyboard = true 13 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/TgEventHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors 2 | 3 | /** 4 | * @created 04.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TgEventHandler { 8 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/TgUpdateExtToSimpleProcessor.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors 2 | 3 | import iris.tg.api.items.Update 4 | import iris.tg.api.items.UpdateExt 5 | 6 | /** 7 | * @created 05.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | @Deprecated("Не нужны эти переливы") 11 | class TgUpdateExtToSimpleProcessor(private val simpleProcessor: TgUpdateProcessor) : TgUpdateProcessor { 12 | 13 | override fun processUpdates(updates: List) { 14 | simpleProcessor.processUpdates(updates.map { it.update }) 15 | } 16 | 17 | override fun processUpdate(update: UpdateExt) { 18 | simpleProcessor.processUpdate(update.update) 19 | } 20 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/TgUpdateMultibotProcessor.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors 2 | 3 | import iris.tg.webhook.BotSource 4 | 5 | /** 6 | * @created 31.10.2020 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgUpdateMultibotProcessor { 10 | fun processUpdates(fromBot: BotSource.BotData, updates: List) 11 | fun processUpdate(fromBot: BotSource.BotData, update: T) 12 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/TgUpdateProcessor.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors 2 | 3 | /** 4 | * @created 31.10.2020 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TgUpdateProcessor { 8 | fun processUpdates(updates: List) 9 | fun processUpdate(update: T) 10 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/TgUpdateProcessor2Multibot.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors 2 | 3 | import iris.tg.webhook.BotSource 4 | 5 | /** 6 | * @created 05.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class TgUpdateProcessor2Multibot(private val botData: BotSource.BotData, private val multibotProcessor: TgUpdateMultibotProcessor) : TgUpdateProcessor { 10 | 11 | override fun processUpdates(updates: List) { 12 | multibotProcessor.processUpdates(botData, updates) 13 | } 14 | 15 | override fun processUpdate(update: U) { 16 | multibotProcessor.processUpdate(botData, update) 17 | } 18 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/er.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors 2 | 3 | import iris.tg.api.items.Update 4 | import iris.tg.webhook.BotSource 5 | 6 | /** 7 | * @created 05.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | class TgUpdateMultibotProcessorToUpdateProcessor(private val simpleProcessor: TgUpdateProcessor) : TgUpdateMultibotProcessor { 11 | override fun processUpdates(fromBot: BotSource.BotData, updates: List) { 12 | simpleProcessor.processUpdates(updates) 13 | } 14 | 15 | override fun processUpdate(fromBot: BotSource.BotData, update: T) { 16 | simpleProcessor.processUpdates(listOf(update)) 17 | } 18 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgChatMemberUpdatedFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.ChatMemberUpdated 4 | 5 | /** 6 | * @created 03.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgChatMemberUpdatedFilter { 10 | fun ownersChanged(items: List): List 11 | fun administratorsChanged(items: List): List 12 | fun administratorsCanceled(items: List): List 13 | fun chatMembersRestricted(items: List): List 14 | fun chatMemberLeft(items: List): List 15 | fun chatMemberBanned(items: List): List 16 | fun chatMemberNew(items: List): List 17 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgChatMemberUpdatedHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.ChatMemberUpdated 4 | 5 | /** 6 | * @created 03.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgChatMemberUpdatedHandler { 10 | fun ownersChanged(items: List) 11 | fun administratorsChanged(items: List) 12 | fun administratorsCanceled(items: List) 13 | fun chatMembersRestricted(items: List) 14 | fun chatMemberLeft(items: List) 15 | fun chatMemberBanned(items: List) 16 | fun chatMemberNew(items: List) 17 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgChatMemberUpdatedSplitter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.ChatMemberUpdated 4 | import java.util.* 5 | 6 | /** 7 | * @created 03.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | class TgChatMemberUpdatedSplitter(private val handler: TgChatMemberUpdatedHandler) { 11 | 12 | private val ownersChanged = LinkedList() 13 | private val administratorsChanged = LinkedList() 14 | private val administratorsCanceled = LinkedList() 15 | private val chatMembersRestricted = LinkedList() 16 | private val chatMemberLeft = LinkedList() 17 | private val chatMemberBanned = LinkedList() 18 | private val chatMemberNew = LinkedList() 19 | 20 | fun process(items: List) { 21 | for (i in items) { 22 | val newUser = i.newChatMember 23 | when (newUser.status) { 24 | "creator" -> ownersChanged += i 25 | "administrator" -> administratorsChanged += i 26 | "restricted" -> chatMembersRestricted += i 27 | "left" -> chatMemberLeft += i 28 | "kicked" -> chatMemberBanned += i 29 | "new" -> chatMemberNew += i 30 | } 31 | } 32 | 33 | if (ownersChanged.isNotEmpty()) { 34 | handler.ownersChanged(ownersChanged) 35 | ownersChanged.clear() 36 | } 37 | 38 | if (administratorsChanged.isNotEmpty()) { 39 | handler.administratorsChanged(administratorsChanged) 40 | administratorsChanged.clear() 41 | } 42 | 43 | if (chatMembersRestricted.isNotEmpty()) { 44 | handler.chatMembersRestricted(chatMembersRestricted) 45 | chatMembersRestricted.clear() 46 | } 47 | 48 | if (chatMemberNew.isNotEmpty()) { 49 | handler.chatMemberNew(chatMemberNew) 50 | chatMemberNew.clear() 51 | } 52 | 53 | if (chatMemberLeft.isNotEmpty()) { 54 | handler.chatMemberLeft(chatMemberLeft) 55 | chatMemberLeft.clear() 56 | } 57 | 58 | if (chatMemberBanned.isNotEmpty()) { 59 | handler.chatMemberBanned(chatMemberBanned) 60 | chatMemberBanned.clear() 61 | } 62 | } 63 | 64 | 65 | 66 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgEventMessagePackFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.* 4 | 5 | interface TgEventMessagePackFilter : TgEventPackFilter, TgMessagePackFilter, TgChatMemberUpdatedFilter -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgEventMessagePackHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.* 4 | 5 | interface TgEventMessagePackHandler: TgEventPackHandler, TgMessagePackHandler, TgChatMemberUpdatedHandler { 16 | } 17 | 18 | typealias TgEventMessagePackHandlerBasicTypes = TgEventMessagePackHandler -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgEventPackFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.* 4 | 5 | /** 6 | * @created 20.09.2019 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgEventPackFilter { 20 | fun messages(messages: List) : List 21 | fun editedMessages(messages: List) : List 22 | fun channelPosts(messages: List) : List 23 | fun editedChannelPosts(messages: List) : List 24 | fun inlineQueries(items: List): List 25 | fun chosenInlineResults(items: List): List 26 | fun callbackQueries(items: List): List 27 | fun shippingQueries(items: List): List 28 | fun preCheckoutQueries(items: List): List 29 | fun polls(items: List

): List

30 | fun pollAnswers(items: List): List 31 | fun myChatMembers(items: List): List 32 | fun chatMembers(items: List): List 33 | fun chatJoinRequests(items: List): List 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgEventPackHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.processors.TgEventHandler 5 | 6 | interface TgEventPackHandler: TgEventHandler { 17 | fun messages(messages: List) 18 | fun editedMessages(messages: List) 19 | fun channelPosts(messages: List) 20 | fun editedChannelPosts(messages: List) 21 | fun inlineQueries(items: List) 22 | fun chosenInlineResults(items: List) 23 | fun callbackQueries(items: List) 24 | fun shippingQueries(items: List) 25 | fun preCheckoutQueries(items: List) 26 | fun polls(items: List

) 27 | fun pollAnswers(items: List) 28 | fun myChatMembers(items: List) 29 | fun chatMembers(items: List) 30 | fun chatJoinRequests(items: List) 31 | } 32 | 33 | typealias TgEventPackHandlerBasicTypes = TgEventPackHandler -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgMessagePackFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.Message 4 | 5 | interface TgMessagePackFilter { 6 | fun texts(messages: List): List 7 | fun newChatMembers(messages: List): List 8 | fun leftChatMember(messages: List): List 9 | fun newChatTitle(messages: List): List 10 | fun newChatPhoto(messages: List): List 11 | fun deleteChatPhoto(messages: List): List 12 | fun groupChatCreated(messages: List): List 13 | fun supergroupChatCreated(messages: List): List 14 | fun channelChatCreated(messages: List): List 15 | fun messageAutoDeleteTimerChanged(messages: List): List 16 | fun migrateToChatId(messages: List): List 17 | fun migrateFromChatId(messages: List): List 18 | fun pinnedMessage(messages: List): List 19 | fun invoice(messages: List): List 20 | fun successfulPayment(messages: List): List 21 | fun connectedWebsite(messages: List): List 22 | fun passportData(messages: List): List 23 | fun proximityAlertTriggered(messages: List): List 24 | fun voiceChatScheduled(messages: List): List 25 | fun voiceChatStarted(messages: List): List 26 | fun voiceChatEnded(messages: List): List 27 | fun voiceChatParticipantsInvited(messages: List): List 28 | fun unresolvedMessages(messages: List): List 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgMessagePackHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.Message 4 | 5 | interface TgMessagePackHandler: TgTextPackHandler { 6 | fun newChatMembers(messages: List) 7 | fun leftChatMember(messages: List) 8 | fun newChatTitle(messages: List) 9 | fun newChatPhoto(messages: List) 10 | fun deleteChatPhoto(messages: List) 11 | fun groupChatCreated(messages: List) 12 | fun supergroupChatCreated(messages: List) 13 | fun channelChatCreated(messages: List) 14 | fun messageAutoDeleteTimerChanged(messages: List) 15 | fun migrateToChatId(messages: List) 16 | fun migrateFromChatId(messages: List) 17 | fun pinnedMessage(messages: List) 18 | fun invoice(messages: List) 19 | fun successfulPayment(messages: List) 20 | fun connectedWebsite(messages: List) 21 | fun passportData(messages: List) 22 | fun proximityAlertTriggered(messages: List) 23 | fun voiceChatScheduled(messages: List) 24 | fun voiceChatStarted(messages: List) 25 | fun voiceChatEnded(messages: List) 26 | fun voiceChatParticipantsInvited(messages: List) 27 | fun unresolvedMessages(messages: List) 28 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/TgTextPackHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.Message 4 | 5 | /** 6 | * @created 08.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgTextPackHandler { 10 | fun texts(messages: List) 11 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/pack/Update2CustomPackHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.pack 2 | 3 | import iris.tg.api.items.* 4 | 5 | /** 6 | * @created 11.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class Update2CustomPackHandler(private val handler: TgEventPackHandler) : TgEventPackHandlerBasicTypes { 20 | 21 | private fun Any.cast() = this as T 22 | 23 | override fun messages(messages: List) { 24 | handler.messages(messages.cast()) 25 | } 26 | 27 | override fun editedMessages(messages: List) { 28 | handler.editedMessages(messages.cast()) 29 | } 30 | 31 | override fun channelPosts(messages: List) { 32 | handler.channelPosts(messages.cast()) 33 | } 34 | 35 | override fun editedChannelPosts(messages: List) { 36 | handler.editedChannelPosts(messages.cast()) 37 | } 38 | 39 | override fun inlineQueries(items: List) { 40 | handler.inlineQueries(items.cast()) 41 | } 42 | 43 | override fun chosenInlineResults(items: List) { 44 | handler.chosenInlineResults(items.cast()) 45 | } 46 | 47 | override fun callbackQueries(items: List) { 48 | handler.callbackQueries(items.cast()) 49 | } 50 | 51 | override fun shippingQueries(items: List) { 52 | handler.shippingQueries(items.cast()) 53 | } 54 | 55 | override fun preCheckoutQueries(items: List) { 56 | handler.preCheckoutQueries(items.cast()) 57 | } 58 | 59 | override fun polls(items: List) { 60 | handler.polls(items.cast()) 61 | } 62 | 63 | override fun pollAnswers(items: List) { 64 | handler.pollAnswers(items.cast()) 65 | } 66 | 67 | override fun myChatMembers(items: List) { 68 | handler.myChatMembers(items.cast()) 69 | } 70 | 71 | override fun chatMembers(items: List) { 72 | handler.chatMembers(items.cast()) 73 | } 74 | 75 | override fun chatJoinRequests(items: List) { 76 | handler.chatJoinRequests(items.cast()) 77 | } 78 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgChatMemberUpdatedSingleFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.ChatMemberUpdated 4 | 5 | /** 6 | * @created 03.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgChatMemberUpdatedSingleFilter { 10 | fun ownerChanged(item: CMU): CMU? 11 | fun administratorChanged(item: CMU): CMU? 12 | fun administratorCanceled(item: CMU): CMU? 13 | fun chatMemberRestricted(item: CMU): CMU? 14 | fun chatMemberLeft(item: CMU): CMU? 15 | fun chatMemberBanned(item: CMU): CMU? 16 | fun chatMemberNew(item: CMU): CMU? 17 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgChatMemberUpdatedSingleHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.ChatMemberUpdated 4 | 5 | /** 6 | * @created 03.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgChatMemberUpdatedSingleHandler { 10 | fun ownerChanged(item: CMU) 11 | fun administratorChanged(item: CMU) 12 | fun administratorCanceled(item: CMU) 13 | fun chatMemberRestricted(item: CMU) 14 | fun chatMemberLeft(item: CMU) 15 | fun chatMemberBanned(item: CMU) 16 | fun chatMemberNew(item: CMU) 17 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgChatMemberUpdatedSplitter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.ChatMemberUpdated 4 | import iris.tg.api.items.Message 5 | 6 | /** 7 | * @created 03.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | class TgChatMemberUpdatedSplitter(private val handler: TgChatMemberUpdatedSingleHandler) { 11 | 12 | fun process(item: CMU) { 13 | val newUser = item.newChatMember 14 | when (newUser.status) { 15 | "creator" -> handler.ownerChanged(item) 16 | "administrator" -> handler.administratorChanged(item) 17 | "restricted" -> handler.chatMemberRestricted(item) 18 | "left" -> handler.chatMemberLeft(item) 19 | "kicked" -> handler.chatMemberBanned(item) 20 | "new" -> handler.chatMemberNew(item) 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgEventMessageSingleFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.* 4 | 5 | interface TgEventMessageSingleFilter : TgEventSingleFilter, TgMessageSingleFilter, TgChatMemberUpdatedSingleFilter -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgEventMessageSingleHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.* 4 | 5 | interface TgEventMessageSingleHandler: TgEventSingleHandler, TgMessageSingleHandler, TgChatMemberUpdatedSingleHandler 16 | 17 | typealias TgEventMessageSingleHandlerBasicTypes = TgEventMessageSingleHandler -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgEventSingleFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.processors.TgEventHandler 5 | 6 | /** 7 | * @created 20.09.2019 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | interface TgEventSingleFilter : TgEventHandler { 21 | fun message(message: M): M? 22 | fun editedMessage(message: M): M? 23 | fun channelPost(message: M): M? 24 | fun editedChannelPost(message: M): M? 25 | fun inlineQuery(item: IQ): IQ? 26 | fun chosenInlineResult(item: CIR): CIR? 27 | fun callbackQuery(item: CQ): CQ? 28 | fun shippingQuery(item: SQ): SQ? 29 | fun preCheckoutQuery(item: PCQ): PCQ? 30 | fun poll(item: P): P? 31 | fun pollAnswer(item: PA): PA? 32 | fun myChatMember(item: CMU): CMU? 33 | fun chatMember(item: CMU): CMU? 34 | fun chatJoinRequest(item: CJR): CJR? 35 | } 36 | 37 | typealias TgEventSingleFilterBasicTypes = TgEventSingleFilter -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgEventSingleHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.processors.TgEventHandler 5 | 6 | /** 7 | * @created 01.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | interface TgEventSingleHandler : TgEventHandler { 21 | fun message(message: M) 22 | fun editedMessage(message: M) 23 | fun channelPost(message: M) 24 | fun editedChannelPost(message: M) 25 | fun inlineQuery(item: IQ) 26 | fun chosenInlineResult(item: CIR) 27 | fun callbackQuery(item: CQ) 28 | fun shippingQuery(item: SQ) 29 | fun preCheckoutQuery(item: PCQ) 30 | fun poll(item: P) 31 | fun pollAnswer(item: PA) 32 | fun myChatMember(item: CMU) 33 | fun chatMember(item: CMU) 34 | fun chatJoinRequest(item: CJR) 35 | } 36 | 37 | typealias TgEventSingleHandlerBasicTypes = TgEventSingleHandler< 38 | Message 39 | , InlineQuery 40 | , ChosenInlineResult 41 | , CallbackQuery 42 | , ShippingQuery 43 | , PreCheckoutQuery 44 | , Poll 45 | , PollAnswer 46 | , ChatMemberUpdated 47 | , ChatJoinRequest 48 | > -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgEventSplitMessageHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.* 4 | 5 | class TgEventSplitMessageHandler(private val handler: TgMessageSingleHandler) { 6 | 7 | fun message(message: M) { 8 | try { 9 | message.text?.also { handler.text(message) } 10 | ?: message.sticker?.also { handler.text(message) } 11 | ?: message.photo?.also { handler.text(message) } 12 | ?: message.animation?.also { handler.text(message) } 13 | ?: message.video?.also { handler.text(message) } 14 | ?: message.videoNote?.also { handler.text(message) } 15 | ?: message.audio?.also { handler.text(message) } 16 | ?: message.caption?.also { handler.text(message) } 17 | ?: message.newChatMembers?.also { handler.newChatMember(message) } 18 | ?: message.leftChatMember?.also { handler.leftChatMember(message) } 19 | ?: message.newChatTitle?.also { handler.newChatTitle(message) } 20 | ?: message.newChatPhoto?.also { handler.newChatPhoto(message) } 21 | ?: if (message.deleteChatPhoto) { handler.deleteChatPhoto(message) } 22 | else if (message.groupChatCreated) { handler.groupChatCreated(message) } 23 | else if (message.supergroupChatCreated) { handler.supergroupChatCreated(message) } 24 | else if (message.channelChatCreated) { handler.channelChatCreated(message) } 25 | else message.messageAutoDeleteTimerChanged?.apply { handler.messageAutoDeleteTimerChanged(message) } 26 | ?: if (message.migrateToChatId != 0L) { handler.migrateToChatId(message) } 27 | else if (message.migrateFromChatId != 0L) { handler.migrateFromChatId(message) } 28 | else message.pinnedMessage?.also { handler.pinnedMessage(message) } 29 | 30 | ?: message.invoice?.also { handler.invoice(message) } 31 | ?: message.successfulPayment?.also { handler.successfulPayment(message) } 32 | ?: message.connectedWebsite?.also { handler.connectedWebsite(message) } 33 | ?: message.passportData?.also { handler.passportData(message) } 34 | ?: message.proximityAlertTriggered?.also { handler.proximityAlertTriggered(message) } 35 | ?: message.voiceChatScheduled?.also { handler.voiceChatScheduled(message) } 36 | ?: message.voiceChatStarted?.also { handler.voiceChatStarted(message) } 37 | ?: message.voiceChatEnded?.also { handler.voiceChatEnded(message) } 38 | ?: message.voiceChatParticipantsInvited?.also { handler.voiceChatParticipantsInvited(message) } 39 | ?: run { handler.text(message) } 40 | } catch (e: Throwable) { 41 | System.err.println(e.message!!) 42 | println(message) 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgMessageSingleFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.Message 4 | 5 | interface TgMessageSingleFilter { 6 | fun text(message: M): M? 7 | fun newChatMember(message: M): M? 8 | fun leftChatMember(message: M): M? 9 | fun newChatTitle(message: M): M? 10 | fun newChatPhoto(message: M): M? 11 | fun deleteChatPhoto(message: M): M? 12 | fun groupChatCreated(message: M): M? 13 | fun supergroupChatCreated(message: M): M? 14 | fun channelChatCreated(message: M): M? 15 | fun messageAutoDeleteTimerChanged(message: M): M? 16 | fun migrateToChatId(message: M): M? 17 | fun migrateFromChatId(message: M): M? 18 | fun pinnedMessage(message: M): M? 19 | fun invoice(message: M): M? 20 | fun successfulPayment(message: M): M? 21 | fun connectedWebsite(message: M): M? 22 | fun passportData(message: M): M? 23 | fun proximityAlertTriggered(message: M): M? 24 | fun voiceChatScheduled(message: M): M? 25 | fun voiceChatStarted(message: M): M? 26 | fun voiceChatEnded(message: M): M? 27 | fun voiceChatParticipantsInvited(message: M): M? 28 | fun unresolvedMessage(message: M): M? 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgMessageSingleHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.Message 4 | 5 | interface TgMessageSingleHandler { 6 | fun text(message: M) 7 | fun newChatMember(message: M) 8 | fun leftChatMember(message: M) 9 | fun newChatTitle(message: M) 10 | fun newChatPhoto(message: M) 11 | fun deleteChatPhoto(message: M) 12 | fun groupChatCreated(message: M) 13 | fun supergroupChatCreated(message: M) 14 | fun channelChatCreated(message: M) 15 | fun messageAutoDeleteTimerChanged(message: M) 16 | fun migrateToChatId(message: M) 17 | fun migrateFromChatId(message: M) 18 | fun pinnedMessage(message: M) 19 | fun invoice(message: M) 20 | fun successfulPayment(message: M) 21 | fun connectedWebsite(message: M) 22 | fun passportData(message: M) 23 | fun proximityAlertTriggered(message: M) 24 | fun voiceChatScheduled(message: M) 25 | fun voiceChatStarted(message: M) 26 | fun voiceChatEnded(message: M) 27 | fun voiceChatParticipantsInvited(message: M) 28 | fun unresolvedMessage(message: M) 29 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgTextSingleHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.Message 4 | 5 | /** 6 | * @created 08.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | interface TgTextSingleHandler { 10 | fun text(message: M) 11 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/TgUpdateProcessorSingle.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.processors.TgUpdateProcessor 5 | 6 | /** 7 | * @created 31.10.2020 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | open class TgUpdateProcessorSingle(private val updateHandler: TgEventSingleHandlerBasicTypes) : TgUpdateProcessor { 11 | 12 | override fun processUpdates(updates: List) { 13 | updates.forEach(this::processUpdate) 14 | } 15 | 16 | override fun processUpdate(update: Update) { 17 | update.message?.also { updateHandler.message(it) } 18 | ?: update.editedMessage?.also { updateHandler.editedMessage(it) } 19 | ?: update.chatMember?.also { updateHandler.chatMember(it) } 20 | ?: update.callbackQuery?.also { updateHandler.callbackQuery(it) } 21 | ?: update.pollAnswer?.also { updateHandler.pollAnswer(it) } 22 | ?: update.poll?.also { updateHandler.poll(it) } 23 | ?: update.channelPost?.also { updateHandler.channelPost(it) } 24 | ?: update.editedChannelPost?.also { updateHandler.editedChannelPost(it) } 25 | ?: update.inlineQuery?.also { updateHandler.inlineQuery(it) } 26 | ?: update.chosenInlineResult?.also { updateHandler.chosenInlineResult(it) } 27 | ?: update.shippingQuery?.also { updateHandler.shippingQuery(it) } 28 | ?: update.preCheckoutQuery?.also { updateHandler.preCheckoutQuery(it) } 29 | ?: update.myChatMember?.also { updateHandler.myChatMember(it) } 30 | ?: update.chatJoinRequest?.also { updateHandler.chatJoinRequest(it) } 31 | } 32 | } -------------------------------------------------------------------------------- /src/iris/tg/processors/single/Update2CustomSingleHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.processors.single 2 | 3 | import iris.tg.api.items.* 4 | 5 | /** 6 | * @created 11.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class Update2CustomSingleHandler(private val handler: TgEventSingleHandler) : TgEventSingleHandlerBasicTypes { 20 | 21 | private fun Any.cast() = this as T 22 | 23 | override fun message(message: Message) { 24 | handler.message(message.cast()) 25 | } 26 | 27 | override fun editedMessage(message: Message) { 28 | handler.editedMessage(message.cast()) 29 | } 30 | 31 | override fun channelPost(message: Message) { 32 | handler.channelPost(message.cast()) 33 | } 34 | 35 | override fun editedChannelPost(message: Message) { 36 | handler.editedChannelPost(message.cast()) 37 | } 38 | 39 | override fun inlineQuery(item: InlineQuery) { 40 | handler.inlineQuery(item.cast()) 41 | } 42 | 43 | override fun chosenInlineResult(item: ChosenInlineResult) { 44 | handler.chosenInlineResult(item.cast()) 45 | } 46 | 47 | override fun callbackQuery(item: CallbackQuery) { 48 | handler.callbackQuery(item.cast()) 49 | } 50 | 51 | override fun shippingQuery(item: ShippingQuery) { 52 | handler.shippingQuery(item.cast()) 53 | } 54 | 55 | override fun preCheckoutQuery(item: PreCheckoutQuery) { 56 | handler.preCheckoutQuery(item.cast()) 57 | } 58 | 59 | override fun poll(item: Poll) { 60 | handler.poll(item.cast()) 61 | } 62 | 63 | override fun pollAnswer(item: PollAnswer) { 64 | handler.pollAnswer(item.cast()) 65 | } 66 | 67 | override fun myChatMember(item: ChatMemberUpdated) { 68 | handler.myChatMember(item.cast()) 69 | } 70 | 71 | override fun chatMember(item: ChatMemberUpdated) { 72 | handler.chatMember(item.cast()) 73 | } 74 | 75 | override fun chatJoinRequest(item: ChatJoinRequest) { 76 | handler.chatJoinRequest(item.cast()) 77 | } 78 | } -------------------------------------------------------------------------------- /src/iris/tg/py/PyResponseHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py 2 | 3 | import iris.json.flow.JsonFlowParser 4 | import iris.tg.api.TgApiObjFuture 5 | import iris.tg.irisjson.ResponseHandler_IrisJsonObj 6 | import iris.tg.irisjson.response.* 7 | import iris.tg.py.response.PyGetUpdateResponse 8 | import iris.tg.py.response.PySendMessageResponse 9 | import java.io.InputStream 10 | 11 | open class PyResponseHandler(var bot: Bot? = null) : ResponseHandler_IrisJsonObj() { 12 | 13 | override fun process(method: String, data: String?): IrisJsonResponse { 14 | data ?: throw NullPointerException("data is null") 15 | val json = JsonFlowParser.start(data) 16 | return when (method) { 17 | "getUpdates" -> PyGetUpdateResponse(bot, json) 18 | "sendMessage" -> PySendMessageResponse(json) 19 | "editMessageText" -> PySendMessageResponse(json) 20 | 21 | "getChatMember" -> IrisJsonGetChatMemberResponse(json) 22 | "getChatAdministrators" -> IrisJsonGetChatAdministratorsResponse(json) 23 | "getChatMemberCount" -> IrisJsonGetChatMemberCountResponse(json) 24 | "banChatMember" -> IrisJsonBanChatMemberResponse(json) 25 | "unbanChatMember" -> IrisJsonBooleanResponse(json) 26 | "getChat" -> IrisJsonGetChatResponse(json) 27 | "deleteMessage" -> IrisJsonBooleanResponse(json) 28 | "sendPhoto" -> PySendMessageResponse(json) 29 | "getFile" -> IrisJsonGetFileResponse(json) 30 | "answerCallbackQuery" -> IrisJsonBooleanResponse(json) 31 | "restrictChatMember" -> IrisJsonBooleanResponse(json) 32 | else -> IrisJsonResponseDefault(json) 33 | } 34 | } 35 | 36 | override fun process(method: String, inputStream: InputStream): IrisJsonResponse { 37 | TODO("Not yet implemented") 38 | } 39 | } -------------------------------------------------------------------------------- /src/iris/tg/py/PySingleHandlerConverter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.processors.pack.TgEventMessagePackFilter 5 | import iris.tg.processors.pack.TgEventMessagePackFilterAdapter 6 | import iris.tg.processors.pack.TgEventMessagePackHandler 7 | import iris.tg.processors.pack.TgEventMessagePackHandlerAdapter 8 | import iris.tg.processors.single.* 9 | import iris.tg.py.items.PyCallbackQuery 10 | import iris.tg.py.items.PyMessage 11 | 12 | interface PySingleHandler: TgEventMessageSingleHandler 13 | interface PyPackHandler: TgEventMessagePackHandler 14 | 15 | open class PySingleHandlerAdapter: TgEventMessageSingleHandlerAdapter(), PySingleHandler 16 | open class PyPackHandlerAdapter: TgEventMessagePackHandlerAdapter(), PyPackHandler 17 | 18 | interface PySingleFilter: TgEventMessageSingleFilter 19 | interface PyPackFilter: TgEventMessagePackFilter 20 | 21 | open class PySingleFilterAdapter: TgEventMessageSingleFilterAdapter(), PySingleFilter 22 | open class PyPackFilterAdapter: TgEventMessagePackFilterAdapter(), PyPackFilter 23 | 24 | class PySingleHandlerConverter(handler: PySingleHandler) 25 | : TgEventSingleBasicType2CustomHandler 26 | (handler) 27 | 28 | class PyPackHandlerConverter(handler: PySingleHandler) 29 | : TgEventSingleBasicType2CustomHandler 30 | (handler) -------------------------------------------------------------------------------- /src/iris/tg/py/TriggerFilterHandlerPackPy.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.py.items.PyCallbackQuery 5 | import iris.tg.py.items.PyMessage 6 | import iris.tg.trigger.TriggerHandlerPack 7 | import iris.tg.trigger.TriggerPackFilterHandler 8 | 9 | /** 10 | * @created 12.02.2022 11 | * @author [Ivan Ivanov](https://t.me/irisism) 12 | */ 13 | open class TriggerFilterHandlerPackPy(handler: TriggerHandlerPackPy) : TriggerPackFilterHandler(handler) { 24 | } -------------------------------------------------------------------------------- /src/iris/tg/py/TriggerHandlerPackPy.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.py.items.PyCallbackQuery 5 | import iris.tg.py.items.PyMessage 6 | import iris.tg.trigger.TriggerHandlerPack 7 | 8 | /** 9 | * @created 12.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | class TriggerHandlerPackPy : TriggerHandlerPack() { 23 | } -------------------------------------------------------------------------------- /src/iris/tg/py/TriggerHandlerSinglePy.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py 2 | 3 | import iris.tg.api.items.* 4 | import iris.tg.py.items.PyCallbackQuery 5 | import iris.tg.py.items.PyMessage 6 | import iris.tg.trigger.TriggerHandlerSingle 7 | 8 | /** 9 | * @created 11.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | class TriggerHandlerSinglePy : TriggerHandlerSingle() { 23 | } -------------------------------------------------------------------------------- /src/iris/tg/py/items/PyCallbackQuery.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.CallbackQuery 5 | import iris.tg.irisjson.items.IrisJsonCallbackQuery 6 | import iris.tg.py.Bot 7 | 8 | class PyCallbackQuery(bot: Bot?, source: JsonItem) : PyItem(bot), CallbackQuery by IrisJsonCallbackQuery(source) { 9 | override val fromChatId: Long 10 | get() = message!!.chat.id 11 | } -------------------------------------------------------------------------------- /src/iris/tg/py/items/PyItem.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py.items 2 | 3 | import iris.tg.api.TgApiObjFuture 4 | import iris.tg.api.response.SendMessageResponse 5 | import iris.tg.py.Bot 6 | import java.util.concurrent.CompletableFuture 7 | 8 | abstract class PyItem(val bot: Bot?) { 9 | 10 | fun answer(text: String): CompletableFuture? { 11 | return bot?.api?.sendMessage(fromChatId, text) 12 | } 13 | 14 | abstract val fromChatId: Long 15 | } -------------------------------------------------------------------------------- /src/iris/tg/py/items/PyMessage.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Message 5 | import iris.tg.irisjson.items.IrisJsonMessage 6 | import iris.tg.py.Bot 7 | 8 | class PyMessage(bot: Bot?, source: JsonItem) : PyItem(bot), Message by IrisJsonMessage(source) { 9 | override val fromChatId: Long 10 | get() = chat.id 11 | } -------------------------------------------------------------------------------- /src/iris/tg/py/items/PyUpdate.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py.items 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.items.Message 5 | import iris.tg.api.items.Update 6 | import iris.tg.irisjson.items.IrisJsonUpdate 7 | import iris.tg.py.Bot 8 | 9 | class PyUpdate(bot: Bot?, source: JsonItem) : Update by IrisJsonUpdate(source) { 10 | override val message: PyMessage? by lazy { with(source["message"]) { if (isNull()) null else PyMessage(bot, this) } } 11 | override val editedMessage: Message? by lazy { with(source["edited_message"]) { if (isNull()) null else PyMessage(bot, this) } } 12 | override val callbackQuery: PyCallbackQuery? by lazy { with(source["callback_query"]) { if (isNull()) null else PyCallbackQuery(bot, this)} } 13 | } -------------------------------------------------------------------------------- /src/iris/tg/py/response/PyGetUpdateResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.irisjson.response.IrisJsonGetUpdatesResponse 5 | import iris.tg.py.Bot 6 | import iris.tg.py.items.PyUpdate 7 | 8 | class PyGetUpdateResponse(bot: Bot?, source: JsonItem): IrisJsonGetUpdatesResponse(source), PyResponse { 9 | override val result: List? by lazy { with(source["result"]) { iterable().map { PyUpdate(bot, it) } }} 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/iris/tg/py/response/PyResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py.response 2 | 3 | import iris.tg.api.response.TgResponse 4 | 5 | interface PyResponse : TgResponse -------------------------------------------------------------------------------- /src/iris/tg/py/response/PySendMessageResponse.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.py.response 2 | 3 | import iris.json.JsonItem 4 | import iris.tg.api.response.SendMessageResponse 5 | import iris.tg.irisjson.response.IrisJsonResponse 6 | import iris.tg.py.Bot 7 | import iris.tg.py.items.PyMessage 8 | 9 | /** 10 | * @created 02.02.2022 11 | * @author [Ivan Ivanov](https://t.me/irisism) 12 | */ 13 | open class PySendMessageResponse(source: JsonItem) : IrisJsonResponse(source), SendMessageResponse, PyResponse { 14 | override val result by lazyItemOrNull("result") { PyMessage(null, it) } 15 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerHandlerPackBasicTypes.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | import iris.tg.api.items.* 4 | 5 | /** 6 | * @created 11.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class TriggerHandlerPackBasicTypes : TriggerHandlerPack() -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerHandlerSingleBasicTypes.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | import iris.tg.api.items.* 4 | 5 | /** 6 | * @created 11.02.2022 7 | * @author [Ivan Ivanov](https://t.me/irisism) 8 | */ 9 | class TriggerHandlerSingleBasicTypes() : TriggerHandlerSingle() { 20 | constructor(initializer: TriggerHandlerSingleBasicTypes.() -> Unit) : this() { 21 | apply(initializer) 22 | } 23 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerPack.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | /** 4 | * @created 11.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TriggerPack { 8 | fun process(events: List) 9 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerPack2Lambda.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | /** 4 | * @created 12.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | open class TriggerPack2Lambda(private val lambda: (M) -> Unit) : TriggerPack { 8 | override fun process(events: List) { 9 | events.forEach(lambda) 10 | } 11 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerPack2Single.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | /** 4 | * @created 12.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | open class TriggerPack2Single(private val singleHandler: TriggerSingle) : TriggerPack { 8 | override fun process(events: List) { 9 | events.forEach(singleHandler::process) 10 | } 11 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerPackFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | /** 4 | * @created 11.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TriggerPackFilter { 8 | fun process(events: List): List 9 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerPackFilterLambda.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | class TriggerPackFilterLambda(private val action: (List) -> List) : TriggerPackFilter { 4 | override fun process(events: List): List { 5 | return action(events) 6 | } 7 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerPackFilterSingleLambda.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | /** 4 | * @created 12.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | class TriggerPackFilterSingleLambda(private val action: (T) -> Boolean) : TriggerPackFilter { 8 | override fun process(events: List): List { 9 | return events.filter(action) 10 | } 11 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerPackLambda.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | class TriggerPackLambda(private val action: (List) -> Unit) : TriggerPack { 4 | override fun process(events: List) { 5 | action(events) 6 | } 7 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerSingle.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | /** 4 | * @created 11.02.2022 5 | * @author [Ivan Ivanov](https://t.me/irisism) 6 | */ 7 | interface TriggerSingle { 8 | fun process(m: T) 9 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerSingleFilter.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | interface TriggerSingleFilter { 4 | fun process(event: T): Boolean 5 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerSingleFilterLambda.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | class TriggerSingleFilterLambda(private val action: (T) -> Boolean) : TriggerSingleFilter { 4 | 5 | override fun process(event: T): Boolean 6 | = action(event) 7 | } -------------------------------------------------------------------------------- /src/iris/tg/trigger/TriggerSingleLambda.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.trigger 2 | 3 | class TriggerSingleLambda(private val action: (T) -> Unit) : TriggerSingle { 4 | override fun process(m: T) { 5 | action(m) 6 | } 7 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/AddressTester.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | /** 4 | * Проверяет подлинность источника входящего запроса 5 | * 6 | * [AddressTesterDefault] — реализует проверку входящего адреса на принадлежность указанным подсетям. По умолчанию 7 | * `95.142.192.0/21` и `2a00:bdc0::/32` 8 | * 9 | * @see AddressTesterDefault 10 | */ 11 | interface AddressTester { 12 | 13 | /** 14 | * Проверяет подлинность источника. 15 | */ 16 | fun isGoodHost(request: TgWebhookRequestHandler.Request): Boolean 17 | 18 | /** 19 | * Должен вернуть IP адрес реального источника. Если запрос происходит от источника через прокси,например, Cloudflare 20 | * или локальный проброс порта. 21 | * 22 | * Вызывается исключительно для логгирования неизвестных IP адресов 23 | */ 24 | fun getRealHost(request: TgWebhookRequestHandler.Request): String 25 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/BotSource.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | interface BotSource { 4 | /** 5 | * Извлекает информацию о группе из запроса, содержащуюся в URI или query. 6 | * 7 | * Например, URI может содержать такую информацию `/callback/fa33a6`, где код `fa33a6` сопоставляется с 8 | * одной из имеющихся групп. 9 | */ 10 | fun getBot(request: TgWebhookRequestHandler.Request): BotData? 11 | 12 | open class BotData(val id: Long) { 13 | companion object { 14 | val zero = BotData(0) 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/BotSourceSimple.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | class BotSourceSimple(private val gb: BotSource.BotData) : BotSource { 4 | 5 | override fun getBot(request: TgWebhookRequestHandler.Request) = gb 6 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/TgWebhookBot.kt1: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | import iris.tg.TgReadWriteUpdateBuffer 4 | import iris.tg.api.items.Update 5 | import iris.tg.processors.TgUpdateProcessor 6 | import iris.tg.processors.pack.TgEventPackHandler 7 | import iris.tg.processors.pack.TgEventPackHandlerBasicTypes 8 | import iris.tg.processors.pack.TgUpdateProcessorPack 9 | import iris.tg.processors.single.TgEventSingleHandler 10 | import iris.tg.processors.single.TgUpdateProcessorSingle 11 | 12 | /** 13 | * @created 02.11.2020 14 | * @author [Ivan Ivanov](https://t.me/irisism) 15 | */ 16 | @Deprecated("Заменили на QueuedService") 17 | class TgWebhookBot( 18 | private val server: TgWebhookRequestServer, 19 | private val updateProcessor: TgUpdateProcessor, 20 | private val buffer: TgReadWriteUpdateBuffer, 21 | ) : Runnable { 22 | 23 | constructor(server: TgWebhookRequestServer, handler: TgEventSingleHandler, buffer: TgReadWriteUpdateBuffer) 24 | : this(server, TgUpdateProcessorSingle(handler), buffer) 25 | 26 | constructor(server: TgWebhookRequestServer, handler: TgEventPackHandlerBasicTypes, buffer: TgReadWriteUpdateBuffer) 27 | : this(server, TgUpdateProcessorPack(handler), buffer) 28 | 29 | private var working = true 30 | 31 | override fun run() { 32 | server.start() 33 | working = true 34 | val thisThread = thread ?: Thread.currentThread() 35 | while (!thisThread.isInterrupted && working) { 36 | val items = buffer.readAll() 37 | if (items.isEmpty()) continue 38 | updateProcessor.processUpdates(items) 39 | } 40 | } 41 | 42 | private var thread: Thread? = null 43 | 44 | fun startPolling() { 45 | thread?.interrupt() 46 | thread = Thread(this).also { it.start() } 47 | } 48 | 49 | fun stop() { 50 | server.stop(5) 51 | working = false 52 | thread?.interrupt() 53 | } 54 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/TgWebhookMultibot.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | import iris.tg.TgReadWriteUpdateBuffer 4 | import iris.tg.api.items.UpdateExt 5 | import iris.tg.processors.TgUpdateProcessor 6 | 7 | /** 8 | * @created 02.11.2020 9 | * @author [Ivan Ivanov](https://t.me/irisism) 10 | */ 11 | @Deprecated("Заменили на QueuedService") 12 | class TgWebhookMultibot( 13 | private val server: TgWebhookRequestServer, 14 | private val updateProcessor: TgUpdateProcessor, 15 | private val buffer: TgReadWriteUpdateBuffer, 16 | ) : Runnable { 17 | 18 | /*constructor(server: TgWebhookRequestServer, handler: TgEventSingleHandler, buffer: TgReadWriteUpdateBuffer) 19 | : this(server, TgUpdateExtToSimpleProcessor(TgUpdateProcessorSingle(handler)), buffer) 20 | 21 | constructor(server: TgWebhookRequestServer, handler: TgEventPackHandler, buffer: TgReadWriteUpdateBuffer) 22 | : this(server, TgUpdateExtToSimpleProcessor(TgUpdateProcessorPack(handler)), buffer)*/ 23 | 24 | private var working = true 25 | 26 | override fun run() { 27 | server.start() 28 | working = true 29 | val thisThread = thread ?: Thread.currentThread() 30 | while (!thisThread.isInterrupted && working) { 31 | val items = buffer.readAll() 32 | if (items.isEmpty()) continue 33 | updateProcessor.processUpdates(items) 34 | } 35 | } 36 | 37 | private var thread: Thread? = null 38 | 39 | fun startPolling() { 40 | thread?.interrupt() 41 | thread = Thread(this).also { it.start() } 42 | } 43 | 44 | fun stop() { 45 | server.stop(5) 46 | working = false 47 | thread?.interrupt() 48 | } 49 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/TgWebhookRequestHandler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | import java.net.InetSocketAddress 4 | import java.net.URI 5 | 6 | /** 7 | * @created 26.12.2020 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | interface TgWebhookRequestHandler { 11 | 12 | fun handle(request: Request) 13 | 14 | interface Request { 15 | 16 | fun findHeader(key: String): String? 17 | 18 | val requestUri: URI 19 | 20 | val remoteAddress: InetSocketAddress 21 | 22 | fun writeResponse(response: String, code: Int = 200) 23 | 24 | fun body(): String 25 | } 26 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/TgWebhookRequestServer.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | import iris.tg.TgService 4 | 5 | /** 6 | * Можно взаимодействовать с любой реализацией сервера входящих запросов через данный интерфейс 7 | * в метод `setHandler` передаётся обработчик запросов по указанному URI 8 | * Данный сервер должен вызывать метод `TgWebhookRequestHandler.handle(request: Request)` каждый раз, как получает входящий запрос 9 | * @see TgWebhookRequestServerDefault — базовая реализация сервера входящих запросов 10 | */ 11 | interface TgWebhookRequestServer : TgService { 12 | 13 | fun setHandler(path: String, handler: TgWebhookRequestHandler) 14 | fun stop(seconds: Int) 15 | 16 | } -------------------------------------------------------------------------------- /src/iris/tg/webhook/TgWebhookRequestServerDefault.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.webhook 2 | 3 | import com.sun.net.httpserver.HttpExchange 4 | import com.sun.net.httpserver.HttpHandler 5 | import com.sun.net.httpserver.HttpServer 6 | import java.net.InetSocketAddress 7 | import java.net.URI 8 | 9 | /** 10 | * Обёртка для HttpServer и обработки входящих запросов 11 | */ 12 | class TgWebhookRequestServerDefault(private val server: HttpServer): HttpHandler, TgWebhookRequestServer { 13 | 14 | private class DefaultRequest(private val request: HttpExchange) : TgWebhookRequestHandler.Request { 15 | 16 | override val requestUri: URI = request.requestURI 17 | 18 | override val remoteAddress: InetSocketAddress = request.remoteAddress 19 | 20 | override fun findHeader(key: String): String? { 21 | return request.requestHeaders.getFirst(key) 22 | } 23 | 24 | override fun writeResponse(response: String, code: Int) { 25 | _writeResponse(response, code) 26 | } 27 | 28 | override fun body(): String { 29 | return request.requestBody.reader().use { it.readText() } 30 | } 31 | 32 | private fun _writeResponse(str: String, rCode: Int = 200) { 33 | val bytes = str.toByteArray() 34 | val request = this.request 35 | request.sendResponseHeaders(rCode, bytes.size.toLong()) 36 | request.responseBody.use { it.write(bytes) } 37 | request.close() 38 | } 39 | } 40 | 41 | private lateinit var handler: TgWebhookRequestHandler 42 | 43 | override fun setHandler(path: String, handler: TgWebhookRequestHandler) { 44 | this.handler = handler 45 | server.createContext(path, this) 46 | } 47 | 48 | override fun handle(exchange: HttpExchange) { 49 | handler.handle(DefaultRequest(exchange)) 50 | } 51 | 52 | override fun start() { 53 | try { 54 | server.start() 55 | } catch (e: IllegalStateException) { 56 | e.printStackTrace() 57 | } 58 | } 59 | 60 | override fun stop(seconds: Int) { 61 | server.stop(seconds) 62 | } 63 | 64 | override fun stop() { 65 | stop(1) 66 | } 67 | 68 | override fun join() { 69 | TODO("Not yet implemented") 70 | } 71 | 72 | override fun run() = start() 73 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/10.0_py_doorway_handler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.TgApiObject 4 | import iris.tg.longpoll.TgLongPoll 5 | import iris.tg.py.items.PyCallbackQuery 6 | import iris.tg.py.PySingleHandlerConverter 7 | import iris.tg.py.PyResponseHandler 8 | import iris.tg.py.PySingleHandler 9 | import iris.tg.py.PySingleHandlerAdapter 10 | import iris.tg.py.items.PyMessage 11 | 12 | /** 13 | * @created 07.02.2022 14 | * @author [Ivan Ivanov](https://vk.com/irisism) 15 | */ 16 | fun main() { 17 | 18 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 19 | TestUtil.init() 20 | val properties = TestUtil.properties 21 | val token = properties.getProperty("bot.token") 22 | 23 | val handler = object : PySingleHandlerAdapter() { 24 | 25 | override fun text(message: PyMessage) { 26 | message.answer("Ну вот лови обратку") 27 | } 28 | 29 | override fun callbackQuery(item: PyCallbackQuery) { 30 | item.answer("Да-да. Окей") 31 | } 32 | } 33 | 34 | val api = TgApiObject(token, PyResponseHandler()) 35 | val lp = TgLongPoll(api, PySingleHandlerConverter(handler)) 36 | lp.run() 37 | } 38 | 39 | -------------------------------------------------------------------------------- /test/iris/tg/examples/10.1_py_bottle_bot.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.AllowedUpdates 4 | import iris.tg.py.Bot 5 | 6 | /** 7 | * @created 08.02.2022 8 | * @author [Ivan Ivanov](https://t.me/irisism) 9 | */ 10 | fun main() { 11 | 12 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 13 | TestUtil.init() 14 | val properties = TestUtil.properties 15 | val token = properties.getProperty("bot.token") 16 | val toId = properties.getProperty("userTo.id").toLong() 17 | 18 | val bot = Bot(token, dropPending = true, allowedUpdates = AllowedUpdates.All) 19 | 20 | bot.defaultSendSettings.parseMode = "HTML" 21 | bot.defaultSendSettings.disableWebPagePreview = true 22 | 23 | bot.on.message { 24 | it.answer("Привет, @${it.from!!.username}. Как дела?") 25 | } 26 | 27 | bot.on.messages { 28 | it.forEach { 29 | it.answer("А это я ещё и рассылаю приветствие, @${it.from!!.username}. Как дела?") 30 | } 31 | } 32 | 33 | bot.on.messageEdit { 34 | it.answer("Не трогай редач") 35 | } 36 | 37 | bot.commands { 38 | 39 | text("привет") { 40 | it.answer("Привет, ${it.from!!.firstName}!") 41 | } 42 | 43 | text("пинг", "кинг") { 44 | it.answer( 45 | when (it.text?.lowercase()) { 46 | "пинг" -> "ПОНГ!" 47 | "кинг" -> "КОНГ!" 48 | else -> "Не понял" 49 | } 50 | ) 51 | } 52 | 53 | } 54 | 55 | bot.filter.onMessage { 56 | // отфильтруем только те сообщения, которые предназначены вашему аккаунту [toId] 57 | it.from!!.id == toId 58 | } 59 | 60 | bot.run_forever() 61 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/10.2_py_custom_response_handler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.AllowedUpdates 4 | import iris.tg.irisjson.response.IrisJsonResponse 5 | import iris.tg.py.Bot 6 | import iris.tg.py.PyResponseHandler 7 | 8 | /** 9 | * @created 12.02.2022 10 | * @author [Ivan Ivanov](https://t.me/irisism) 11 | */ 12 | fun main() { 13 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 14 | TestUtil.init() 15 | val properties = TestUtil.properties 16 | val token = properties.getProperty("bot.token") 17 | val responseHandler = MyPyResponseHandler() 18 | 19 | val bot = Bot(token, responseHandler = responseHandler) 20 | responseHandler.bot = bot 21 | 22 | // Вызовем ошибку 23 | val res = bot.api.sendMessage(1, "Вызовем ошибку, отправив в несуществующий чат").get() 24 | if (res.ok) 25 | println("Каким-то чудом ошибки не произошло: $res") 26 | 27 | bot.run_forever() 28 | } 29 | 30 | class MyPyResponseHandler : PyResponseHandler() { 31 | override fun process(method: String, data: String?): IrisJsonResponse { 32 | val res = super.process(method, data) 33 | if (!res.ok) { 34 | IllegalStateException("TG API Error: " + with(res.error) { "$description ($errorCode)" }).printStackTrace() 35 | } 36 | return res 37 | } 38 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/1_send_message.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.tgApi 4 | 5 | /** 6 | * @created 30.10.2020 7 | * @author [Ivan Ivanov](https://vk.com/irisism) 8 | */ 9 | fun main() { 10 | 11 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 12 | TestUtil.init() 13 | val properties = TestUtil.properties 14 | val token = properties.getProperty("bot.token") 15 | val toId = properties.getProperty("userTo.id").toLong() 16 | 17 | 18 | // Создаём объект TgApi с подготовленными по умолчанию настройками 19 | val api = tgApi(token) 20 | 21 | // Наш первый запрос к серверу Телеграм 22 | val res = api.sendMessage(toId, "💝 Это сообщение отправлено с помощью Kotlin") 23 | println("Ответ: ${res.result}") 24 | 25 | // Доступ к конкретному элементу объекта 26 | if (res.ok) 27 | println("ID сообщения: ${res.result!!.messageId}") 28 | else 29 | println("Получена ошибка: ${res.error}") 30 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/2_send_message_future.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.response.SendMessageResponse 4 | import iris.tg.tgApiFuture 5 | 6 | /** 7 | * @created 30.10.2020 8 | * @author [Ivan Ivanov](https://vk.com/irisism) 9 | */ 10 | fun main() { 11 | 12 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 13 | TestUtil.init() 14 | val properties = TestUtil.properties 15 | val token = properties.getProperty("bot.token") 16 | val toId = properties.getProperty("userTo.id").toLong() 17 | 18 | // Создаём объект TgApiFuture с подготовленными по умолчанию настройками. 19 | // Спецификой данного объекта являются неблокирующие запросы 20 | val api = tgApiFuture(token) 21 | 22 | println("Запускаем работу асинхронных запросов\n") 23 | 24 | val res = api.sendMessage(toId, "💝 Это сообщение отправлено с помощью Kotlin") 25 | println("Первый запрос без задержек") 26 | val res2 = api.sendMessage(toId, "💝 Второе сообщение отправлено с помощью Kotlin") 27 | println("Второй запрос без задержек") 28 | 29 | // Создадим намеренную ошибку 30 | val res3 = api.sendMessage(1, "💝 Третье сообщение отправлено с помощью Kotlin") 31 | println("Третий запрос без задержек\n") 32 | 33 | println("Ждём ответ 1:") 34 | println("message_id=" + res.get()?.result?.messageId) 35 | 36 | ////////////////////////////// 37 | println("\nЖдём ответ 2 и проверим есть там результат или ошибка:") 38 | 39 | println(res2.get()?.let(::testResponse)) // Хороший запрос 40 | 41 | println("\nЖдём ответ 3 и проверим есть там результат или ошибка:") 42 | println(res3.get()?.let(::testResponse)) // Запрос с ошибкой 43 | } 44 | 45 | fun testResponse(response: SendMessageResponse): String { 46 | return if (response.ok) 47 | "Ответ получен: message_id=" + response.result!!.messageId 48 | else 49 | with(response.error!!) { "Возникла ошибка: $description ($errorCode)" } 50 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/3.0_bot_polling.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.longpoll.TgLongPoll 4 | import iris.tg.api.items.CallbackQuery 5 | import iris.tg.api.items.Message 6 | import iris.tg.processors.single.TgEventMessageSingleHandlerAdapter 7 | import iris.tg.processors.single.TgEventMessageSingleHandlerAdapterBasicTypes 8 | import iris.tg.tgApi 9 | import iris.tg.tgApiFuture 10 | import kotlin.system.exitProcess 11 | 12 | /** 13 | * @created 27.09.2020 14 | * @author [Ivan Ivanov](https://vk.com/irisism) 15 | * Пример запуска слушателя событий Телеграм методом long polling 16 | */ 17 | 18 | fun main() { 19 | 20 | 21 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 22 | TestUtil.init() 23 | val props = TestUtil.properties 24 | val token = props.getProperty("bot.token") 25 | 26 | // Создаём объект TgApi с неблокирующими запросами для отправки сообщений 27 | val api = tgApiFuture(token) 28 | 29 | // api.deleteWebhook().get() // Раскомментировать в случае ошибки конфликта работающего webhook'а 30 | 31 | // Определяем обработчик получаемых событий 32 | val simpleMessageHandler = object : TgEventMessageSingleHandlerAdapterBasicTypes() { 33 | 34 | override fun text(message: Message) { 35 | 36 | api.sendMessage(message.chat.id, 37 | message.text?.let { "Получено сообщение: $it" } 38 | ?: message.sticker?.let { "Получен стикер: $it" } 39 | ?: message.video?.let { "Получено видео: $it" } 40 | ?: message.audio?.let { "Получено аудио: $it" } 41 | ?: message.animation?.let { "Получен GIF: $it" } 42 | ?: message.photo?.let { "Получено фото: $it" } 43 | ?: "Получено сообщение: $message" 44 | ) 45 | 46 | val text = message.text 47 | if (text =="пинг") { 48 | println("Команда Пинг получена") 49 | 50 | // Шлём ответ 51 | api.sendMessage(message.chat.id, "ПОНГ") 52 | } 53 | } 54 | 55 | override fun callbackQuery(callback: CallbackQuery) { 56 | println("Получено callback-событие: ${callback.id} data=${callback.data}") 57 | } 58 | } 59 | 60 | // Передаём в параметрах слушателя событий токен и созданный обработчик событий 61 | val listener = TgLongPoll(tgApi(token), simpleMessageHandler) 62 | listener.startPolling() // Можно запустить неблокирующего слушателя 63 | listener.join() // Даст дождаться завершения работы слушателя 64 | 65 | //listener.run() // А можно просто заблокировать дальнейшую работу потока, пока не будет остановлено 66 | 67 | exitProcess(0) 68 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/3.1_bot_polling_queue.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.items.Message 4 | import iris.tg.longpoll.longPollQueued 5 | import iris.tg.processors.single.TgEventMessageSingleHandlerAdapterBasicTypes 6 | import iris.tg.tgApi 7 | 8 | /** 9 | * @created 06.02.2022 10 | * @author [Ivan Ivanov](https://vk.com/irisism) 11 | * Пример запуска слушателя событий Телеграм методом long polling. 12 | * 13 | * В отличие от предыдущего примера, содержащегося в файле 3.0_bot_polling.kt, 14 | * бот не дожидается обработки всех полученных событий, а обращается за новыми. 15 | * 16 | * Полученные события собираются в очередь и ждут, когда их запросит обработчик событий. 17 | */ 18 | fun main() { 19 | 20 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 21 | TestUtil.init() 22 | val props = TestUtil.properties 23 | val token = props.getProperty("bot.token") ?: throw IllegalArgumentException() 24 | 25 | // TestUtil.api.deleteWebhook() // Раскомментировать в случае ошибки конфликта работающего webhook'а 26 | 27 | // Определяем обработчик получаемых событий 28 | val textHandler = object: TgEventMessageSingleHandlerAdapterBasicTypes() { 29 | override fun text(message: Message) { 30 | println("Сообщение от @" + message.from!!.username + ": " + message.text) 31 | } 32 | } 33 | 34 | // 35 | val bot = longPollQueued { 36 | api = tgApi(token) 37 | updateProcessor = processor(textHandler) 38 | } 39 | bot.run() 40 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/4.0_bot_webhook.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.items.Message 4 | import iris.tg.processors.single.TgEventMessageSingleHandlerAdapter 5 | import iris.tg.processors.single.TgEventMessageSingleHandlerAdapterBasicTypes 6 | import iris.tg.tgApi 7 | import iris.tg.webhook.AddressTesterDefault 8 | import iris.tg.webhook.webhookBot 9 | import kotlin.system.exitProcess 10 | 11 | /** 12 | * @created 29.12.2020 13 | * @author [Ivan Ivanov](https://vk.com/irisism) 14 | */ 15 | fun main() { 16 | 17 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 18 | TestUtil.init() 19 | val props = TestUtil.properties 20 | val token = props.getProperty("bot.token") 21 | val webhookUrl = props.getProperty("webhook.url") 22 | val addressTesterIP = props.getProperty("webhook.addressTesterIP") 23 | 24 | val api = tgApi(token) 25 | api.setWebhook(webhookUrl) 26 | 27 | // Уже знакомый нам обработчик событий 28 | val handler = object : TgEventMessageSingleHandlerAdapterBasicTypes() { 29 | 30 | override fun text(message: Message) { 31 | if (message.text == "стоп") { 32 | val r = api.deleteWebhook() 33 | println(r.result ?: r.error) 34 | exitProcess(0) 35 | } 36 | 37 | println("New message: " + message.text) 38 | } 39 | 40 | } 41 | 42 | // Настройка бота 43 | val bot = webhookBot { 44 | addressTester = if (addressTesterIP != null) AddressTesterDefault(addressTesterIP) else null 45 | path = "/telegram" 46 | updateProcessor = toProcessor(handler) 47 | port = 8000 48 | } 49 | bot.run() 50 | } 51 | 52 | -------------------------------------------------------------------------------- /test/iris/tg/examples/4.1_multibot_webhook.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.items.UpdateExt 4 | import iris.tg.processors.TgUpdateProcessor 5 | import iris.tg.tgApi 6 | import iris.tg.webhook.AddressTesterDefault 7 | import iris.tg.webhook.BotSource 8 | import iris.tg.webhook.TgWebhookRequestHandler 9 | import iris.tg.webhook.webhookMultibot 10 | 11 | /** 12 | * @created 05.02.2022 13 | * @author [Ivan Ivanov](https://vk.com/irisism) 14 | */ 15 | fun main() { 16 | 17 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 18 | TestUtil.init() 19 | val props = TestUtil.properties 20 | val bot1Token = props.getProperty("bot.token") 21 | val bot1Id = props.getProperty("bot.id").toLong() 22 | 23 | 24 | val addressTesterIP = props.getProperty("webhook.addressTesterIP") 25 | val webhookBeginUrl = props.getProperty("multibot.webhook.url") ?: throw IllegalArgumentException("Для запуска данного примера необходимо назначить webhookBeginUrl") 26 | val bot2Token = props.getProperty("multibot.bot2.token") ?: throw IllegalArgumentException("Для запуска данного примера необходимо назначить token второго бота") 27 | val bot2Id = props.getProperty("multibot.bot2.id")?.toLong() ?: throw IllegalArgumentException("Для запуска данного примера необходимо назначить id второго бота") 28 | val uri = "/multibot/" 29 | 30 | tgApi(bot1Token).apply { 31 | setWebhook("$webhookBeginUrl$bot1Id") 32 | .apply(::println) 33 | getWebhookInfo().apply(::println) 34 | } 35 | 36 | tgApi(bot2Token).apply { 37 | setWebhook("$webhookBeginUrl$bot2Id") 38 | .apply(::println) 39 | getWebhookInfo().apply(::println) 40 | } 41 | 42 | //////////////////////////// 43 | 44 | val myBotSource = object : BotSource { 45 | 46 | private val matcher = Regex("""$uri(\w+)""") 47 | 48 | override fun getBot(request: TgWebhookRequestHandler.Request): BotSource.BotData? { 49 | val m = matcher.matchEntire(request.requestUri.path) ?: return null 50 | val id = m.groupValues[1].toLong() 51 | if (!(id == bot1Id || id == bot2Id)) { 52 | println("Несанкционированный доступ с ID бота: $id") 53 | return null 54 | } 55 | return BotSource.BotData(id) 56 | } 57 | } 58 | 59 | /////////////////////////// 60 | 61 | val processor = object : TgUpdateProcessor { 62 | override fun processUpdates(updates: List) { 63 | updates.forEach(this::processUpdate) 64 | } 65 | 66 | override fun processUpdate(update: UpdateExt) { 67 | println("Update received by bot with ID: " + update.forBot.id + " text: " + update.update) 68 | } 69 | } 70 | 71 | //////////////////////////// 72 | 73 | val bot = webhookMultibot { 74 | botSource = myBotSource 75 | if (addressTesterIP != null) addressTester = AddressTesterDefault(addressTesterIP) 76 | path = uri 77 | updateProcessor = processor 78 | port = 8000 79 | //tgVsLocalTimeDiff = TestUtil.tgVsLocalTimeDiff() 80 | } 81 | bot.run() 82 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/5_command_handler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.items.Message 4 | import iris.tg.command.CommandMatcher 5 | import iris.tg.longpoll.TgLongPoll 6 | import iris.tg.command.TgCommandHandler 7 | import iris.tg.processors.pack.TgEventMessagePackHandlerAdapterBasicTypes 8 | import iris.tg.processors.pack.TgTextPackHandler 9 | import iris.tg.tgApi 10 | import iris.tg.tgApiFuture 11 | import kotlin.system.exitProcess 12 | 13 | /** 14 | * @created 27.10.2020 15 | * @author [Ivan Ivanov](https://vk.com/irisism) 16 | */ 17 | fun main() { 18 | 19 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 20 | TestUtil.init() 21 | val props = TestUtil.properties 22 | val token = props.getProperty("bot.token") 23 | 24 | // Создаём класс для отправки сообщений 25 | val api = tgApiFuture(token) 26 | 27 | // api.deleteWebhook().get() // Раскомментировать в случае ошибки конфликта работающего webhook'а 28 | 29 | // Определяем обработчик команд 30 | val commandsHandler = TgCommandHandler() 31 | 32 | commandsHandler.text("кинг") { 33 | api.sendMessage(it.chat.id, "КОНГ!") 34 | } 35 | 36 | commandsHandler.text("мой ид") { 37 | val from = it.from!! 38 | api.sendMessage(it.chat.id, "ID ${from.firstName} ${from.lastName} (@${from.username}) равен: ${it.from!!.id}") 39 | } 40 | 41 | commandsHandler.regex("рандом (\\d+) (\\d+)") { message, params -> 42 | 43 | var first = params[1].toInt() 44 | var second = params[2].toInt() 45 | if (second < first) 46 | first = second.also { second = first } 47 | 48 | api.sendMessage(message.chat.id, "🎲 Случайное значение в диапазоне [$first..$second] выпало на ${(first..second).random()}") 49 | } 50 | 51 | // Определяем произвольно анализирующий текст команды обработчик команды 52 | commandsHandler += object : CommandMatcher { 53 | override fun testAndExecute(command: String, message: Message): Boolean { 54 | if (!(command.startsWith("пинг") || command.endsWith("пыньк"))) return false 55 | api.sendMessage(message.chat.id, "ПОНГ!") 56 | return true 57 | } 58 | } 59 | 60 | // Передаём в параметрах слушателя событий токен и созданный обработчик команд 61 | val listener = TgLongPoll(tgApi(token), TextHandlerAdapter(commandsHandler)) 62 | listener.startPolling() // Можно запустить неблокирующего слушателя 63 | listener.join() // Даст дождаться завершения работы слушателя 64 | //listener.run() // Можно заблокировать дальнейшую работу потока, пока не будет остановлено 65 | 66 | exitProcess(0) 67 | } 68 | 69 | class TextHandlerAdapter(private val textHandler: TgTextPackHandler) : TgEventMessagePackHandlerAdapterBasicTypes() { 70 | override fun texts(messages: List) { 71 | textHandler.texts(messages as List) 72 | } 73 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/7_command_trigger_style.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.command.TgCommandHandler 4 | import iris.tg.longpoll.TgLongPoll 5 | import iris.tg.tgApi 6 | import iris.tg.tgApiFuture 7 | import iris.tg.trigger.TriggerHandlerSingleBasicTypes 8 | import kotlin.system.exitProcess 9 | 10 | /** 11 | * @created 01.11.2020 12 | * @author [Ivan Ivanov](https://vk.com/irisism) 13 | */ 14 | fun main() { 15 | 16 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 17 | TestUtil.init() 18 | val props = TestUtil.properties 19 | val token = props.getProperty("bot.token") 20 | 21 | // Создаём класс для отправки сообщений 22 | val api = tgApiFuture(token) 23 | // api.deleteWebhook().get() // Раскомментировать в случае ошибки конфликта работающего webhook'а 24 | 25 | // Определяем обработчик триггеров 26 | val triggerHandler = TriggerHandlerSingleBasicTypes() 27 | 28 | // можно настраивать лямбдами 29 | triggerHandler.onMessage { 30 | println("Получено сообщение от ${it.chat.id}: ${it.text}") 31 | } 32 | 33 | triggerHandler.onMessage { 34 | println("Сообщение исправлено ${it.messageId}: ${it.text}") 35 | } 36 | 37 | // можно настраивать классами триггеров 38 | triggerHandler.onMessage ( 39 | TgCommandHandler { 40 | text("пинг") { 41 | api.sendMessage(it.chat.id, "ПОНГ!") 42 | } 43 | 44 | text("мой ид") { 45 | api.sendMessage(it.chat.id, "Ваш ID равен: ${it.from?.id}") 46 | } 47 | 48 | regex("""рандом (\d+) (\d+)""") { mess, params -> 49 | 50 | var first = params[1].toInt() 51 | var second = params[2].toInt() 52 | if (second < first) 53 | first = second.also { second = first } 54 | 55 | api.sendMessage(mess.chat.id, "🎲 Случайное значение в диапазоне [$first..$second] выпало на ${(first..second).random()}") 56 | } 57 | } 58 | ) 59 | 60 | // Передаём в параметрах слушателя событий токен и созданный обработчик команд 61 | val listener = TgLongPoll(tgApi(token), triggerHandler) 62 | listener.startPolling() // Можно запустить неблокирующего слушателя 63 | listener.join() // Даст дождаться завершения работы слушателя 64 | //listener.run() // Можно заблокировать дальнейшую работу потока, пока не будет остановлено 65 | 66 | exitProcess(0) 67 | } 68 | 69 | fun tt() { 70 | 71 | TestUtil.init() 72 | val props = TestUtil.properties 73 | val token = props.getProperty("bot.token") 74 | 75 | 76 | 77 | val triggerHandler = TriggerHandlerSingleBasicTypes { 78 | onMessage { 79 | println("Получено сообщение от ${it.chat.id}: ${it.text}") 80 | } 81 | 82 | onMessageEdit { 83 | println("Сообщение исправлено ${it.messageId}: ${it.text}") 84 | } 85 | } 86 | 87 | // Передаём в параметрах слушателя событий токен и созданный обработчик команд 88 | val bot = TgLongPoll(tgApi(token), triggerHandler) 89 | bot.run() 90 | 91 | 92 | 93 | exitProcess(0) 94 | 95 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/8_command_trigger_style_dsl.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.command.TgCommandHandler 4 | import iris.tg.longpoll.TgLongPoll 5 | import iris.tg.tgApi 6 | import iris.tg.tgApiFuture 7 | import iris.tg.trigger.TriggerHandlerSingleBasicTypes 8 | import kotlin.system.exitProcess 9 | 10 | /** 11 | * @created 01.11.2020 12 | * @author [Ivan Ivanov](https://vk.com/irisism) 13 | */ 14 | fun main() { 15 | 16 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 17 | TestUtil.init() 18 | val props = TestUtil.properties 19 | val token = props.getProperty("bot.token") 20 | 21 | // Создаём класс для отправки сообщений 22 | val api = tgApiFuture(token) 23 | // api.deleteWebhook().get() // Раскомментировать в случае ошибки конфликта работающего webhook'а 24 | 25 | // Определяем обработчик триггеров 26 | val triggerHandler = TriggerHandlerSingleBasicTypes { 27 | 28 | onMessage { 29 | println("Получено сообщение от ${it.chat.id}: ${it.text}") 30 | } 31 | 32 | onMessageEdit { 33 | println("Сообщение исправлено ${it.messageId}: ${it.text}") 34 | } 35 | 36 | onMessage( 37 | TgCommandHandler { 38 | text("пинг") { 39 | api.sendMessage(it.chat.id, "ПОНГ!") 40 | } 41 | text("мой ид") { 42 | api.sendMessage(it.chat.id, "Ваш ID равен: ${it.from!!.id}") 43 | } 44 | regex("""рандом (\d+) (\d+)""") { message, params -> 45 | 46 | var first = params[1].toInt() 47 | var second = params[2].toInt() 48 | if (second < first) 49 | first = second.also { second = first } 50 | 51 | api.sendMessage(message.chat.id, "🎲 Случайное значение в диапазоне [$first..$second] выпало на ${(first..second).random()}") 52 | } 53 | } 54 | ) 55 | } 56 | 57 | // Передаём в параметрах слушателя событий токен и созданный обработчик команд 58 | val listener = TgLongPoll(tgApi(token), triggerHandler) 59 | listener.startPolling() // Можно запустить неблокирующего слушателя 60 | listener.join() // Даст дождаться завершения работы слушателя 61 | //listener.run() // Можно заблокировать дальнейшую работу потока, пока не будет остановлено 62 | 63 | exitProcess(0) 64 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/9_callback_handler.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.keyboard.callback.CallbackMonster 4 | import iris.tg.longpoll.TgLongPoll 5 | import iris.tg.tgApi 6 | import iris.tg.tgApiFuture 7 | 8 | /** 9 | * @created 07.02.2022 10 | * @author [Ivan Ivanov](https://vk.com/irisism) 11 | */ 12 | fun main() { 13 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 14 | TestUtil.init() 15 | val props = TestUtil.properties 16 | val token = props.getProperty("bot.token") 17 | val toId = props.getProperty("userTo.id").toLong() 18 | 19 | // Создаём объект TgApi с неблокирующими запросами для отправки сообщений 20 | val api = tgApiFuture(token) 21 | 22 | val callbackHandler = CallbackMonster(api) 23 | 24 | val handlerKeyboard = callbackHandler.keyboard { 25 | row { 26 | button("Я реагирую!") { 27 | api.sendMessage(it.message!!.chat.id, "Меня заставили отреагираовать: @${it.from.username}") 28 | } 29 | 30 | button("Я реагирую 2") { 31 | api.sendMessage(it.message!!.chat.id, "Меня заставили отреагираовать на второе: @${it.from.username}") 32 | } 33 | } 34 | } 35 | 36 | val singleButton = callbackHandler.singleButtonKeyboard("Я реагирую!") { 37 | api.sendMessage(it.message!!.chat.id, "Меня заставили отреагираовать: @${it.from.username}") 38 | } 39 | 40 | api.sendMessage(toId, "Кнопка с реакцией", reply_markup = api.json(handlerKeyboard)) 41 | 42 | val listener = TgLongPoll(tgApi(token), callbackHandler) 43 | listener.startPolling() 44 | 45 | listener.join() 46 | } -------------------------------------------------------------------------------- /test/iris/tg/examples/Util.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.examples 2 | 3 | import iris.tg.api.TgApiObjFuture 4 | import iris.tg.api.TgApiObject 5 | import iris.tg.tgApi 6 | import iris.tg.tgApiFuture 7 | import java.io.File 8 | import java.util.* 9 | import java.util.logging.LogManager 10 | 11 | /** 12 | * @created 28.09.2020 13 | * @author [Ivan Ivanov](https://vk.com/irisism) 14 | */ 15 | 16 | 17 | 18 | 19 | 20 | object TestUtil { 21 | 22 | const val confPath = "excl/cfg.properties" 23 | lateinit var api: TgApiObject 24 | lateinit var apiFuture: TgApiObjFuture 25 | 26 | val properties = run { 27 | val props = Properties() 28 | File(confPath).reader().use { props.load(it) } 29 | props 30 | } 31 | 32 | fun init() { 33 | TimeZone.setDefault(TimeZone.getTimeZone("Europe/Moscow")) 34 | 35 | val token = properties.getProperty("bot.token") 36 | api = tgApi(token) 37 | apiFuture = tgApiFuture(token) 38 | //initLogger() 39 | } 40 | 41 | private fun initLogger() { 42 | val ist = this.javaClass.getResourceAsStream("logger.properties").use { 43 | LogManager.getLogManager().readConfiguration(it) 44 | } 45 | } 46 | 47 | fun tgVsLocalTimeDiff(): Long { 48 | val toId = properties.getProperty("checkTimeDiffToId")?.toLong() ?: throw IllegalArgumentException("\"checkTimeDiffToId\" property is not defined") 49 | val startTime = System.currentTimeMillis() 50 | val firstText = "Current local server time: " + Date(startTime) 51 | val response = api.sendMessage(toId, firstText, parse_mode = "HTML") 52 | val responseTime = System.currentTimeMillis() 53 | val result = response.result ?: throw IllegalArgumentException("Error: $response") 54 | val tgVsLocal = (result.date*1000 - responseTime) 55 | api.editMessageText(toId, result.messageId, firstText 56 | + "\nResponse time: " + (responseTime - startTime) + " ms" 57 | + "\nTG vs Local server time diff: " + tgVsLocal + " ms" 58 | , parse_mode = "HTML" 59 | ) 60 | return tgVsLocal 61 | } 62 | 63 | 64 | } -------------------------------------------------------------------------------- /test/iris/tg/test/api/sendMediaGroup.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.test.api 2 | 3 | import iris.connection.Connection 4 | import iris.tg.examples.TestUtil 5 | import iris.tg.pojo.items.InputMediaPhoto_Pojo 6 | import iris.tg.tgApi 7 | import java.io.File 8 | 9 | /** 10 | * @created 10.02.2022 11 | * @author [Ivan Ivanov](https://t.me/irisism) 12 | */ 13 | fun main() { 14 | 15 | // Инициализируем тестовые данные. В рабочих проектах этого делать не нужно 16 | TestUtil.init() 17 | val properties = TestUtil.properties 18 | val token = properties.getProperty("bot.token") 19 | val toId = properties.getProperty("userTo.id").toLong() 20 | 21 | 22 | // Создаём объект TgApi с подготовленными по умолчанию настройками 23 | val api = tgApi(token) 24 | 25 | // Собираем медиа-группу через список 26 | val res = api.sendMediaGroup(toId, 27 | listOf( 28 | InputMediaPhoto_Pojo(data = Connection.BinaryDataFile(File("D:/test.png")), caption = "Это фото 1"), 29 | InputMediaPhoto_Pojo(data = Connection.BinaryDataFile(File("D:/test.png")), caption = "Это фото 2") 30 | ) 31 | ) 32 | println("Ответ: $res") 33 | 34 | // Собираем медиа-группу через лямбду-билдер 35 | val res2 = api.sendMediaGroup(toId) { 36 | photo(data = binary("D:/Downloads/photo_2022-02-04_18-19-03.jpg"), caption = "Да. Оно работает!") 37 | photo(data = binary("D:/Downloads/6EFyti31Ix4.jpg"), caption = "БН-Лайв") 38 | video(data = binary("D:/Downloads/IMG_6625.MOV"), caption = "Какой-то Леонид Волков") 39 | } 40 | 41 | println(res2) 42 | 43 | } -------------------------------------------------------------------------------- /test/iris/tg/test/simple_jsonifier/input_media.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.test 2 | 3 | import iris.tg.api.JsonifierSimple 4 | import iris.connection.Connection 5 | import iris.tg.pojo.items.InputMediaDocument_Pojo 6 | import iris.tg.pojo.items.InputMediaPhoto_Pojo 7 | import java.io.File 8 | 9 | /** 10 | * @created 07.02.2022 11 | * @author [Ivan Ivanov](https://vk.com/irisism) 12 | */ 13 | fun main() { 14 | val simpleJsonifier = JsonifierSimple() 15 | 16 | val input = listOf( 17 | InputMediaDocument_Pojo(data = Connection.BinaryDataFile(File("D:/test.png")), caption = "Это документик"), 18 | InputMediaPhoto_Pojo(data = Connection.BinaryDataFile(File("D:/test.png")), caption = "Это фото") 19 | ) 20 | 21 | val res = simpleJsonifier.inputMedia(input) 22 | println(res) 23 | 24 | } 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/iris/tg/test/simple_jsonifier/keyboard.kt: -------------------------------------------------------------------------------- 1 | package iris.tg.test 2 | 3 | import iris.tg.api.JsonifierSimple 4 | import iris.tg.keyboard.inlineKeyboardMarkup 5 | import iris.tg.pojo.items.InlineKeyboardMarkup_Pojo 6 | import iris.tg.pojo.items.ReplyKeyboardRemove_Pojo 7 | 8 | /** 9 | * @created 07.02.2022 10 | * @author [Ivan Ivanov](https://vk.com/irisism) 11 | */ 12 | 13 | val simpleJsonifier = JsonifierSimple() 14 | 15 | fun main() { 16 | 17 | /*run { 18 | val arr = arrayOf("event1", "event2", "callback", "message") 19 | simpleJsonifier.array2JsonString(arr).apply(::println) 20 | } 21 | 22 | run { 23 | val arr = arrayOf() 24 | simpleJsonifier.array2JsonString(arr).apply(::println) 25 | }*/ 26 | 27 | /*run { 28 | val arr = listOf( 29 | MessageEntity_Pojo("type1", 3, 10, """https://url.ru/tada""", null, "RU"), 30 | MessageEntity_Pojo("type2", 23, 14, null, null, "US"), 31 | ) 32 | simpleJsonifier.entities(arr).apply(::println) 33 | } 34 | 35 | run { 36 | simpleJsonifier.entities(listOf()).apply(::println) 37 | }*/ 38 | 39 | /*run { 40 | val kb = inlineKeyboardMarkup { 41 | 42 | // Хочешь аргументами в функцию 43 | row( 44 | button("Wow 11"), 45 | button("Wow 12"), 46 | ) 47 | 48 | // Хочешь DSL конструкторами накидывай 49 | row { 50 | button("Wow 21") 51 | button("Wow 22") 52 | } 53 | 54 | // Лучше, конечно, в функцию, ибо нет накладок с промежуточным билдером 55 | } 56 | 57 | simpleJsonifier.replyMarkup(kb).apply(::println) 58 | } 59 | 60 | run { 61 | val arr = InlineKeyboardMarkup_Pojo(listOf()) 62 | simpleJsonifier.replyMarkup(arr).apply(::println) 63 | }*/ 64 | 65 | run { 66 | val arr = ReplyKeyboardRemove_Pojo(true) 67 | simpleJsonifier.replyMarkup(arr) 68 | .apply(::println) 69 | } 70 | 71 | } 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /test/ttt.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * @created 04.02.2022 3 | * @author [Ivan Ivanov](https://vk.com/irisism) 4 | */ 5 | fun main() { 6 | println("Warmup") 7 | System.gc() 8 | testCopy(20_000_000) 9 | System.gc() 10 | testRemove(20_000_000) 11 | System.gc() 12 | testIter(20_000_000) 13 | println("Goo") 14 | System.gc() 15 | testCopy(20_000_000) 16 | System.gc() 17 | testRemove(20_000_000) 18 | System.gc() 19 | testIter(20_000_000) 20 | } 21 | 22 | fun testCopy(amount: Int) { 23 | val queue = ArrayDeque() 24 | (1..amount).toCollection(queue) 25 | 26 | val t = System.currentTimeMillis() 27 | val l = queue.toList() 28 | queue.clear() 29 | println(System.currentTimeMillis() - t) 30 | } 31 | 32 | fun testIter(amount: Int) { 33 | val limit = amount 34 | val queue = ArrayDeque() 35 | (1..amount).toCollection(queue) 36 | val l = ArrayList(limit) 37 | 38 | val t = System.currentTimeMillis() 39 | 40 | val iter = queue.iterator() 41 | for (i in 1..limit) { 42 | l += iter.next() 43 | iter.remove() 44 | } 45 | println(System.currentTimeMillis() - t) 46 | } 47 | 48 | fun testRemove(amount: Int) { 49 | val limit = amount 50 | val queue = ArrayDeque() 51 | (1..amount).toCollection(queue) 52 | val l = ArrayList(limit) 53 | 54 | val t = System.currentTimeMillis() 55 | 56 | for (i in 1..limit) { 57 | l += queue.removeFirst() 58 | } 59 | 60 | println(System.currentTimeMillis() - t) 61 | } --------------------------------------------------------------------------------