mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2026-01-04 04:19:23 +00:00
Compare commits
17 Commits
0.38.15
...
ad50f41d1e
| Author | SHA1 | Date | |
|---|---|---|---|
| ad50f41d1e | |||
| 8c9cd9df67 | |||
| 8e7f7a03c8 | |||
| 484e09374d | |||
|
|
619c82bb32 | ||
| 33fb75a5eb | |||
| a52f31f4c9 | |||
| 682f696866 | |||
| 87fff2e5d0 | |||
| 92b4ba2ff0 | |||
| 9014cdbc99 | |||
| 37317a1055 | |||
| 60c21002e1 | |||
| 78a7a3546a | |||
| 4799617ced | |||
| c70484076d | |||
| 0c92e6eeb4 |
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,5 +1,23 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 0.38.18
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* Add support of test servers (fix of [#577](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/577))
|
||||||
|
* `BehaviourBuilder`:
|
||||||
|
* Fixes in extension `BehaviourContext#doInSubContextWithUpdatesFilter` (thanks to [xzima](https://github.com/xzima))
|
||||||
|
|
||||||
|
## 0.38.17
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* Add `BotCommandScopeChat` as new `BotCommandScope` (fix of [#574](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/574))
|
||||||
|
* `BotCommandScope` companion got several properties and functions for more useful scope creation
|
||||||
|
|
||||||
|
## 0.38.16
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* `TelegramAPIUrlsKeeper` now have two new things: properties `webAppDataSecretKey` and fun `checkWebAppLink`
|
||||||
|
|
||||||
## 0.38.15
|
## 0.38.15
|
||||||
|
|
||||||
* `Common`:
|
* `Common`:
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ javax_activation_version=1.1.1
|
|||||||
dokka_version=1.6.10
|
dokka_version=1.6.10
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.38.15
|
library_version=0.38.18
|
||||||
|
|
||||||
github_release_plugin_version=2.3.7
|
github_release_plugin_version=2.3.7
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ data class BotBuilder internal constructor(
|
|||||||
fun buildBot(
|
fun buildBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
testServer: Boolean = false,
|
||||||
block: BotBuilder.() -> Unit
|
block: BotBuilder.() -> Unit
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||||
BotBuilder().apply(block).createHttpClient()
|
BotBuilder().apply(block).createHttpClient()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -66,17 +66,19 @@ inline fun telegramBot(
|
|||||||
inline fun telegramBot(
|
inline fun telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
testServer: Boolean = false,
|
||||||
client: HttpClient = HttpClient()
|
client: HttpClient = HttpClient()
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client)
|
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, testServer, apiUrl), client)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <T: HttpClientEngineConfig> telegramBot(
|
inline fun <T: HttpClientEngineConfig> telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
clientFactory: HttpClientEngineFactory<T>,
|
clientFactory: HttpClientEngineFactory<T>,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
testServer: Boolean = false,
|
||||||
noinline clientConfig: HttpClientConfig<T>.() -> Unit = {}
|
noinline clientConfig: HttpClientConfig<T>.() -> Unit = {}
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||||
clientFactory,
|
clientFactory,
|
||||||
clientConfig
|
clientConfig
|
||||||
)
|
)
|
||||||
@@ -90,9 +92,10 @@ inline fun telegramBot(
|
|||||||
token: String,
|
token: String,
|
||||||
clientEngine: HttpClientEngine,
|
clientEngine: HttpClientEngine,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
testServer: Boolean = false,
|
||||||
noinline clientConfig: HttpClientConfig<*>.() -> Unit = {}
|
noinline clientConfig: HttpClientConfig<*>.() -> Unit = {}
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||||
clientEngine,
|
clientEngine,
|
||||||
clientConfig
|
clientConfig
|
||||||
)
|
)
|
||||||
@@ -105,8 +108,9 @@ inline fun telegramBot(
|
|||||||
inline fun telegramBot(
|
inline fun telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
testServer: Boolean = false,
|
||||||
noinline clientConfig: HttpClientConfig<*>.() -> Unit
|
noinline clientConfig: HttpClientConfig<*>.() -> Unit
|
||||||
) = telegramBot(
|
) = telegramBot(
|
||||||
TelegramAPIUrlsKeeper(token, apiUrl),
|
TelegramAPIUrlsKeeper(token, testServer, apiUrl),
|
||||||
clientConfig
|
clientConfig
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -38,10 +38,12 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
|
|||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
|
testServer: Boolean = false,
|
||||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
): TelegramBot = telegramBot(
|
): TelegramBot = telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
|
testServer,
|
||||||
builder
|
builder
|
||||||
).apply {
|
).apply {
|
||||||
buildBehaviourWithFSMAndStartLongPolling(
|
buildBehaviourWithFSMAndStartLongPolling(
|
||||||
@@ -73,11 +75,13 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
|
|||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
|
||||||
|
testServer: Boolean = false,
|
||||||
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
|
||||||
): Pair<TelegramBot, Job> {
|
): Pair<TelegramBot, Job> {
|
||||||
return telegramBot(
|
return telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
|
testServer,
|
||||||
builder
|
builder
|
||||||
).let {
|
).let {
|
||||||
it to it.buildBehaviourWithFSMAndStartLongPolling (
|
it to it.buildBehaviourWithFSMAndStartLongPolling (
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class DefaultBehaviourContext(
|
|||||||
onBufferOverflow: BufferOverflow,
|
onBufferOverflow: BufferOverflow,
|
||||||
upstreamUpdatesFlow: Flow<Update>?,
|
upstreamUpdatesFlow: Flow<Update>?,
|
||||||
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
|
||||||
): BehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter)
|
): DefaultBehaviourContext = DefaultBehaviourContext(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BehaviourContext(
|
fun BehaviourContext(
|
||||||
@@ -116,19 +116,20 @@ suspend fun <T, BC : BehaviourContext> BC.doInSubContextWithUpdatesFilter(
|
|||||||
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
updatesUpstreamFlow: Flow<Update> = allUpdatesFlow,
|
||||||
scope: CoroutineScope = LinkedSupervisorScope(),
|
scope: CoroutineScope = LinkedSupervisorScope(),
|
||||||
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
|
behaviourContextReceiver: CustomBehaviourContextReceiver<BC, T>
|
||||||
): T = copy(
|
): T {
|
||||||
scope = scope,
|
val newContext = copy(
|
||||||
updatesFilter = updatesFilter ?.let { _ ->
|
scope = scope,
|
||||||
{
|
updatesFilter = updatesFilter ?.let { _ ->
|
||||||
(this as? BC) ?.run {
|
{
|
||||||
updatesFilter(it)
|
(this as? BC) ?.run {
|
||||||
} ?: true
|
updatesFilter(it)
|
||||||
}
|
} ?: true
|
||||||
},
|
}
|
||||||
upstreamUpdatesFlow = updatesUpstreamFlow
|
},
|
||||||
).run {
|
upstreamUpdatesFlow = updatesUpstreamFlow
|
||||||
withContext(coroutineContext) {
|
) as BC
|
||||||
behaviourContextReceiver().also { if (stopOnCompletion) stop() }
|
return withContext(currentCoroutineContext()) {
|
||||||
|
newContext.behaviourContextReceiver().also { if (stopOnCompletion) newContext.stop() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ suspend fun telegramBotWithBehaviour(
|
|||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
|
testServer: Boolean = false,
|
||||||
block: BehaviourContextReceiver<Unit>
|
block: BehaviourContextReceiver<Unit>
|
||||||
): TelegramBot = telegramBot(
|
): TelegramBot = telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
|
testServer,
|
||||||
builder
|
builder
|
||||||
).apply {
|
).apply {
|
||||||
buildBehaviour(
|
buildBehaviour(
|
||||||
@@ -63,11 +65,13 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
|
|||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
|
testServer: Boolean = false,
|
||||||
block: BehaviourContextReceiver<Unit>
|
block: BehaviourContextReceiver<Unit>
|
||||||
): Pair<TelegramBot, Job> {
|
): Pair<TelegramBot, Job> {
|
||||||
return telegramBot(
|
return telegramBot(
|
||||||
token,
|
token,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
|
testServer,
|
||||||
builder
|
builder
|
||||||
).let {
|
).let {
|
||||||
it to it.buildBehaviourWithLongPolling(
|
it to it.buildBehaviourWithLongPolling(
|
||||||
|
|||||||
@@ -125,5 +125,6 @@ inline fun telegramBot(
|
|||||||
inline fun telegramBot(
|
inline fun telegramBot(
|
||||||
token: String,
|
token: String,
|
||||||
apiUrl: String = telegramBotAPIDefaultUrl,
|
apiUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
testServer: Boolean = false,
|
||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, testServer, apiUrl), builder)
|
||||||
|
|||||||
@@ -22,11 +22,14 @@ private class SurrogateBotCommandScope(
|
|||||||
BotCommandScopeAllGroupChats.type -> BotCommandScopeAllGroupChats
|
BotCommandScopeAllGroupChats.type -> BotCommandScopeAllGroupChats
|
||||||
BotCommandScopeAllChatAdministrators.type -> BotCommandScopeAllChatAdministrators
|
BotCommandScopeAllChatAdministrators.type -> BotCommandScopeAllChatAdministrators
|
||||||
BotCommandScopeChatAdministrators.type -> BotCommandScopeChatAdministrators(
|
BotCommandScopeChatAdministrators.type -> BotCommandScopeChatAdministrators(
|
||||||
chatId ?: error("chat_administrators type must have $chatIdField field, but have no")
|
chatId ?: error("${BotCommandScopeChatAdministrators.type} type must have $chatIdField field, but have no")
|
||||||
)
|
)
|
||||||
BotCommandScopeChatMember.type -> BotCommandScopeChatMember(
|
BotCommandScopeChatMember.type -> BotCommandScopeChatMember(
|
||||||
chatId ?: error("chat_administrators type must have $chatIdField field, but have no"),
|
chatId ?: error("${BotCommandScopeChatMember.type} type must have $chatIdField field, but have no"),
|
||||||
userId ?: error("chat_administrators type must have $userIdField field, but have no")
|
userId ?: error("${BotCommandScopeChatMember.type} type must have $userIdField field, but have no")
|
||||||
|
)
|
||||||
|
BotCommandScopeChat.type -> BotCommandScopeChat(
|
||||||
|
chatId ?: error("${BotCommandScopeChat.type} type must have $chatIdField field, but have no")
|
||||||
)
|
)
|
||||||
else -> UnknownBotCommandScope(type)
|
else -> UnknownBotCommandScope(type)
|
||||||
}
|
}
|
||||||
@@ -40,6 +43,7 @@ private class SurrogateBotCommandScope(
|
|||||||
BotCommandScopeAllChatAdministrators -> SurrogateBotCommandScope(scope.type)
|
BotCommandScopeAllChatAdministrators -> SurrogateBotCommandScope(scope.type)
|
||||||
is BotCommandScopeChatAdministrators -> SurrogateBotCommandScope(scope.type, scope.chatId)
|
is BotCommandScopeChatAdministrators -> SurrogateBotCommandScope(scope.type, scope.chatId)
|
||||||
is BotCommandScopeChatMember -> SurrogateBotCommandScope(scope.type, scope.chatId, scope.userId)
|
is BotCommandScopeChatMember -> SurrogateBotCommandScope(scope.type, scope.chatId, scope.userId)
|
||||||
|
is BotCommandScopeChat -> SurrogateBotCommandScope(scope.type, scope.chatId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,6 +51,16 @@ private class SurrogateBotCommandScope(
|
|||||||
@Serializable(BotCommandScopeSerializer::class)
|
@Serializable(BotCommandScopeSerializer::class)
|
||||||
sealed interface BotCommandScope {
|
sealed interface BotCommandScope {
|
||||||
val type: String
|
val type: String
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val Default = BotCommandScopeDefault
|
||||||
|
val AllPrivateChats = BotCommandScopeAllPrivateChats
|
||||||
|
val AllGroupChats = BotCommandScopeAllGroupChats
|
||||||
|
val AllChatAdministrators = BotCommandScopeAllChatAdministrators
|
||||||
|
fun ChatAdministrators(chatId: ChatIdentifier) = BotCommandScopeChatAdministrators(chatId)
|
||||||
|
fun Chat(chatId: ChatIdentifier) = BotCommandScopeChat(chatId)
|
||||||
|
fun ChatMember(chatId: ChatIdentifier, userId: UserId) = BotCommandScopeChatMember(chatId, userId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -94,6 +108,17 @@ data class BotCommandScopeChatAdministrators(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BotCommandScopeChat(
|
||||||
|
override val chatId: ChatIdentifier
|
||||||
|
) : ChatBotCommandScope {
|
||||||
|
@Required
|
||||||
|
override val type: String = BotCommandScopeChat.type
|
||||||
|
companion object {
|
||||||
|
const val type = "chat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class BotCommandScopeChatMember(
|
data class BotCommandScopeChatMember(
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package dev.inmo.tgbotapi.utils
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.crypto.SourceBytes
|
||||||
|
import dev.inmo.micro_utils.crypto.SourceString
|
||||||
|
|
||||||
|
internal expect fun SourceString.hmacSha256(key: String): String
|
||||||
|
private val HEX_ARRAY = "0123456789abcdef".toCharArray()
|
||||||
|
|
||||||
|
internal fun SourceBytes.hex(): String {
|
||||||
|
val hexChars = CharArray(size * 2)
|
||||||
|
for (j in indices) {
|
||||||
|
val v: Int = this[j].toInt() and 0xFF
|
||||||
|
hexChars[j * 2] = HEX_ARRAY[v ushr 4]
|
||||||
|
hexChars[j * 2 + 1] = HEX_ARRAY[v and 0x0F]
|
||||||
|
}
|
||||||
|
return hexChars.concatToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun SourceString.hex(): String = encodeToByteArray().hex()
|
||||||
@@ -16,16 +16,33 @@ private inline val String.withoutLastSlash: String
|
|||||||
|
|
||||||
class TelegramAPIUrlsKeeper(
|
class TelegramAPIUrlsKeeper(
|
||||||
token: String,
|
token: String,
|
||||||
hostUrl: String = telegramBotAPIDefaultUrl
|
hostUrl: String = telegramBotAPIDefaultUrl,
|
||||||
|
urlsSuffixes: String = ""
|
||||||
) {
|
) {
|
||||||
|
val webAppDataSecretKey by lazy {
|
||||||
|
token.hmacSha256("WebAppData")
|
||||||
|
}
|
||||||
|
|
||||||
val commonAPIUrl: String
|
val commonAPIUrl: String
|
||||||
val fileBaseUrl: String
|
val fileBaseUrl: String
|
||||||
|
|
||||||
|
constructor(token: String, testServer: Boolean, hostUrl: String = telegramBotAPIDefaultUrl) : this(
|
||||||
|
token,
|
||||||
|
hostUrl,
|
||||||
|
"/test".takeIf { testServer } ?: ""
|
||||||
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val correctedHost = hostUrl.withoutLastSlash
|
val correctedHost = hostUrl.withoutLastSlash
|
||||||
commonAPIUrl = "$correctedHost/bot$token"
|
commonAPIUrl = "$correctedHost/bot$token$urlsSuffixes"
|
||||||
fileBaseUrl = "$correctedHost/file/bot$token"
|
fileBaseUrl = "$correctedHost/file/bot$token$urlsSuffixes"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
|
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param rawData Data from [dev.inmo.tgbotapi.webapps.WebApp.initData]
|
||||||
|
* @param hash Data from [dev.inmo.tgbotapi.webapps.WebApp.initDataUnsafe] from the field [dev.inmo.tgbotapi.webapps.WebAppInitData.hash]
|
||||||
|
*/
|
||||||
|
fun checkWebAppLink(rawData: String, hash: String) = rawData.hmacSha256(webAppDataSecretKey).hex() == hash
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package dev.inmo.tgbotapi.utils
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.crypto.CryptoJS
|
||||||
|
import dev.inmo.micro_utils.crypto.SourceString
|
||||||
|
|
||||||
|
actual fun SourceString.hmacSha256(key: String) = CryptoJS.asDynamic().HmacSHA256(this, key).toString().unsafeCast<String>()
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package dev.inmo.tgbotapi.utils
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.crypto.SourceString
|
||||||
|
import javax.crypto.Mac
|
||||||
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
|
actual fun SourceString.hmacSha256(key: String): String {
|
||||||
|
val mac = Mac.getInstance("HmacSHA256")
|
||||||
|
|
||||||
|
val secretKey = SecretKeySpec(key.toByteArray(), "HmacSHA256")
|
||||||
|
mac.init(secretKey)
|
||||||
|
|
||||||
|
return mac.doFinal(toByteArray()).hex()
|
||||||
|
}
|
||||||
@@ -27,6 +27,13 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
jvm {
|
||||||
|
compilations.main {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
js(IR) {
|
js(IR) {
|
||||||
browser()
|
browser()
|
||||||
nodejs()
|
nodejs()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.webapps
|
package dev.inmo.tgbotapi.webapps
|
||||||
|
|
||||||
import dev.inmo.micro_utils.crypto.CryptoJS
|
import dev.inmo.micro_utils.crypto.CryptoJS
|
||||||
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
|
|
||||||
external class WebApp {
|
external class WebApp {
|
||||||
val initData: String
|
val initData: String
|
||||||
@@ -76,6 +77,7 @@ fun WebApp.onMainButtonClicked(eventHandler: EventHandler) = onEvent(EventType.M
|
|||||||
*/
|
*/
|
||||||
fun WebApp.onViewportChanged(eventHandler: ViewportChangedEventHandler) = onEvent(EventType.ViewportChanged, eventHandler)
|
fun WebApp.onViewportChanged(eventHandler: ViewportChangedEventHandler) = onEvent(EventType.ViewportChanged, eventHandler)
|
||||||
|
|
||||||
fun WebApp.isInitDataSafe(botToken: String) = CryptoJS.hex(
|
fun WebApp.isInitDataSafe(botToken: String) = TelegramAPIUrlsKeeper(botToken).checkWebAppLink(
|
||||||
CryptoJS.HmacSHA256(botToken, "WebAppData")
|
initData,
|
||||||
) == initDataUnsafe.hash
|
initDataUnsafe.hash
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user