From 0231d26b20488d324012087891ea0ef7cb44c06f Mon Sep 17 00:00:00 2001 From: madhead Date: Sat, 29 Oct 2022 22:31:23 +0200 Subject: [PATCH 1/6] Container for provider tokens --- settings.gradle.kts | 1 + shop/provider/README.adoc | 5 +++++ shop/provider/build.gradle.kts | 3 +++ .../jprof/telegram/bot/shop/provider/ChatProviderTokens.kt | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 shop/provider/README.adoc create mode 100644 shop/provider/build.gradle.kts create mode 100644 shop/provider/src/main/kotlin/by/jprof/telegram/bot/shop/provider/ChatProviderTokens.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index f11ae81b..9cd99d0b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -43,4 +43,5 @@ include(":english:urban-word-of-the-day") include(":english:urban-word-of-the-day:dynamodb") include(":english:urban-word-of-the-day-formatter") include(":english:urban-dictionary-daily") +include(":shop:provider") include(":launchers:lambda") diff --git a/shop/provider/README.adoc b/shop/provider/README.adoc new file mode 100644 index 00000000..cd142820 --- /dev/null +++ b/shop/provider/README.adoc @@ -0,0 +1,5 @@ += Shop / Provider + +Container for https://core.telegram.org/bots/payments#getting-a-token[provider tokens]. +Different chats/groups could have different tokens. +It is useful for test purposes: a test group could use test provider (e.g. https://stripe.com/docs/testing[Stripe Test]). diff --git a/shop/provider/build.gradle.kts b/shop/provider/build.gradle.kts new file mode 100644 index 00000000..444baaa3 --- /dev/null +++ b/shop/provider/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + kotlin("jvm") +} diff --git a/shop/provider/src/main/kotlin/by/jprof/telegram/bot/shop/provider/ChatProviderTokens.kt b/shop/provider/src/main/kotlin/by/jprof/telegram/bot/shop/provider/ChatProviderTokens.kt new file mode 100644 index 00000000..809cbc55 --- /dev/null +++ b/shop/provider/src/main/kotlin/by/jprof/telegram/bot/shop/provider/ChatProviderTokens.kt @@ -0,0 +1,3 @@ +package by.jprof.telegram.bot.shop.provider + +typealias ChatProviderTokens = Map From ce5751ca0b1b7c983267c571414fba1f4346c377 Mon Sep 17 00:00:00 2001 From: madhead Date: Fri, 13 Jan 2023 13:03:14 +0100 Subject: [PATCH 2/6] Payloads for invoices --- settings.gradle.kts | 1 + shop/payload/README.adoc | 3 +++ shop/payload/build.gradle.kts | 8 ++++++++ .../by/jprof/telegram/bot/shop/payload/Payload.kt | 6 ++++++ .../by/jprof/telegram/bot/shop/payload/PinsPayload.kt | 11 +++++++++++ .../by/jprof/telegram/bot/shop/payload/RichPayload.kt | 11 +++++++++++ .../jprof/telegram/bot/shop/payload/SupportPayload.kt | 10 ++++++++++ 7 files changed, 50 insertions(+) create mode 100644 shop/payload/README.adoc create mode 100644 shop/payload/build.gradle.kts create mode 100644 shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt create mode 100644 shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt create mode 100644 shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt create mode 100644 shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index 9cd99d0b..654752f6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -44,4 +44,5 @@ include(":english:urban-word-of-the-day:dynamodb") include(":english:urban-word-of-the-day-formatter") include(":english:urban-dictionary-daily") include(":shop:provider") +include(":shop:payload") include(":launchers:lambda") diff --git a/shop/payload/README.adoc b/shop/payload/README.adoc new file mode 100644 index 00000000..cf17aea9 --- /dev/null +++ b/shop/payload/README.adoc @@ -0,0 +1,3 @@ += Shop / Payload + +Payloads to use in `payload` field of https://core.telegram.org/bots/api#sendinvoice[TG Bot API invoices]. diff --git a/shop/payload/build.gradle.kts b/shop/payload/build.gradle.kts new file mode 100644 index 00000000..d6aa50b9 --- /dev/null +++ b/shop/payload/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + kotlin("jvm") + kotlin("plugin.serialization") +} + +dependencies { + implementation(libs.kotlinx.serialization.core) +} diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt new file mode 100644 index 00000000..f1adc4a2 --- /dev/null +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt @@ -0,0 +1,6 @@ +package by.jprof.telegram.bot.shop.payload + +import kotlinx.serialization.Serializable + +@Serializable +sealed class Payload diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt new file mode 100644 index 00000000..87540c61 --- /dev/null +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt @@ -0,0 +1,11 @@ +package by.jprof.telegram.bot.shop.payload + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +@SerialName("pins") +data class PinsPayload( + val pins: Long, + val chat: Long, +) : Payload() diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt new file mode 100644 index 00000000..9e663146 --- /dev/null +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt @@ -0,0 +1,11 @@ +package by.jprof.telegram.bot.shop.payload + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +@SerialName("rich") +data class RichPayload( + val status: String, + val chat: Long, +) : Payload() diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt new file mode 100644 index 00000000..a7365d69 --- /dev/null +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt @@ -0,0 +1,10 @@ +package by.jprof.telegram.bot.shop.payload + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +@SerialName("support") +data class SupportPayload( + val chat: Long, +) : Payload() From c118a005de387c3814cb71058e5e8e97a5406359 Mon Sep 17 00:00:00 2001 From: madhead Date: Fri, 13 Jan 2023 17:01:29 +0100 Subject: [PATCH 3/6] Add `shop` module --- .deploy/lambda/lib/JProfByBotStack.ts | 18 ++++- README.adoc | 2 + gradle/libs.versions.toml | 1 + launchers/lambda/build.gradle.kts | 3 + .../telegram/bot/launchers/lambda/JProf.kt | 2 + .../bot/launchers/lambda/config/env.kt | 16 +++++ .../bot/launchers/lambda/config/pipeline.kt | 52 +++++++++++++++ .../bot/launchers/lambda/config/secrets.kt | 12 ++++ pins/build.gradle.kts | 2 + .../bot/pins/PinCommandUpdateProcessor.kt | 39 +++++++++++ settings.gradle.kts | 1 + shop/README.adoc | 3 + shop/build.gradle.kts | 18 +++++ ...ardedPaymentStartCommandUpdateProcessor.kt | 34 ++++++++++ .../PinsPreCheckoutQueryUpdateProcessor.kt | 50 ++++++++++++++ .../bot/shop/RichCommandUpdateProcessor.kt | 66 +++++++++++++++++++ .../RichPreCheckoutQueryUpdateProcessor.kt | 38 +++++++++++ .../bot/shop/SupportCommandUpdateProcessor.kt | 63 ++++++++++++++++++ .../SupportPreCheckoutQueryUpdateProcessor.kt | 38 +++++++++++ .../by/jprof/telegram/bot/shop/currency.kt | 3 + .../jprof/telegram/bot/shop/utils/messages.kt | 57 ++++++++++++++++ 21 files changed, 516 insertions(+), 2 deletions(-) create mode 100644 launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/secrets.kt create mode 100644 shop/README.adoc create mode 100644 shop/build.gradle.kts create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/ForwardedPaymentStartCommandUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/currency.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt diff --git a/.deploy/lambda/lib/JProfByBotStack.ts b/.deploy/lambda/lib/JProfByBotStack.ts index b6206179..94d5e124 100644 --- a/.deploy/lambda/lib/JProfByBotStack.ts +++ b/.deploy/lambda/lib/JProfByBotStack.ts @@ -3,6 +3,8 @@ import {Construct} from 'constructs'; import * as apigateway from 'aws-cdk-lib/aws-apigateway'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import * as lambda from 'aws-cdk-lib/aws-lambda'; +import {Architecture} from 'aws-cdk-lib/aws-lambda'; +import * as secrets from 'aws-cdk-lib/aws-secretsmanager'; import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks'; import * as ses from 'aws-cdk-lib/aws-ses'; @@ -13,6 +15,8 @@ export class JProfByBotStack extends cdk.Stack { constructor(scope: Construct, id: string, props: JProfByBotStackProps) { super(scope, id, props); + const secretPaymentProviderTokens = new secrets.Secret(this, 'jprof-by-bot-secret-payment-provider-tokens'); + const votesTable = new dynamodb.Table(this, 'jprof-by-bot-table-votes', { tableName: 'jprof-by-bot-table-votes', partitionKey: {name: 'id', type: dynamodb.AttributeType.STRING}, @@ -123,13 +127,20 @@ export class JProfByBotStack extends cdk.Stack { }); const layerLibGL = new lambda.LayerVersion(this, 'jprof-by-bot-lambda-layer-libGL', { + layerVersionName: 'libGL', code: lambda.Code.fromAsset('layers/libGL.zip'), - compatibleRuntimes: [lambda.Runtime.JAVA_11], + compatibleArchitectures: [Architecture.ARM_64], }); const layerLibfontconfig = new lambda.LayerVersion(this, 'jprof-by-bot-lambda-layer-libfontconfig', { + layerVersionName: 'libfontconfig', code: lambda.Code.fromAsset('layers/libfontconfig.zip'), - compatibleRuntimes: [lambda.Runtime.JAVA_11], + compatibleArchitectures: [Architecture.ARM_64], }); + const layerParametersAndSecretsLambdaExtension = lambda.LayerVersion.fromLayerVersionArn( + this, + 'jprof-by-bot-lambda-layer-parametersAndSecretsLambdaExtension', + 'arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2' + ) const lambdaWebhookTimeout = cdk.Duration.seconds(29); const lambdaWebhook = new lambda.Function(this, 'jprof-by-bot-lambda-webhook', { @@ -138,6 +149,7 @@ export class JProfByBotStack extends cdk.Stack { layers: [ layerLibGL, layerLibfontconfig, + layerParametersAndSecretsLambdaExtension, ], timeout: lambdaWebhookTimeout, maxEventAge: cdk.Duration.minutes(5), @@ -198,6 +210,8 @@ export class JProfByBotStack extends cdk.Stack { ], }); + secretPaymentProviderTokens.grantRead(lambdaWebhook); + votesTable.grantReadWriteData(lambdaWebhook); youtubeChannelsWhitelistTable.grantReadData(lambdaWebhook); diff --git a/README.adoc b/README.adoc index 2411b957..fd229ac8 100644 --- a/README.adoc +++ b/README.adoc @@ -12,7 +12,9 @@ Official Telegram bot of Java Professionals BY community. * Converts some currencies to EUR and USD * Posts scheduled messages from this repo's `posts` branch * Expands LeetCode links +* Tells users' local times * Regulates our English Rooms & teaches us new English words +* Sells pins and custom statuses 🤑 So, it just brings some fun and interactivity in our chat. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ce66c3e9..af9f6e6e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,6 +37,7 @@ aws-lambda-java-events = { group = "com.amazonaws", name = "aws-lambda-java-even aws-lambda-java-core = { group = "com.amazonaws", name = "aws-lambda-java-core", version.ref = "aws-lambda-java-core" } aws-lambda-java-log4j2 = { group = "com.amazonaws", name = "aws-lambda-java-log4j2", version.ref = "aws-lambda-java-log4j2" } dynamodb = { group = "software.amazon.awssdk", name = "dynamodb", version.ref = "awssdk" } +secretsmanager = { group = "software.amazon.awssdk", name = "secretsmanager", version.ref = "awssdk" } sfn = { group = "software.amazon.awssdk", name = "sfn", version.ref = "awssdk" } koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin" } diff --git a/launchers/lambda/build.gradle.kts b/launchers/lambda/build.gradle.kts index a1bbab28..78d0f9fe 100644 --- a/launchers/lambda/build.gradle.kts +++ b/launchers/lambda/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { implementation(libs.bundles.aws.lambda) + implementation(libs.secretsmanager) implementation(libs.koin.core) implementation(libs.tgbotapi) implementation(libs.bundles.log4j) @@ -28,4 +29,6 @@ dependencies { implementation(project.projects.english.urbanWordOfTheDay.dynamodb) implementation(project.projects.english.urbanDictionary) implementation(project.projects.english.dictionaryapiDev) + implementation(project.projects.shop.provider) + implementation(project.projects.shop) } diff --git a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt index 336e606c..f1cbbbd8 100644 --- a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt +++ b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt @@ -7,6 +7,7 @@ import by.jprof.telegram.bot.launchers.lambda.config.dictionaryApiDevModule import by.jprof.telegram.bot.launchers.lambda.config.envModule import by.jprof.telegram.bot.launchers.lambda.config.jsonModule import by.jprof.telegram.bot.launchers.lambda.config.pipelineModule +import by.jprof.telegram.bot.launchers.lambda.config.secretsModule import by.jprof.telegram.bot.launchers.lambda.config.sfnModule import by.jprof.telegram.bot.launchers.lambda.config.telegramModule import by.jprof.telegram.bot.launchers.lambda.config.urbanDictionaryModule @@ -45,6 +46,7 @@ class JProf : RequestHandler, K init { startKoin { modules( + secretsModule, envModule, databaseModule, jsonModule, diff --git a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt index 1af82d2f..38cd6342 100644 --- a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt +++ b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt @@ -1,7 +1,13 @@ package by.jprof.telegram.bot.launchers.lambda.config +import by.jprof.telegram.bot.shop.provider.ChatProviderTokens +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json import org.koin.core.qualifier.named import org.koin.dsl.module +import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient + +private const val SECRET_PAYMENT_PROVIDER_TOKENS = "jprof-by-bot-secret-payment-provider-tokens" const val TOKEN_TELEGRAM_BOT = "TOKEN_TELEGRAM_BOT" const val TOKEN_YOUTUBE_API = "TOKEN_YOUTUBE_API" @@ -42,4 +48,14 @@ val envModule = module { single(named(TIMEOUT)) { System.getenv(TIMEOUT)!!.toLong() } + + single { + val json: Json = get() + val secrets: SecretsManagerClient = get() + val secret = secrets.getSecretValue { + it.secretId(SECRET_PAYMENT_PROVIDER_TOKENS) + } + + json.decodeFromString(secret.secretString()) + } } diff --git a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt index d9180f1a..b87097b7 100644 --- a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt +++ b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt @@ -21,6 +21,12 @@ import by.jprof.telegram.bot.quizoji.QuizojiOptionUpdateProcessor import by.jprof.telegram.bot.quizoji.QuizojiQuestionUpdateProcessor import by.jprof.telegram.bot.quizoji.QuizojiStartCommandUpdateProcessor import by.jprof.telegram.bot.quizoji.QuizojiVoteUpdateProcessor +import by.jprof.telegram.bot.shop.ForwardedPaymentStartCommandUpdateProcessor +import by.jprof.telegram.bot.shop.PinsPreCheckoutQueryUpdateProcessor +import by.jprof.telegram.bot.shop.RichCommandUpdateProcessor +import by.jprof.telegram.bot.shop.RichPreCheckoutQueryUpdateProcessor +import by.jprof.telegram.bot.shop.SupportCommandUpdateProcessor +import by.jprof.telegram.bot.shop.SupportPreCheckoutQueryUpdateProcessor import by.jprof.telegram.bot.times.TimeCommandUpdateProcessor import by.jprof.telegram.bot.times.TimeZoneCommandUpdateProcessor import by.jprof.telegram.bot.youtube.YouTubeUpdateProcessor @@ -116,6 +122,8 @@ val pipelineModule = module { pinDAO = get(), unpinScheduler = get(), bot = get(), + providerTokens = get(), + json = get(), ) } @@ -191,4 +199,48 @@ val pipelineModule = module { bot = get(), ) } + + single(named("RichCommandUpdateProcessor")) { + RichCommandUpdateProcessor( + bot = get(), + providerTokens = get(), + json = get(), + ) + } + + single(named("RichPreCheckoutQueryUpdateProcessor")) { + RichPreCheckoutQueryUpdateProcessor( + bot = get(), + json = get(), + ) + } + + single(named("SupportCommandUpdateProcessor")) { + SupportCommandUpdateProcessor( + bot = get(), + providerTokens = get(), + json = get(), + ) + } + + single(named("SupportPreCheckoutQueryUpdateProcessor")) { + SupportPreCheckoutQueryUpdateProcessor( + bot = get(), + json = get(), + ) + } + + single(named("ForwardedPaymentStartCommandUpdateProcessor")) { + ForwardedPaymentStartCommandUpdateProcessor( + bot = get(), + ) + } + + single(named("PinsPreCheckoutQueryUpdateProcessor")) { + PinsPreCheckoutQueryUpdateProcessor( + bot = get(), + json = get(), + moniesDAO = get(), + ) + } } diff --git a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/secrets.kt b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/secrets.kt new file mode 100644 index 00000000..ef60d2dc --- /dev/null +++ b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/secrets.kt @@ -0,0 +1,12 @@ +package by.jprof.telegram.bot.launchers.lambda.config + +import kotlinx.serialization.ExperimentalSerializationApi +import org.koin.dsl.module +import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient + +@ExperimentalSerializationApi +val secretsModule = module { + single { + SecretsManagerClient.create() + } +} diff --git a/pins/build.gradle.kts b/pins/build.gradle.kts index f1d8c651..a833199b 100644 --- a/pins/build.gradle.kts +++ b/pins/build.gradle.kts @@ -6,6 +6,8 @@ dependencies { api(project.projects.core) api(libs.tgbotapi) api(project.projects.monies) + implementation(project.projects.shop.provider) + implementation(project.projects.shop.payload) implementation(project.projects.pins.dto) implementation(project.projects.pins.scheduler) implementation(libs.log4j.api) diff --git a/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt b/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt index 24c17603..2527597b 100644 --- a/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt +++ b/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt @@ -8,6 +8,7 @@ import by.jprof.telegram.bot.pins.dao.PinDAO import by.jprof.telegram.bot.pins.dto.Unpin import by.jprof.telegram.bot.pins.model.Pin import by.jprof.telegram.bot.pins.model.PinDuration +import by.jprof.telegram.bot.pins.model.PinRequest import by.jprof.telegram.bot.pins.scheduler.UnpinScheduler import by.jprof.telegram.bot.pins.utils.PinRequestFinder import by.jprof.telegram.bot.pins.utils.beggar @@ -16,13 +17,20 @@ import by.jprof.telegram.bot.pins.utils.negativeDuration import by.jprof.telegram.bot.pins.utils.tooManyPinnedMessages import by.jprof.telegram.bot.pins.utils.tooPositiveDuration import by.jprof.telegram.bot.pins.utils.unrecognizedDuration +import by.jprof.telegram.bot.shop.payload.PinsPayload +import by.jprof.telegram.bot.shop.provider.ChatProviderTokens import dev.inmo.tgbotapi.bot.RequestsExecutor import dev.inmo.tgbotapi.extensions.api.chat.modify.pinChatMessage +import dev.inmo.tgbotapi.extensions.api.send.payments.sendInvoice import dev.inmo.tgbotapi.extensions.api.send.reply import dev.inmo.tgbotapi.types.message.MarkdownV2 +import dev.inmo.tgbotapi.types.payments.LabeledPrice import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.utils.PreviewFeature import java.time.Duration +import kotlin.random.Random +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import org.apache.logging.log4j.LogManager @PreviewFeature @@ -31,6 +39,8 @@ class PinCommandUpdateProcessor( private val pinDAO: PinDAO, private val unpinScheduler: UnpinScheduler, private val bot: RequestsExecutor, + private val providerTokens: ChatProviderTokens, + private val json: Json, private val pinRequestFinder: PinRequestFinder = PinRequestFinder.DEFAULT ) : UpdateProcessor { companion object { @@ -47,6 +57,7 @@ class PinCommandUpdateProcessor( if (pin.message == null) { bot.reply(to = pin.request, text = help(pins), parseMode = MarkdownV2) + pinsShop(pin) return } @@ -71,6 +82,7 @@ class PinCommandUpdateProcessor( if (pins < pin.price) { bot.reply(to = pin.request, text = beggar(pins, pin.price), parseMode = MarkdownV2) + pinsShop(pin) return } @@ -90,9 +102,36 @@ class PinCommandUpdateProcessor( chatId = pin.chat.id.chatId ttl = duration.duration.seconds }) + if (Random.nextInt(4) == 0) { + pinsShop(pin) + } } catch (e: Exception) { logger.error("Failed to pin a message", e) } } } + + private suspend fun pinsShop(pin: PinRequest) { + val chatProviderToken = providerTokens[pin.request.chat.id.chatId] + + if (chatProviderToken != null) { + bot.sendInvoice( + chatId = pin.request.chat.id, + title = "168 пинов", + description = "Неделя закрепа", + payload = json.encodeToString(PinsPayload( + pins = 168, + chat = pin.request.chat.id.chatId, + )), + providerToken = chatProviderToken, + currency = "USD", + prices = listOf( + LabeledPrice("Пины × 168", 200) + ), + startParameter = "forwarded_payment", + replyToMessageId = pin.request.messageId, + allowSendingWithoutReply = true, + ) + } + } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 654752f6..bc16e876 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -45,4 +45,5 @@ include(":english:urban-word-of-the-day-formatter") include(":english:urban-dictionary-daily") include(":shop:provider") include(":shop:payload") +include(":shop") include(":launchers:lambda") diff --git a/shop/README.adoc b/shop/README.adoc new file mode 100644 index 00000000..057b5174 --- /dev/null +++ b/shop/README.adoc @@ -0,0 +1,3 @@ += Shop + +This feature allows users to buy link:../pins[pins] and custom titles. diff --git a/shop/build.gradle.kts b/shop/build.gradle.kts new file mode 100644 index 00000000..3373f256 --- /dev/null +++ b/shop/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + kotlin("jvm") +} + +dependencies { + api(project.projects.core) + api(libs.tgbotapi) + implementation(project.projects.shop.provider) + implementation(project.projects.shop.payload) + implementation(project.projects.monies) + implementation(libs.log4j.api) + + testImplementation(libs.junit.jupiter.api) + testImplementation(libs.junit.jupiter.params) + testImplementation(libs.mockk) + testRuntimeOnly(libs.junit.jupiter.engine) + testRuntimeOnly(libs.log4j.core) +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/ForwardedPaymentStartCommandUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/ForwardedPaymentStartCommandUpdateProcessor.kt new file mode 100644 index 00000000..d12f6238 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/ForwardedPaymentStartCommandUpdateProcessor.kt @@ -0,0 +1,34 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.utils.forwardedPaymentsAreNotSupported +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.send.sendMessage +import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate +import dev.inmo.tgbotapi.extensions.utils.asPrivateChat +import dev.inmo.tgbotapi.extensions.utils.asPrivateContentMessage +import dev.inmo.tgbotapi.extensions.utils.asTextContent +import dev.inmo.tgbotapi.types.message.MarkdownV2ParseMode +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature + +@PreviewFeature +class ForwardedPaymentStartCommandUpdateProcessor( + private val bot: RequestsExecutor, +) : UpdateProcessor { + override suspend fun process(update: Update) { + val message = update.asMessageUpdate()?.data?.asPrivateContentMessage() ?: return + val chat = message.chat.asPrivateChat() ?: return + val content = message.content.asTextContent() ?: return + + if (content.text != "/start forwarded_payment") { + return + } + + bot.sendMessage( + chat = chat, + text = forwardedPaymentsAreNotSupported(), + parseMode = MarkdownV2ParseMode, + ) + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt new file mode 100644 index 00000000..5407e484 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt @@ -0,0 +1,50 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.monies.dao.MoniesDAO +import by.jprof.telegram.bot.monies.model.Monies +import by.jprof.telegram.bot.shop.payload.PinsPayload +import by.jprof.telegram.bot.shop.utils.tooManyPins +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryError +import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryOk +import dev.inmo.tgbotapi.extensions.utils.asPreCheckoutQueryUpdate +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.apache.logging.log4j.LogManager + +@OptIn(PreviewFeature::class) +class PinsPreCheckoutQueryUpdateProcessor( + private val bot: RequestsExecutor, + private val json: Json, + private val moniesDAO: MoniesDAO, +) : UpdateProcessor { + companion object { + private val logger = LogManager.getLogger(PinsPreCheckoutQueryUpdateProcessor::class.java)!! + } + + override suspend fun process(update: Update) { + val preCheckoutQuery = update.asPreCheckoutQueryUpdate()?.data ?: return + + logger.debug(preCheckoutQuery) + + val payload = try { + json.decodeFromString(preCheckoutQuery.invoicePayload) + } catch (_: Exception) { + return + } + + logger.debug(payload) + + val monies = moniesDAO.get(preCheckoutQuery.user.id.chatId, payload.chat) ?: Monies(preCheckoutQuery.user.id.chatId, payload.chat) + val pins = monies.pins ?: 0 + + if (pins > 9999) { + bot.answerPreCheckoutQueryError(preCheckoutQuery, tooManyPins()) + } else { + bot.answerPreCheckoutQueryOk(preCheckoutQuery) + } + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt new file mode 100644 index 00000000..f329d9e2 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt @@ -0,0 +1,66 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.RichPayload +import by.jprof.telegram.bot.shop.provider.ChatProviderTokens +import by.jprof.telegram.bot.shop.utils.notAShop +import by.jprof.telegram.bot.shop.utils.richInvoiceDescription +import by.jprof.telegram.bot.shop.utils.richInvoiceTitle +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.send.payments.sendInvoice +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.utils.asBotCommandTextSource +import dev.inmo.tgbotapi.extensions.utils.asContentMessage +import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate +import dev.inmo.tgbotapi.extensions.utils.asTextContent +import dev.inmo.tgbotapi.types.message.MarkdownV2ParseMode +import dev.inmo.tgbotapi.types.payments.LabeledPrice +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +private val item = LabeledPrice("Флекс × 9000", 500) + +@OptIn(PreviewFeature::class) +class RichCommandUpdateProcessor( + private val bot: RequestsExecutor, + private val providerTokens: ChatProviderTokens, + private val json: Json, +) : UpdateProcessor { + override suspend fun process(update: Update) { + val message = update.asMessageUpdate()?.data?.asContentMessage() ?: return + val content = message.content.asTextContent() ?: return + val command = content.textSources + .mapNotNull { it.asBotCommandTextSource() } + .firstOrNull { it.command == "rich" || it.command == "vip" } ?: return + val status = when (command.command) { + "rich" -> "I AM RICH" + else -> "V.I.P." + } + + val chatProviderToken = providerTokens[message.chat.id.chatId] + + if (chatProviderToken == null) { + bot.reply( + to = message, + text = notAShop(), + parseMode = MarkdownV2ParseMode, + disableNotification = true, + ) + } else { + bot.sendInvoice( + chatId = message.chat.id, + title = richInvoiceTitle(status), + description = richInvoiceDescription(), + payload = json.encodeToString(RichPayload(status = status, chat = message.chat.id.chatId)), + providerToken = chatProviderToken, + currency = currency, + prices = listOf(item), + startParameter = "forwarded_payment", + replyToMessageId = message.messageId, + allowSendingWithoutReply = true, + ) + } + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt new file mode 100644 index 00000000..8f56cc48 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt @@ -0,0 +1,38 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.RichPayload +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryOk +import dev.inmo.tgbotapi.extensions.utils.asPreCheckoutQueryUpdate +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.apache.logging.log4j.LogManager + +@OptIn(PreviewFeature::class) +class RichPreCheckoutQueryUpdateProcessor( + private val bot: RequestsExecutor, + private val json: Json, +) : UpdateProcessor { + companion object { + private val logger = LogManager.getLogger(RichPreCheckoutQueryUpdateProcessor::class.java)!! + } + + override suspend fun process(update: Update) { + val preCheckoutQuery = update.asPreCheckoutQueryUpdate()?.data ?: return + + logger.debug(preCheckoutQuery) + + val payload = try { + json.decodeFromString(preCheckoutQuery.invoicePayload) + } catch (_: Exception) { + return + } + + logger.debug(payload) + + bot.answerPreCheckoutQueryOk(preCheckoutQuery) + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt new file mode 100644 index 00000000..1e5a3e99 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt @@ -0,0 +1,63 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.SupportPayload +import by.jprof.telegram.bot.shop.provider.ChatProviderTokens +import by.jprof.telegram.bot.shop.utils.notAShop +import by.jprof.telegram.bot.shop.utils.supportInvoiceDescription +import by.jprof.telegram.bot.shop.utils.supportInvoiceTitle +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.send.payments.sendInvoice +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.utils.asBotCommandTextSource +import dev.inmo.tgbotapi.extensions.utils.asContentMessage +import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate +import dev.inmo.tgbotapi.extensions.utils.asTextContent +import dev.inmo.tgbotapi.types.message.MarkdownV2ParseMode +import dev.inmo.tgbotapi.types.payments.LabeledPrice +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +private val item = LabeledPrice("❤️ × ∞", 100) + +@OptIn(PreviewFeature::class) +class SupportCommandUpdateProcessor( + private val bot: RequestsExecutor, + private val providerTokens: ChatProviderTokens, + private val json: Json, +) : UpdateProcessor { + override suspend fun process(update: Update) { + val message = update.asMessageUpdate()?.data?.asContentMessage() ?: return + val content = message.content.asTextContent() ?: return + + if (content.textSources.mapNotNull { it.asBotCommandTextSource() }.none { it.command == "support" }) { + return + } + + val chatProviderToken = providerTokens[message.chat.id.chatId] + + if (chatProviderToken == null) { + bot.reply( + to = message, + text = notAShop(), + parseMode = MarkdownV2ParseMode, + disableNotification = true, + ) + } else { + bot.sendInvoice( + chatId = message.chat.id, + title = supportInvoiceTitle(), + description = supportInvoiceDescription(), + payload = json.encodeToString(SupportPayload(chat = message.chat.id.chatId)), + providerToken = chatProviderToken, + currency = currency, + prices = listOf(item), + startParameter = "forwarded_payment", + replyToMessageId = message.messageId, + allowSendingWithoutReply = true, + ) + } + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt new file mode 100644 index 00000000..1bd81721 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt @@ -0,0 +1,38 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.SupportPayload +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryOk +import dev.inmo.tgbotapi.extensions.utils.asPreCheckoutQueryUpdate +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.apache.logging.log4j.LogManager + +@OptIn(PreviewFeature::class) +class SupportPreCheckoutQueryUpdateProcessor( + private val bot: RequestsExecutor, + private val json: Json, +) : UpdateProcessor { + companion object { + private val logger = LogManager.getLogger(SupportPreCheckoutQueryUpdateProcessor::class.java)!! + } + + override suspend fun process(update: Update) { + val preCheckoutQuery = update.asPreCheckoutQueryUpdate()?.data ?: return + + logger.debug(preCheckoutQuery) + + val payload = try { + json.decodeFromString(preCheckoutQuery.invoicePayload) + } catch (_: Exception) { + return + } + + logger.debug(payload) + + bot.answerPreCheckoutQueryOk(preCheckoutQuery) + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/currency.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/currency.kt new file mode 100644 index 00000000..3e2b7879 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/currency.kt @@ -0,0 +1,3 @@ +package by.jprof.telegram.bot.shop + +const val currency = "USD" diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt new file mode 100644 index 00000000..65914bfc --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt @@ -0,0 +1,57 @@ +package by.jprof.telegram.bot.shop.utils + +import java.text.MessageFormat + +private val notAShopMessages = listOf( + "В этом чате ничего не продаётся\\!" +) + +internal fun notAShop(): String { + return notAShopMessages.random() +} + +private val richInvoiceTitleMessages = listOf( + "Статус \"{0}\"" +) + +fun richInvoiceTitle(status: String): String = + MessageFormat(richInvoiceTitleMessages.random()) + .format(status) + +private val richInvoiceDescriptionMessages = listOf( + "Отображается в чате возле ваших сообщений" +) + +fun richInvoiceDescription(): String = + richInvoiceDescriptionMessages.random() + +private val supportInvoiceTitleMessages = listOf( + "Поддержка JProf", +) + +fun supportInvoiceTitle(): String = + supportInvoiceTitleMessages.random() + +private val supportInvoiceDescriptionMessages = listOf( + "Безвозмездная поддержка JProf" +) + +fun supportInvoiceDescription(): String = + supportInvoiceDescriptionMessages.random() + +private val forwardedPaymentsAreNotSupportedMessages = listOf( + "Ты пытаешься оплатить пересланный инвойс\\. Покупка и оплата возможны только под оригинальным сообщением\\." +) + +internal fun forwardedPaymentsAreNotSupported(): String { + return forwardedPaymentsAreNotSupportedMessages.random() +} + +private val tooManyPinsMessages = listOf( + "У тебя и так хватает пинов\\!", + "У тебя и так много пинов\\!", +) + +internal fun tooManyPins(): String { + return tooManyPinsMessages.random() +} From 4d4c4269a14ae4a4a7778390876ace28bc506622 Mon Sep 17 00:00:00 2001 From: madhead Date: Sat, 14 Jan 2023 00:29:38 +0100 Subject: [PATCH 4/6] WIP --- .deploy/lambda/lib/JProfByBotStack.ts | 18 ++++--- .../bot/core/UpdateProcessingPipeline.kt | 2 +- deploy.sh | 8 +++ .../kotlin/KotlinMentionsUpdateProcessor.kt | 4 +- .../telegram/bot/launchers/lambda/JProf.kt | 3 +- .../bot/launchers/lambda/config/env.kt | 4 +- .../bot/launchers/lambda/config/pipeline.kt | 29 ++++++++++- .../bot/pins/PinCommandUpdateProcessor.kt | 5 +- .../bot/pins/PinReplyUpdateProcessor.kt | 2 +- .../telegram/bot/shop/payload/Payload.kt | 2 +- .../telegram/bot/shop/payload/PinsPayload.kt | 2 +- .../telegram/bot/shop/payload/RichPayload.kt | 2 +- .../bot/shop/payload/SupportPayload.kt | 2 +- .../PinsPreCheckoutQueryUpdateProcessor.kt | 12 +++-- .../PinsSuccessfulPaymentUpdateProcessor.kt | 51 +++++++++++++++++++ .../bot/shop/RichCommandUpdateProcessor.kt | 3 +- .../RichPreCheckoutQueryUpdateProcessor.kt | 8 ++- .../RichSuccessfulPaymentUpdateProcessor.kt | 47 +++++++++++++++++ .../bot/shop/SupportCommandUpdateProcessor.kt | 3 +- .../SupportPreCheckoutQueryUpdateProcessor.kt | 8 ++- ...SupportSuccessfulPaymentUpdateProcessor.kt | 46 +++++++++++++++++ .../kotlin/by/jprof/telegram/bot/shop/app.kt | 19 +++++++ .../jprof/telegram/bot/shop/utils/messages.kt | 2 +- .../bot/times/TimeCommandUpdateProcessor.kt | 4 +- .../times/TimeZoneCommandUpdateProcessor.kt | 2 +- 25 files changed, 246 insertions(+), 42 deletions(-) create mode 100755 deploy.sh create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsSuccessfulPaymentUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichSuccessfulPaymentUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt create mode 100644 shop/src/main/kotlin/by/jprof/telegram/bot/shop/app.kt diff --git a/.deploy/lambda/lib/JProfByBotStack.ts b/.deploy/lambda/lib/JProfByBotStack.ts index 94d5e124..8d691d86 100644 --- a/.deploy/lambda/lib/JProfByBotStack.ts +++ b/.deploy/lambda/lib/JProfByBotStack.ts @@ -15,7 +15,13 @@ export class JProfByBotStack extends cdk.Stack { constructor(scope: Construct, id: string, props: JProfByBotStackProps) { super(scope, id, props); - const secretPaymentProviderTokens = new secrets.Secret(this, 'jprof-by-bot-secret-payment-provider-tokens'); + const secretPaymentProviderTokens = new secrets.Secret(this, 'jprof-by-bot-secret-payment-provider-tokens', { + secretName: 'jprof-by-bot-secret-payment-provider-tokens', + secretObjectValue: { + test: cdk.SecretValue.unsafePlainText('test'), + production: cdk.SecretValue.unsafePlainText('production'), + } + }); const votesTable = new dynamodb.Table(this, 'jprof-by-bot-table-votes', { tableName: 'jprof-by-bot-table-votes', @@ -107,7 +113,7 @@ export class JProfByBotStack extends cdk.Stack { code: lambda.Code.fromAsset('../../pins/unpin/build/libs/jprof_by_bot-pins-unpin-all.jar'), handler: 'by.jprof.telegram.bot.pins.unpin.Handler', environment: { - 'LOG_THRESHOLD': 'DEBUG', + 'LOG_THRESHOLD': 'INFO', 'TABLE_PINS': pinsTable.tableName, 'TOKEN_TELEGRAM_BOT': props.telegramToken, }, @@ -129,12 +135,12 @@ export class JProfByBotStack extends cdk.Stack { const layerLibGL = new lambda.LayerVersion(this, 'jprof-by-bot-lambda-layer-libGL', { layerVersionName: 'libGL', code: lambda.Code.fromAsset('layers/libGL.zip'), - compatibleArchitectures: [Architecture.ARM_64], + compatibleArchitectures: [Architecture.X86_64], }); const layerLibfontconfig = new lambda.LayerVersion(this, 'jprof-by-bot-lambda-layer-libfontconfig', { layerVersionName: 'libfontconfig', code: lambda.Code.fromAsset('layers/libfontconfig.zip'), - compatibleArchitectures: [Architecture.ARM_64], + compatibleArchitectures: [Architecture.X86_64], }); const layerParametersAndSecretsLambdaExtension = lambda.LayerVersion.fromLayerVersionArn( this, @@ -158,7 +164,7 @@ export class JProfByBotStack extends cdk.Stack { code: lambda.Code.fromAsset('../../launchers/lambda/build/libs/jprof_by_bot-launchers-lambda-all.jar'), handler: 'by.jprof.telegram.bot.launchers.lambda.JProf', environment: { - 'LOG_THRESHOLD': 'DEBUG', + 'LOG_THRESHOLD': 'INFO', 'TABLE_VOTES': votesTable.tableName, 'TABLE_YOUTUBE_CHANNELS_WHITELIST': youtubeChannelsWhitelistTable.tableName, 'TABLE_KOTLIN_MENTIONS': kotlinMentionsTable.tableName, @@ -189,7 +195,7 @@ export class JProfByBotStack extends cdk.Stack { code: lambda.Code.fromAsset('../../english/urban-dictionary-daily/build/libs/jprof_by_bot-english-urban-dictionary-daily-all.jar'), handler: 'by.jprof.telegram.bot.english.urban_dictionary_daily.Handler', environment: { - 'LOG_THRESHOLD': 'DEBUG', + 'LOG_THRESHOLD': 'INFO', 'TABLE_URBAN_WORDS_OF_THE_DAY': urbanWordsOfTheDayTable.tableName, 'TABLE_LANGUAGE_ROOMS': languageRoomsTable.tableName, 'TOKEN_TELEGRAM_BOT': props.telegramToken, diff --git a/core/src/main/kotlin/by/jprof/telegram/bot/core/UpdateProcessingPipeline.kt b/core/src/main/kotlin/by/jprof/telegram/bot/core/UpdateProcessingPipeline.kt index e4e886f8..b34fadb1 100644 --- a/core/src/main/kotlin/by/jprof/telegram/bot/core/UpdateProcessingPipeline.kt +++ b/core/src/main/kotlin/by/jprof/telegram/bot/core/UpdateProcessingPipeline.kt @@ -23,7 +23,7 @@ class UpdateProcessingPipeline( processors .map { launch(exceptionHandler(it)) { - logger.debug("Processing update with ${it::class.simpleName}") + logger.trace("Processing update with ${it::class.simpleName}") it.process(update) } } diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..247e9e7a --- /dev/null +++ b/deploy.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +source .env && +./gradlew clean shadowJar && +pushd .deploy/lambda && +npm install && +cdk deploy --outputs-file=cdk.out/outputs.json --require-approval=never && +popd diff --git a/kotlin/src/main/kotlin/by/jprof/telegram/bot/kotlin/KotlinMentionsUpdateProcessor.kt b/kotlin/src/main/kotlin/by/jprof/telegram/bot/kotlin/KotlinMentionsUpdateProcessor.kt index 36242faf..77d77e57 100644 --- a/kotlin/src/main/kotlin/by/jprof/telegram/bot/kotlin/KotlinMentionsUpdateProcessor.kt +++ b/kotlin/src/main/kotlin/by/jprof/telegram/bot/kotlin/KotlinMentionsUpdateProcessor.kt @@ -50,7 +50,7 @@ class KotlinMentionsUpdateProcessor( else -> return } - logger.info("Kotlin mentioned!") + logger.debug("Kotlin mentioned!") val now = Instant.now() val user = (message as? FromUserMessage)?.user ?: return @@ -128,6 +128,6 @@ class KotlinMentionsUpdateProcessor( replyToMessageId = message.messageId, ) - logger.info("Kotlin mention reported!") + logger.debug("Kotlin mention reported!") } } diff --git a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt index f1cbbbd8..fbfc8cf4 100644 --- a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt +++ b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/JProf.kt @@ -66,10 +66,11 @@ class JProf : RequestHandler, K override fun handleRequest(input: APIGatewayV2HTTPEvent, context: Context): APIGatewayV2HTTPResponse { logger.debug("Incoming request: {}", input) + logger.info(input.body) val update = json.decodeFromString(UpdateDeserializationStrategy, input.body ?: return OK) - logger.debug("Parsed update: {}", update) + logger.info("{}", update) pipeline.process(update) diff --git a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt index 38cd6342..77e687ba 100644 --- a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt +++ b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/env.kt @@ -49,13 +49,13 @@ val envModule = module { System.getenv(TIMEOUT)!!.toLong() } - single { + single { val json: Json = get() val secrets: SecretsManagerClient = get() val secret = secrets.getSecretValue { it.secretId(SECRET_PAYMENT_PROVIDER_TOKENS) } - json.decodeFromString(secret.secretString()) + json.decodeFromString(secret.secretString()) } } diff --git a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt index b87097b7..b6ce17a2 100644 --- a/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt +++ b/launchers/lambda/src/main/kotlin/by/jprof/telegram/bot/launchers/lambda/config/pipeline.kt @@ -23,10 +23,13 @@ import by.jprof.telegram.bot.quizoji.QuizojiStartCommandUpdateProcessor import by.jprof.telegram.bot.quizoji.QuizojiVoteUpdateProcessor import by.jprof.telegram.bot.shop.ForwardedPaymentStartCommandUpdateProcessor import by.jprof.telegram.bot.shop.PinsPreCheckoutQueryUpdateProcessor +import by.jprof.telegram.bot.shop.PinsSuccessfulPaymentUpdateProcessor import by.jprof.telegram.bot.shop.RichCommandUpdateProcessor import by.jprof.telegram.bot.shop.RichPreCheckoutQueryUpdateProcessor +import by.jprof.telegram.bot.shop.RichSuccessfulPaymentUpdateProcessor import by.jprof.telegram.bot.shop.SupportCommandUpdateProcessor import by.jprof.telegram.bot.shop.SupportPreCheckoutQueryUpdateProcessor +import by.jprof.telegram.bot.shop.SupportSuccessfulPaymentUpdateProcessor import by.jprof.telegram.bot.times.TimeCommandUpdateProcessor import by.jprof.telegram.bot.times.TimeZoneCommandUpdateProcessor import by.jprof.telegram.bot.youtube.YouTubeUpdateProcessor @@ -215,6 +218,13 @@ val pipelineModule = module { ) } + single(named("RichSuccessfulPaymentUpdateProcessor")) { + RichSuccessfulPaymentUpdateProcessor( + bot = get(), + json = get(), + ) + } + single(named("SupportCommandUpdateProcessor")) { SupportCommandUpdateProcessor( bot = get(), @@ -230,9 +240,10 @@ val pipelineModule = module { ) } - single(named("ForwardedPaymentStartCommandUpdateProcessor")) { - ForwardedPaymentStartCommandUpdateProcessor( + single(named("SupportSuccessfulPaymentUpdateProcessor")) { + SupportSuccessfulPaymentUpdateProcessor( bot = get(), + json = get(), ) } @@ -243,4 +254,18 @@ val pipelineModule = module { moniesDAO = get(), ) } + + single(named("PinsSuccessfulPaymentUpdateProcessor")) { + PinsSuccessfulPaymentUpdateProcessor( + bot = get(), + json = get(), + moniesDAO = get(), + ) + } + + single(named("ForwardedPaymentStartCommandUpdateProcessor")) { + ForwardedPaymentStartCommandUpdateProcessor( + bot = get(), + ) + } } diff --git a/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt b/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt index 2527597b..2f7f9945 100644 --- a/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt +++ b/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinCommandUpdateProcessor.kt @@ -17,6 +17,7 @@ import by.jprof.telegram.bot.pins.utils.negativeDuration import by.jprof.telegram.bot.pins.utils.tooManyPinnedMessages import by.jprof.telegram.bot.pins.utils.tooPositiveDuration import by.jprof.telegram.bot.pins.utils.unrecognizedDuration +import by.jprof.telegram.bot.shop.payload.Payload import by.jprof.telegram.bot.shop.payload.PinsPayload import by.jprof.telegram.bot.shop.provider.ChatProviderTokens import dev.inmo.tgbotapi.bot.RequestsExecutor @@ -49,7 +50,7 @@ class PinCommandUpdateProcessor( override suspend fun process(update: Update) { pinRequestFinder(update)?.let { pin -> - logger.info("Pin requested: {}", pin) + logger.debug("Pin requested: {}", pin) val monies = moniesDAO.get(pin.user.id.chatId, pin.chat.id.chatId) ?: Monies(pin.user.id.chatId, pin.chat.id.chatId) val pins = monies.pins ?: 0 @@ -119,7 +120,7 @@ class PinCommandUpdateProcessor( chatId = pin.request.chat.id, title = "168 пинов", description = "Неделя закрепа", - payload = json.encodeToString(PinsPayload( + payload = json.encodeToString(PinsPayload( pins = 168, chat = pin.request.chat.id.chatId, )), diff --git a/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinReplyUpdateProcessor.kt b/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinReplyUpdateProcessor.kt index 78d15560..e181883e 100644 --- a/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinReplyUpdateProcessor.kt +++ b/pins/src/main/kotlin/by/jprof/telegram/bot/pins/PinReplyUpdateProcessor.kt @@ -28,7 +28,7 @@ class PinReplyUpdateProcessor( return } - logger.info("{} replied to {}", replier, pin) + logger.debug("{} replied to {}", replier, pin) val monies = moniesDAO.get(pin.userId, replyTo.chat.id.chatId) ?: Monies(pin.userId, replyTo.chat.id.chatId) diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt index f1adc4a2..b969d4e5 100644 --- a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/Payload.kt @@ -3,4 +3,4 @@ package by.jprof.telegram.bot.shop.payload import kotlinx.serialization.Serializable @Serializable -sealed class Payload +sealed interface Payload diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt index 87540c61..830fcb2d 100644 --- a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/PinsPayload.kt @@ -8,4 +8,4 @@ import kotlinx.serialization.Serializable data class PinsPayload( val pins: Long, val chat: Long, -) : Payload() +) : Payload diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt index 9e663146..d59e2e30 100644 --- a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/RichPayload.kt @@ -8,4 +8,4 @@ import kotlinx.serialization.Serializable data class RichPayload( val status: String, val chat: Long, -) : Payload() +) : Payload diff --git a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt index a7365d69..349bb27b 100644 --- a/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt +++ b/shop/payload/src/main/kotlin/by/jprof/telegram/bot/shop/payload/SupportPayload.kt @@ -7,4 +7,4 @@ import kotlinx.serialization.Serializable @SerialName("support") data class SupportPayload( val chat: Long, -) : Payload() +) : Payload diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt index 5407e484..e7551cce 100644 --- a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsPreCheckoutQueryUpdateProcessor.kt @@ -3,6 +3,7 @@ package by.jprof.telegram.bot.shop import by.jprof.telegram.bot.core.UpdateProcessor import by.jprof.telegram.bot.monies.dao.MoniesDAO import by.jprof.telegram.bot.monies.model.Monies +import by.jprof.telegram.bot.shop.payload.Payload import by.jprof.telegram.bot.shop.payload.PinsPayload import by.jprof.telegram.bot.shop.utils.tooManyPins import dev.inmo.tgbotapi.bot.RequestsExecutor @@ -27,23 +28,24 @@ class PinsPreCheckoutQueryUpdateProcessor( override suspend fun process(update: Update) { val preCheckoutQuery = update.asPreCheckoutQueryUpdate()?.data ?: return - - logger.debug(preCheckoutQuery) - val payload = try { - json.decodeFromString(preCheckoutQuery.invoicePayload) + json.decodeFromString(preCheckoutQuery.invoicePayload) as PinsPayload } catch (_: Exception) { return } - logger.debug(payload) + logger.info("{}", payload) val monies = moniesDAO.get(preCheckoutQuery.user.id.chatId, payload.chat) ?: Monies(preCheckoutQuery.user.id.chatId, payload.chat) val pins = monies.pins ?: 0 if (pins > 9999) { + logger.info("{} already has enough ({}) pins!", preCheckoutQuery.user, pins) + bot.answerPreCheckoutQueryError(preCheckoutQuery, tooManyPins()) } else { + logger.info("Selling pins to {}", preCheckoutQuery.user) + bot.answerPreCheckoutQueryOk(preCheckoutQuery) } } diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsSuccessfulPaymentUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsSuccessfulPaymentUpdateProcessor.kt new file mode 100644 index 00000000..b68b6425 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/PinsSuccessfulPaymentUpdateProcessor.kt @@ -0,0 +1,51 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.monies.dao.MoniesDAO +import by.jprof.telegram.bot.monies.model.Money +import by.jprof.telegram.bot.monies.model.Monies +import by.jprof.telegram.bot.shop.payload.Payload +import by.jprof.telegram.bot.shop.payload.PinsPayload +import dev.inmo.tgbotapi.abstracts.FromUser +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate +import dev.inmo.tgbotapi.extensions.utils.asPossiblyPaymentMessage +import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.apache.logging.log4j.LogManager + +@OptIn(PreviewFeature::class) +class PinsSuccessfulPaymentUpdateProcessor( + private val bot: RequestsExecutor, + private val json: Json, + private val moniesDAO: MoniesDAO, +) : UpdateProcessor { + companion object { + private val logger = LogManager.getLogger(PinsSuccessfulPaymentUpdateProcessor::class.java)!! + } + + override suspend fun process(update: Update) { + val message = update.asMessageUpdate()?.data?.asPossiblyPaymentMessage() ?: return + val user = (message as? FromUser)?.user ?: return + val payment = (message.paymentInfo as? SuccessfulPaymentEvent)?.payment ?: return + val payload = try { + json.decodeFromString(payment.invoicePayload) as PinsPayload + } catch (_: Exception) { + return + } + + val monies = moniesDAO.get(user.id.chatId, payload.chat) ?: Monies(user.id.chatId, payload.chat) + val pins = monies.pins ?: 0 + + moniesDAO.save( + monies.copy( + monies = monies.monies + (Money.PINS to pins) + ) + ) + bot.reply(message, "Thank you for the purchase!") + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt index f329d9e2..f6a31c88 100644 --- a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichCommandUpdateProcessor.kt @@ -1,6 +1,7 @@ package by.jprof.telegram.bot.shop import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.Payload import by.jprof.telegram.bot.shop.payload.RichPayload import by.jprof.telegram.bot.shop.provider.ChatProviderTokens import by.jprof.telegram.bot.shop.utils.notAShop @@ -53,7 +54,7 @@ class RichCommandUpdateProcessor( chatId = message.chat.id, title = richInvoiceTitle(status), description = richInvoiceDescription(), - payload = json.encodeToString(RichPayload(status = status, chat = message.chat.id.chatId)), + payload = json.encodeToString(RichPayload(status = status, chat = message.chat.id.chatId)), providerToken = chatProviderToken, currency = currency, prices = listOf(item), diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt index 8f56cc48..9ade0827 100644 --- a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichPreCheckoutQueryUpdateProcessor.kt @@ -1,6 +1,7 @@ package by.jprof.telegram.bot.shop import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.Payload import by.jprof.telegram.bot.shop.payload.RichPayload import dev.inmo.tgbotapi.bot.RequestsExecutor import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryOk @@ -22,16 +23,13 @@ class RichPreCheckoutQueryUpdateProcessor( override suspend fun process(update: Update) { val preCheckoutQuery = update.asPreCheckoutQueryUpdate()?.data ?: return - - logger.debug(preCheckoutQuery) - val payload = try { - json.decodeFromString(preCheckoutQuery.invoicePayload) + json.decodeFromString(preCheckoutQuery.invoicePayload) as RichPayload } catch (_: Exception) { return } - logger.debug(payload) + logger.info("{}", payload) bot.answerPreCheckoutQueryOk(preCheckoutQuery) } diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichSuccessfulPaymentUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichSuccessfulPaymentUpdateProcessor.kt new file mode 100644 index 00000000..4c44cdcc --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/RichSuccessfulPaymentUpdateProcessor.kt @@ -0,0 +1,47 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.Payload +import by.jprof.telegram.bot.shop.payload.RichPayload +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.chat.members.setChatAdministratorCustomTitle +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage +import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate +import dev.inmo.tgbotapi.types.chat.PrivateChat +import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent +import dev.inmo.tgbotapi.types.toChatId +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.apache.logging.log4j.LogManager + +@OptIn(PreviewFeature::class) +class RichSuccessfulPaymentUpdateProcessor( + private val bot: RequestsExecutor, + private val json: Json, +) : UpdateProcessor { + companion object { + private val logger = LogManager.getLogger(RichSuccessfulPaymentUpdateProcessor::class.java)!! + } + + override suspend fun process(update: Update) { + val message = update.asMessageUpdate()?.data ?: return + val chat = message.chat as? PrivateChat ?: return + val payment = (message.asChatEventMessage()?.chatEvent as? SuccessfulPaymentEvent)?.payment ?: return + + val payload = try { + json.decodeFromString(payment.invoicePayload) as RichPayload + } catch (_: Exception) { + return + } + + bot.setChatAdministratorCustomTitle( + chatId = payload.chat.toChatId(), + userId = chat.id, + customTitle = payload.status + ) + bot.reply(message, "Thank you for the purchase!") + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt index 1e5a3e99..153b2c8b 100644 --- a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportCommandUpdateProcessor.kt @@ -1,6 +1,7 @@ package by.jprof.telegram.bot.shop import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.Payload import by.jprof.telegram.bot.shop.payload.SupportPayload import by.jprof.telegram.bot.shop.provider.ChatProviderTokens import by.jprof.telegram.bot.shop.utils.notAShop @@ -50,7 +51,7 @@ class SupportCommandUpdateProcessor( chatId = message.chat.id, title = supportInvoiceTitle(), description = supportInvoiceDescription(), - payload = json.encodeToString(SupportPayload(chat = message.chat.id.chatId)), + payload = json.encodeToString(SupportPayload(chat = message.chat.id.chatId)), providerToken = chatProviderToken, currency = currency, prices = listOf(item), diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt index 1bd81721..e1f8e1db 100644 --- a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportPreCheckoutQueryUpdateProcessor.kt @@ -1,6 +1,7 @@ package by.jprof.telegram.bot.shop import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.Payload import by.jprof.telegram.bot.shop.payload.SupportPayload import dev.inmo.tgbotapi.bot.RequestsExecutor import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryOk @@ -22,16 +23,13 @@ class SupportPreCheckoutQueryUpdateProcessor( override suspend fun process(update: Update) { val preCheckoutQuery = update.asPreCheckoutQueryUpdate()?.data ?: return - - logger.debug(preCheckoutQuery) - val payload = try { - json.decodeFromString(preCheckoutQuery.invoicePayload) + json.decodeFromString(preCheckoutQuery.invoicePayload) as SupportPayload } catch (_: Exception) { return } - logger.debug(payload) + logger.info("{}", payload) bot.answerPreCheckoutQueryOk(preCheckoutQuery) } diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt new file mode 100644 index 00000000..d3473e19 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt @@ -0,0 +1,46 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.core.UpdateProcessor +import by.jprof.telegram.bot.shop.payload.Payload +import by.jprof.telegram.bot.shop.payload.SupportPayload +import dev.inmo.tgbotapi.abstracts.FromUser +import dev.inmo.tgbotapi.bot.RequestsExecutor +import dev.inmo.tgbotapi.extensions.api.send.reply +import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate +import dev.inmo.tgbotapi.extensions.utils.asPossiblyPaymentMessage +import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent +import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.apache.logging.log4j.LogManager + +@OptIn(PreviewFeature::class) +class SupportSuccessfulPaymentUpdateProcessor( + private val bot: RequestsExecutor, + private val json: Json, +) : UpdateProcessor { + companion object { + private val logger = LogManager.getLogger(SupportSuccessfulPaymentUpdateProcessor::class.java)!! + } + + override suspend fun process(update: Update) { + logger.info("1") + val message = update.asMessageUpdate()?.data?.asPossiblyPaymentMessage() ?: return + logger.info("2") + val user = (message as? FromUser)?.user ?: return + logger.info("3") + val payment = (message.paymentInfo as? SuccessfulPaymentEvent)?.payment ?: return + logger.info("4") + val payload = try { + logger.info("5") + json.decodeFromString(payment.invoicePayload) as SupportPayload + } catch (_: Exception) { + logger.info("6") + return + } + + logger.info("7") + bot.reply(message, "Thank you for the donation!") + } +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/app.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/app.kt new file mode 100644 index 00000000..b4731bd8 --- /dev/null +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/app.kt @@ -0,0 +1,19 @@ +package by.jprof.telegram.bot.shop + +import by.jprof.telegram.bot.shop.payload.Payload +import by.jprof.telegram.bot.shop.payload.RichPayload +import by.jprof.telegram.bot.shop.payload.SupportPayload +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +fun main() { + val json = Json { + encodeDefaults = false + ignoreUnknownKeys = true + } + + val s = json.encodeToString(RichPayload(status = "status", chat = 123)) + + println(json.decodeFromString(s)) +} diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt index 65914bfc..b945c917 100644 --- a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/utils/messages.kt @@ -16,7 +16,7 @@ private val richInvoiceTitleMessages = listOf( fun richInvoiceTitle(status: String): String = MessageFormat(richInvoiceTitleMessages.random()) - .format(status) + .format(arrayOf(status)) private val richInvoiceDescriptionMessages = listOf( "Отображается в чате возле ваших сообщений" diff --git a/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeCommandUpdateProcessor.kt b/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeCommandUpdateProcessor.kt index ccfebf2b..f1ac6d59 100644 --- a/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeCommandUpdateProcessor.kt +++ b/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeCommandUpdateProcessor.kt @@ -60,7 +60,7 @@ class TimeCommandUpdateProcessor( val messageTime = Instant.ofEpochMilli(message.date.unixMillisLong).toLocalDateTime(timeZone) ?: return "" val now = Instant.now().toLocalDateTime(timeZone) ?: return "" - logger.info( + logger.debug( "Replying to {}. Author: {}. TimeZone: {}. Message time: {}, current time: {}", message, author, timeZone, messageTime, now ) @@ -91,7 +91,7 @@ class TimeCommandUpdateProcessor( val allMentions = mentionsWithTimeZones + textMentionsWithTimeZones val now = Instant.now() - logger.info( + logger.debug( "Mentions: {}. Text mentions: {}. Combined mentions with TimeZones: {}", mentions, textMentions, allMentions ) diff --git a/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeZoneCommandUpdateProcessor.kt b/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeZoneCommandUpdateProcessor.kt index 9763210d..cc29dea6 100644 --- a/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeZoneCommandUpdateProcessor.kt +++ b/times/src/main/kotlin/by/jprof/telegram/bot/times/TimeZoneCommandUpdateProcessor.kt @@ -28,7 +28,7 @@ class TimeZoneCommandUpdateProcessor( override suspend fun process(update: Update) { timeZoneParser(update)?.let { timeZone -> - logger.info("TimeZone requested: {}", timeZone) + logger.debug("TimeZone requested: {}", timeZone) when (timeZone.value) { TimeZoneValue.Unrecognized -> replyToUnrecognizedTimeZoneRequest(timeZone) From aeafc9310ecd79e9a9f52375844096418671dc65 Mon Sep 17 00:00:00 2001 From: madhead Date: Sat, 14 Jan 2023 22:31:19 +0100 Subject: [PATCH 5/6] WIP --- .deploy/lambda/lib/JProfByBotStack.ts | 5 ++++- build.gradle.kts | 6 ++++++ .../bot/english/EnglishCommandUpdateProcessor.kt | 5 ++++- .../bot/english/ExplainerUpdateProcessor.kt | 8 +++++--- .../bot/english/MotherfuckingUpdateProcessor.kt | 4 +++- .../english/UrbanWordOfTheDayUpdateProcessor.kt | 4 +++- .../bot/english/WhatWordUpdateProcessor.kt | 4 +++- .../SupportSuccessfulPaymentUpdateProcessor.kt | 7 ------- .../bot/youtube/YouTubeUpdateProcessor.kt | 15 +++++---------- 9 files changed, 33 insertions(+), 25 deletions(-) diff --git a/.deploy/lambda/lib/JProfByBotStack.ts b/.deploy/lambda/lib/JProfByBotStack.ts index 8d691d86..915523e9 100644 --- a/.deploy/lambda/lib/JProfByBotStack.ts +++ b/.deploy/lambda/lib/JProfByBotStack.ts @@ -113,6 +113,7 @@ export class JProfByBotStack extends cdk.Stack { code: lambda.Code.fromAsset('../../pins/unpin/build/libs/jprof_by_bot-pins-unpin-all.jar'), handler: 'by.jprof.telegram.bot.pins.unpin.Handler', environment: { + 'JAVA_TOOL_OPTIONS': '-Dsoftware.amazon.awssdk.http.async.service.impl=software.amazon.awssdk.http.nio.netty.NettySdkAsyncHttpService', 'LOG_THRESHOLD': 'INFO', 'TABLE_PINS': pinsTable.tableName, 'TOKEN_TELEGRAM_BOT': props.telegramToken, @@ -160,10 +161,11 @@ export class JProfByBotStack extends cdk.Stack { timeout: lambdaWebhookTimeout, maxEventAge: cdk.Duration.minutes(5), retryAttempts: 0, - memorySize: 512, + memorySize: 768, code: lambda.Code.fromAsset('../../launchers/lambda/build/libs/jprof_by_bot-launchers-lambda-all.jar'), handler: 'by.jprof.telegram.bot.launchers.lambda.JProf', environment: { + 'JAVA_TOOL_OPTIONS': '-Dsoftware.amazon.awssdk.http.async.service.impl=software.amazon.awssdk.http.nio.netty.NettySdkAsyncHttpService', 'LOG_THRESHOLD': 'INFO', 'TABLE_VOTES': votesTable.tableName, 'TABLE_YOUTUBE_CHANNELS_WHITELIST': youtubeChannelsWhitelistTable.tableName, @@ -195,6 +197,7 @@ export class JProfByBotStack extends cdk.Stack { code: lambda.Code.fromAsset('../../english/urban-dictionary-daily/build/libs/jprof_by_bot-english-urban-dictionary-daily-all.jar'), handler: 'by.jprof.telegram.bot.english.urban_dictionary_daily.Handler', environment: { + 'JAVA_TOOL_OPTIONS': '-Dsoftware.amazon.awssdk.http.async.service.impl=software.amazon.awssdk.http.nio.netty.NettySdkAsyncHttpService', 'LOG_THRESHOLD': 'INFO', 'TABLE_URBAN_WORDS_OF_THE_DAY': urbanWordsOfTheDayTable.tableName, 'TABLE_LANGUAGE_ROOMS': languageRoomsTable.tableName, diff --git a/build.gradle.kts b/build.gradle.kts index cd417b68..6577441c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,6 +29,9 @@ subprojects { withType { // Workaround for https://stackoverflow.com/q/42174572/750510 archiveBaseName.set(rootProject.name + "-" + this.project.path.removePrefix(":").replace(":", "-")) + manifest { + attributes["Multi-Release"] = true + } } withType { useJUnitPlatform { @@ -40,6 +43,9 @@ subprojects { } withType { transform(Log4j2PluginsCacheFileTransformer::class.java) + manifest { + attributes["Multi-Release"] = true + } } } } diff --git a/english/src/main/kotlin/by/jprof/telegram/bot/english/EnglishCommandUpdateProcessor.kt b/english/src/main/kotlin/by/jprof/telegram/bot/english/EnglishCommandUpdateProcessor.kt index b26997a5..515c1799 100644 --- a/english/src/main/kotlin/by/jprof/telegram/bot/english/EnglishCommandUpdateProcessor.kt +++ b/english/src/main/kotlin/by/jprof/telegram/bot/english/EnglishCommandUpdateProcessor.kt @@ -18,9 +18,12 @@ import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember import dev.inmo.tgbotapi.types.message.MarkdownV2ParseMode import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature +import dev.inmo.tgbotapi.utils.RiskFeature import io.ktor.utils.io.streams.asInput import org.apache.logging.log4j.LogManager +@OptIn(PreviewFeature::class, RiskFeature::class) class EnglishCommandUpdateProcessor( private val languageRoomDAO: LanguageRoomDAO, private val bot: RequestsExecutor, @@ -30,7 +33,7 @@ class EnglishCommandUpdateProcessor( } override suspend fun process(update: Update) { - val update = update.asBaseMessageUpdate() ?: return + @Suppress("NAME_SHADOWING") val update = update.asBaseMessageUpdate() ?: return val message = update.data.asContentMessage() ?: return val content = message.content.asTextContent() ?: return val (_, argument) = (content.textSources + null) diff --git a/english/src/main/kotlin/by/jprof/telegram/bot/english/ExplainerUpdateProcessor.kt b/english/src/main/kotlin/by/jprof/telegram/bot/english/ExplainerUpdateProcessor.kt index 7b0b0405..ad0dd1c5 100644 --- a/english/src/main/kotlin/by/jprof/telegram/bot/english/ExplainerUpdateProcessor.kt +++ b/english/src/main/kotlin/by/jprof/telegram/bot/english/ExplainerUpdateProcessor.kt @@ -28,6 +28,7 @@ import dev.inmo.tgbotapi.types.message.textsources.link import dev.inmo.tgbotapi.types.message.textsources.regular import dev.inmo.tgbotapi.types.message.textsources.underline import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature import java.time.Duration import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred @@ -36,6 +37,7 @@ import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.time.withTimeoutOrNull import org.apache.logging.log4j.LogManager +@OptIn(PreviewFeature::class) class ExplainerUpdateProcessor( private val languageRoomDAO: LanguageRoomDAO, private val urbanDictionaryClient: UrbanDictionaryClient, @@ -47,7 +49,7 @@ class ExplainerUpdateProcessor( } override suspend fun process(update: Update) { - val update = update.asBaseMessageUpdate() ?: return + @Suppress("NAME_SHADOWING") val update = update.asBaseMessageUpdate() ?: return val roomId = update.data.chat.id val message = update.data.asContentMessage() ?: return val content = message.content.asTextContent() ?: return @@ -60,7 +62,7 @@ class ExplainerUpdateProcessor( val emphasizedWords = extractEmphasizedWords(content) - logger.debug("Emphasized words: $emphasizedWords") + logger.info("Emphasized words: $emphasizedWords") val explanations = fetchExplanations(emphasizedWords) @@ -151,7 +153,7 @@ class ExplainerUpdateProcessor( private fun StringBuilder.dictionaryDotDevExplanations(dictionaryDotDevExplanations: Collection?) { dictionaryDotDevExplanations?.let { definitions -> - definitions.take(3).forEachIndexed { index, definition -> + definitions.take(3).forEachIndexed { _, definition -> val link = definition.sourceUrls?.firstOrNull() if (link != null) { diff --git a/english/src/main/kotlin/by/jprof/telegram/bot/english/MotherfuckingUpdateProcessor.kt b/english/src/main/kotlin/by/jprof/telegram/bot/english/MotherfuckingUpdateProcessor.kt index fd6394e6..493bba9f 100644 --- a/english/src/main/kotlin/by/jprof/telegram/bot/english/MotherfuckingUpdateProcessor.kt +++ b/english/src/main/kotlin/by/jprof/telegram/bot/english/MotherfuckingUpdateProcessor.kt @@ -13,10 +13,12 @@ import dev.inmo.tgbotapi.extensions.utils.asContentMessage import dev.inmo.tgbotapi.extensions.utils.asTextContent import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature import io.ktor.utils.io.streams.asInput import kotlin.random.Random import org.apache.logging.log4j.LogManager +@OptIn(PreviewFeature::class) class MotherfuckingUpdateProcessor( private val languageRoomDAO: LanguageRoomDAO, private val bot: RequestsExecutor, @@ -26,7 +28,7 @@ class MotherfuckingUpdateProcessor( } override suspend fun process(update: Update) { - val update = update.asBaseMessageUpdate() ?: return + @Suppress("NAME_SHADOWING") val update = update.asBaseMessageUpdate() ?: return val roomId = update.data.chat.id val message = update.data.asContentMessage() ?: return val content = message.content.asTextContent() ?: return diff --git a/english/src/main/kotlin/by/jprof/telegram/bot/english/UrbanWordOfTheDayUpdateProcessor.kt b/english/src/main/kotlin/by/jprof/telegram/bot/english/UrbanWordOfTheDayUpdateProcessor.kt index a91bd61e..74144a6f 100644 --- a/english/src/main/kotlin/by/jprof/telegram/bot/english/UrbanWordOfTheDayUpdateProcessor.kt +++ b/english/src/main/kotlin/by/jprof/telegram/bot/english/UrbanWordOfTheDayUpdateProcessor.kt @@ -14,9 +14,11 @@ import dev.inmo.tgbotapi.extensions.utils.asContentMessage import dev.inmo.tgbotapi.extensions.utils.asTextContent import dev.inmo.tgbotapi.types.message.MarkdownV2 import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature import java.time.LocalDate import org.apache.logging.log4j.LogManager +@OptIn(PreviewFeature::class) class UrbanWordOfTheDayUpdateProcessor( private val languageRoomDAO: LanguageRoomDAO, private val urbanWordOfTheDayDAO: UrbanWordOfTheDayDAO, @@ -27,7 +29,7 @@ class UrbanWordOfTheDayUpdateProcessor( } override suspend fun process(update: Update) { - val update = update.asBaseMessageUpdate() ?: return + @Suppress("NAME_SHADOWING") val update = update.asBaseMessageUpdate() ?: return val roomId = update.data.chat.id val message = update.data.asContentMessage() ?: return val content = message.content.asTextContent() ?: return diff --git a/english/src/main/kotlin/by/jprof/telegram/bot/english/WhatWordUpdateProcessor.kt b/english/src/main/kotlin/by/jprof/telegram/bot/english/WhatWordUpdateProcessor.kt index da13aabc..e9e541e4 100644 --- a/english/src/main/kotlin/by/jprof/telegram/bot/english/WhatWordUpdateProcessor.kt +++ b/english/src/main/kotlin/by/jprof/telegram/bot/english/WhatWordUpdateProcessor.kt @@ -11,9 +11,11 @@ import dev.inmo.tgbotapi.extensions.utils.asContentMessage import dev.inmo.tgbotapi.extensions.utils.asTextContent import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.types.update.abstracts.Update +import dev.inmo.tgbotapi.utils.PreviewFeature import io.ktor.utils.io.streams.asInput import org.apache.logging.log4j.LogManager +@OptIn(PreviewFeature::class) class WhatWordUpdateProcessor( private val languageRoomDAO: LanguageRoomDAO, private val bot: RequestsExecutor, @@ -23,7 +25,7 @@ class WhatWordUpdateProcessor( } override suspend fun process(update: Update) { - val update = update.asBaseMessageUpdate() ?: return + @Suppress("NAME_SHADOWING") val update = update.asBaseMessageUpdate() ?: return val roomId = update.data.chat.id val message = update.data.asContentMessage() ?: return val content = message.content.asTextContent() ?: return diff --git a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt index d3473e19..40d54800 100644 --- a/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt +++ b/shop/src/main/kotlin/by/jprof/telegram/bot/shop/SupportSuccessfulPaymentUpdateProcessor.kt @@ -25,22 +25,15 @@ class SupportSuccessfulPaymentUpdateProcessor( } override suspend fun process(update: Update) { - logger.info("1") val message = update.asMessageUpdate()?.data?.asPossiblyPaymentMessage() ?: return - logger.info("2") val user = (message as? FromUser)?.user ?: return - logger.info("3") val payment = (message.paymentInfo as? SuccessfulPaymentEvent)?.payment ?: return - logger.info("4") val payload = try { - logger.info("5") json.decodeFromString(payment.invoicePayload) as SupportPayload } catch (_: Exception) { - logger.info("6") return } - logger.info("7") bot.reply(message, "Thank you for the donation!") } } diff --git a/youtube/src/main/kotlin/by/jprof/telegram/bot/youtube/YouTubeUpdateProcessor.kt b/youtube/src/main/kotlin/by/jprof/telegram/bot/youtube/YouTubeUpdateProcessor.kt index ff56dc82..bac72c4c 100644 --- a/youtube/src/main/kotlin/by/jprof/telegram/bot/youtube/YouTubeUpdateProcessor.kt +++ b/youtube/src/main/kotlin/by/jprof/telegram/bot/youtube/YouTubeUpdateProcessor.kt @@ -43,7 +43,7 @@ class YouTubeUpdateProcessor( companion object { private val logger = LogManager.getLogger(YouTubeUpdateProcessor::class.java)!! private val linkRegex = - "^.*((youtu.be/)|(v/)|(/u/\\w/)|(embed/)|(watch\\?))\\??v?=?([^#&?]*).*".toRegex() + "https?://(?:m.)?(?:www\\.)?youtu(?:\\.be/|(?:be-nocookie|be)\\.com/(?:watch|\\w+\\?(?:feature=\\w+.\\w+&)?v=|v/|e/|embed/|user/(?:[\\w#]+/)+))(?[^&#?\\n]+)".toRegex() private const val ACCEPTED_DISPLAY_LEN = 500 } @@ -55,11 +55,9 @@ class YouTubeUpdateProcessor( } private suspend fun processMessage(message: Message) { - logger.debug("Processing message: {}", message) - val youTubeVideos = extractYoutubeVideos(message) ?: return - logger.debug("YouTube videos: {}", youTubeVideos) + logger.info("Detected {} YouTube videos: {}", youTubeVideos.size, youTubeVideos) supervisorScope { youTubeVideos @@ -76,20 +74,17 @@ class YouTubeUpdateProcessor( .mapNotNull { (it as? URLTextSource)?.source ?: (it as? TextLinkTextSource)?.url } - .mapNotNull { - linkRegex.matchEntire(it)?.destructured + .mapNotNull { url -> + linkRegex.matchEntire(url)?.groups?.get("id")?.value?.takeUnless { it.isBlank() } } - .map { (_, _, _, _, _, _, id) -> id } } } private suspend fun replyToYouTubeVideo(video: String, message: Message) { - logger.debug("YouTube video ID: {}", video) - val response = withContext(Dispatchers.IO) { youTube.videos().list(listOf("snippet", "statistics")).setId(listOf(video)).execute() } - val videoDetails = response.items.first() + val videoDetails = response.items.firstOrNull() ?: return val snippet = videoDetails.snippet val channelId = snippet.channelId From bb2603b994169641414b9d2c136872db5d176b18 Mon Sep 17 00:00:00 2001 From: madhead Date: Wed, 1 Feb 2023 01:03:25 +0100 Subject: [PATCH 6/6] WIP --- .deploy/lambda/lib/JProfByBotStack.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.deploy/lambda/lib/JProfByBotStack.ts b/.deploy/lambda/lib/JProfByBotStack.ts index 915523e9..5fe0aada 100644 --- a/.deploy/lambda/lib/JProfByBotStack.ts +++ b/.deploy/lambda/lib/JProfByBotStack.ts @@ -18,8 +18,8 @@ export class JProfByBotStack extends cdk.Stack { const secretPaymentProviderTokens = new secrets.Secret(this, 'jprof-by-bot-secret-payment-provider-tokens', { secretName: 'jprof-by-bot-secret-payment-provider-tokens', secretObjectValue: { - test: cdk.SecretValue.unsafePlainText('test'), - production: cdk.SecretValue.unsafePlainText('production'), + 1: cdk.SecretValue.unsafePlainText('test'), + 2: cdk.SecretValue.unsafePlainText('production'), } });