Skip to content

Commit

Permalink
feat: команда tldr
Browse files Browse the repository at this point in the history
  • Loading branch information
Djaler committed Oct 6, 2023
1 parent e78980f commit 834b9d2
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/main/kotlin/com/github/djaler/evilbot/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.github.djaler.evilbot.config.TelegramProperties
import com.github.djaler.evilbot.config.fixer.FixerApiProperties
import com.github.djaler.evilbot.config.locationiq.LocationiqApiProperties
import com.github.djaler.evilbot.config.vkcloud.VKCloudApiProperties
import com.github.djaler.evilbot.config.yandex.YandexApiProperties
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
Expand All @@ -21,7 +22,8 @@ import org.springframework.scheduling.annotation.EnableScheduling
BotProperties::class,
FixerApiProperties::class,
LocationiqApiProperties::class,
VKCloudApiProperties::class
VKCloudApiProperties::class,
YandexApiProperties::class,
)
class Application

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.github.djaler.evilbot.clients

import com.fasterxml.jackson.databind.PropertyNamingStrategy
import com.fasterxml.jackson.databind.annotation.JsonNaming
import com.github.djaler.evilbot.components.RecordBreadcrumb
import com.github.djaler.evilbot.config.yandex.YandexApiCondition
import com.github.djaler.evilbot.config.yandex.YandexApiProperties
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*
import org.springframework.context.annotation.Conditional
import org.springframework.stereotype.Component

@Component
@Conditional(YandexApiCondition::class)
@RecordBreadcrumb
class YandexGptClient(
private val httpClient: HttpClient,
private val yandexApiProperties: YandexApiProperties
) {
suspend fun generateLinkThesis(link: String, sessionId: String? = null): ThesisResult {
return httpClient.post {
url("https://300.ya.ru/api/generation")

contentType(ContentType.Application.Json)
setBody(mapOf(
"article_url" to link,
"session_id" to sessionId
))

headers {
append(HttpHeaders.Authorization, "OAuth ${yandexApiProperties.token}")
}
}.body()
}
}

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class)
data class ThesisResult(
val sessionId: String,
val pollIntervalMs: Long,
val statusCode: Int,
val thesis: List<Thesis>?
)

data class Thesis(
val content: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.djaler.evilbot.config.yandex

import org.springframework.context.annotation.Condition
import org.springframework.context.annotation.ConditionContext
import org.springframework.core.type.AnnotatedTypeMetadata

class YandexApiCondition : Condition {
override fun matches(context: ConditionContext, metadata: AnnotatedTypeMetadata): Boolean {
return context.environment.getProperty("yandex.api.token", "").isNotBlank()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.github.djaler.evilbot.config.yandex

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding

@ConfigurationProperties(prefix = "yandex.api")
@ConstructorBinding
data class YandexApiProperties(
val token: String = ""
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.github.djaler.evilbot.handlers.commands

import com.github.djaler.evilbot.clients.SentryClient
import com.github.djaler.evilbot.handlers.base.CommandHandler
import com.github.djaler.evilbot.service.YandexGptService
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.withTypingAction
import dev.inmo.tgbotapi.extensions.utils.asContentMessage
import dev.inmo.tgbotapi.extensions.utils.asURLTextSource
import dev.inmo.tgbotapi.types.chat.ExtendedBot
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.TextContent
import dev.inmo.tgbotapi.types.message.content.TextMessage
import org.apache.logging.log4j.LogManager
import org.springframework.stereotype.Component

@Component
class TlDrHandler(
private val requestsExecutor: RequestsExecutor,
private val yandexGptService: YandexGptService,
private val sentryClient: SentryClient,
botInfo: ExtendedBot
) : CommandHandler(
botInfo,
command = arrayOf("tldr"),
commandDescription = "пересказать содержимое по ссылке"
) {
companion object {
private val log = LogManager.getLogger()
}

override suspend fun handleCommand(
message: TextMessage,
args: String?
) {
val messageToReply: Message
val link: String?

val replyTo = message.replyTo
val replyMessageLink = replyTo?.asContentMessage()?.let { extractLink(it) }
if (replyMessageLink !== null) {
messageToReply = replyTo
link = replyMessageLink
} else {
messageToReply = message
link = extractLink(message)
}

if (link === null) {
requestsExecutor.reply(messageToReply, "Либо пришли ссылку, либо ответь командой на сообщение со ссылкой")
return
}

requestsExecutor.withTypingAction(message.chat) {
try {
val thesis = yandexGptService.generateLinkThesis(link)
if (thesis != null) {
requestsExecutor.reply(messageToReply, thesis)
} else {
log.warn("Empty thesis generation result")
}
} catch (e: Exception) {
log.error("Exception in thesis generation", e)
sentryClient.captureException(e)
requestsExecutor.reply(messageToReply, "Не получилось, попробуй ещё")
}
}
}

private fun extractLink(message: ContentMessage<*>): String? {
return when (val content = message.content) {
is TextContent -> content.textSources.firstNotNullOfOrNull { it.asURLTextSource()?.source }
else -> null
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.github.djaler.evilbot.service

import com.github.djaler.evilbot.clients.YandexGptClient
import kotlinx.coroutines.delay
import org.springframework.stereotype.Service

@Service
class YandexGptService(
private val yandexGptClient: YandexGptClient
) {
suspend fun generateLinkThesis(link: String): String? {
var result = yandexGptClient.generateLinkThesis(link)

while (result.statusCode == 1) {
delay(result.pollIntervalMs)
result = yandexGptClient.generateLinkThesis(link, result.sessionId)
}

return result.thesis?.joinToString(separator = "\n") { it.content }
}
}

0 comments on commit 834b9d2

Please sign in to comment.