Skip to content

Shop #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft

Shop #43

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions .deploy/lambda/lib/JProfByBotStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -13,6 +15,14 @@ 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', {
secretName: 'jprof-by-bot-secret-payment-provider-tokens',
secretObjectValue: {
1: cdk.SecretValue.unsafePlainText('test'),
2: cdk.SecretValue.unsafePlainText('production'),
}
});

const votesTable = new dynamodb.Table(this, 'jprof-by-bot-table-votes', {
tableName: 'jprof-by-bot-table-votes',
partitionKey: {name: 'id', type: dynamodb.AttributeType.STRING},
Expand Down Expand Up @@ -103,7 +113,8 @@ 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',
'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,
},
Expand All @@ -123,13 +134,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.X86_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.X86_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', {
Expand All @@ -138,15 +156,17 @@ export class JProfByBotStack extends cdk.Stack {
layers: [
layerLibGL,
layerLibfontconfig,
layerParametersAndSecretsLambdaExtension,
],
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: {
'LOG_THRESHOLD': 'DEBUG',
'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,
'TABLE_KOTLIN_MENTIONS': kotlinMentionsTable.tableName,
Expand Down Expand Up @@ -177,7 +197,8 @@ 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',
'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,
'TOKEN_TELEGRAM_BOT': props.telegramToken,
Expand All @@ -198,6 +219,8 @@ export class JProfByBotStack extends cdk.Stack {
],
});

secretPaymentProviderTokens.grantRead(lambdaWebhook);

votesTable.grantReadWriteData(lambdaWebhook);

youtubeChannelsWhitelistTable.grantReadData(lambdaWebhook);
Expand Down
2 changes: 2 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
6 changes: 6 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ subprojects {
withType<Jar> {
// Workaround for https://stackoverflow.com/q/42174572/750510
archiveBaseName.set(rootProject.name + "-" + this.project.path.removePrefix(":").replace(":", "-"))
manifest {
attributes["Multi-Release"] = true
}
}
withType<Test> {
useJUnitPlatform {
Expand All @@ -40,6 +43,9 @@ subprojects {
}
withType<ShadowJar> {
transform(Log4j2PluginsCacheFileTransformer::class.java)
manifest {
attributes["Multi-Release"] = true
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
8 changes: 8 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -60,7 +62,7 @@ class ExplainerUpdateProcessor(

val emphasizedWords = extractEmphasizedWords(content)

logger.debug("Emphasized words: $emphasizedWords")
logger.info("Emphasized words: $emphasizedWords")

val explanations = fetchExplanations(emphasizedWords)

Expand Down Expand Up @@ -151,7 +153,7 @@ class ExplainerUpdateProcessor(

private fun StringBuilder.dictionaryDotDevExplanations(dictionaryDotDevExplanations: Collection<Word>?) {
dictionaryDotDevExplanations?.let { definitions ->
definitions.take(3).forEachIndexed { index, definition ->
definitions.take(3).forEachIndexed { _, definition ->
val link = definition.sourceUrls?.firstOrNull()

if (link != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -128,6 +128,6 @@ class KotlinMentionsUpdateProcessor(
replyToMessageId = message.messageId,
)

logger.info("Kotlin mention reported!")
logger.debug("Kotlin mention reported!")
}
}
3 changes: 3 additions & 0 deletions launchers/lambda/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -45,6 +46,7 @@ class JProf : RequestHandler<APIGatewayV2HTTPEvent, APIGatewayV2HTTPResponse>, K
init {
startKoin {
modules(
secretsModule,
envModule,
databaseModule,
jsonModule,
Expand All @@ -64,10 +66,11 @@ class JProf : RequestHandler<APIGatewayV2HTTPEvent, APIGatewayV2HTTPResponse>, 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)

Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -42,4 +48,14 @@ val envModule = module {
single(named(TIMEOUT)) {
System.getenv(TIMEOUT)!!.toLong()
}

single<ChatProviderTokens> {
val json: Json = get()
val secrets: SecretsManagerClient = get()
val secret = secrets.getSecretValue {
it.secretId(SECRET_PAYMENT_PROVIDER_TOKENS)
}

json.decodeFromString(secret.secretString())
}
}
Loading