Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CatOBot handler scripts
import com.vk.api.sdk.callback.CallbackApi
import com.vk.api.sdk.objects.messages.AudioMessage
import com.vk.api.sdk.objects.messages.Message
import groovy.transform.Canonical
import groovy.transform.builder.Builder
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import ru.progrm_jarvis.catobot.CatOBot
import ru.progrm_jarvis.catobot.ai.RecognitionResult
import ru.progrm_jarvis.catobot.image.CatImage
import ru.progrm_jarvis.catobot.util.CollectionUtil
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ExecutionException
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.function.Function
import java.util.stream.Stream
return (bot) -> {
return new VkCallbackHandler(bot)
} as Function<CatOBot, CallbackApi>
@Canonical
class VkCallbackHandler extends CallbackApi {
protected static Logger log = LoggerFactory.getLogger("VK-Handler")
protected final CatOBot bot
protected ExecutorService executor
protected Messages messages
VkCallbackHandler(final CatOBot bot) {
this.bot = bot
executor = Executors.newCachedThreadPool()
log.info("Loading messages for VK-handler")
messages = loadMessages()
log.info("Loaded messages for VK-handler: {}", messages)
}
@SuppressWarnings("GrMethodMayBeStatic")
Messages loadMessages() {
new Messages()
}
@Override
void messageNew(final Integer groupId, final Message message) {
executor.submit(() -> {
log.debug("Received VK message: {}", message)
AudioMessage audioMessage
for(attachment in message.attachments) {
attachment = attachment.audioMessage
if (attachment != null) {
audioMessage = attachment
break
}
}
CompletableFuture<Optional<RecognitionResult>> recognition
if (audioMessage != null) {
def audioStream = bot.vk.toMp3InputStream(audioMessage)
if (audioStream.present) recognition = bot.recognizer.recognizeSpeech(audioStream.get(), null)
else {
sendRandomMessage(message, messages.unavailableAudioMessage)
return
}
} else recognition = bot.recognizer.recognizeMessage(message.text, null)
recognition.whenComplete((result, x) -> {
if (result.present) {
final def entities = result.get().entities
// check if the message relates to the bot
if (message.getPeerId() >= 2000000000) {
// this means that the message is from a chat which means
// that a mention-check should be performed
// should contain `general` or `vk` mention
def mention = entities.getAsJsonArray("mention")
if (mention == null || mention.isEmpty()) return
mention = mention.get(0).asJsonObject.get("value").asString
if (mention != "general" && mention != "vk") return
}
def intent = entities .getAsJsonArray("intent")
if (intent == null || intent.empty) {
sendRandomMessage(message, messages.noIntent)
return
}
intent = intent.get(0).asJsonObject
switch (intent.get("value").asString) {
case "get_cat_images":
def imagesCount
def numberJson = entities.getAsJsonArray("number")
if (numberJson == null || numberJson.empty) imagesCount = 1
else imagesCount = Math.max(
1, Math.min(10, numberJson.get(0).asJsonObject.get("value").asInt)
)
bot.vk.sendCatImages(
message.peerId, message.id, bot.catImages.pickRandomCatImages(imagesCount, null
)
.parallelStream()
.flatMap { imageFuture ->
def image
try {
image = imageFuture.get()
} catch (InterruptedException | ExecutionException e) {
log.error("An exception occurred while getting one of the images", e)
return Stream.empty()
}
return image.map(Stream::of).orElseGet(Stream::empty)
}
.toArray() as CatImage[])
break
}
} else bot.vk.sendCatsUnavailable(message.peerId, message.id)
})
})
}
protected void sendRandomMessage(final Message message, final List<String> messages) {
final def text = CollectionUtil.getRandom(messages)
if (text.present) {
final def vk = bot.vk, peer = message.peerId
vk.client.messages()
.send(vk.groupActor)
.peerId(peer)
.randomId(vk.getRandomMessageId(peer))
.replyTo(message.id)
.message(text.get())
.execute()
}
}
@Builder
@Canonical
static class Messages {
List<String> noIntent = ["Unknown action"]
List<String> unavailableAudioMessage = ["Unavailable audio-message"]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment