Created
May 20, 2019 22:00
-
-
Save JarvisCraft/c853a1ec979234db706dedb24a1dc31b to your computer and use it in GitHub Desktop.
CatOBot handler scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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