2.0.2 • Published 3 years ago

vk-io-question-fix v2.0.2

Weekly downloads
4
License
MIT
Repository
github
Last release
3 years ago

vk-io-question-fix

Описание

Небольшой модуль для системы "Вопрос-Ответ". Интегрируется в цепь middleware vk-io. FIX получение ответа только с того диалога, в котором вопрос был задан

npm package

Установка

npm

npm i -S vk-io-question-fix

yarn

yarn add vk-io-question-fix

Использование

JavaScript

const { VK } = require('vk-io');
const vk = new VK({
    token: process.env.TOKEN
});

const { QuestionManager } = require('vk-io-question-fix');
const questionManager = new QuestionManager();

vk.updates.use(questionManager.middleware);

vk.updates.hear('/reg', async (context) => {
    const answer = await context.question(
        'Согласны-ли Вы на обработку персональных данных?'
    );

    if (!/да|yes|согласен|конечно/i.test(answer.text)) {
        await context.send('Тогда, мы не можем совершить регистрацию');

        return;
    }

    await context.send('Отлично, тогда продолжим');

    const age = await context.question('Введите Ваш возраст');
    const email = await context.question('Введите Ваш имейл');
    const phone = await context.question('Введите Ваш номер телефона');

    await context.send(
        `Возраст: ${age.text}\nЭл. адрес: ${email.text}\nТелефон: ${phone.text}`
    );
});

vk.updates.startPolling();

TypeScript

import { VK } from 'vk-io';
const vk = new VK({
    token: process.env.TOKEN
});

import {
    QuestionManager,
    IQuestionMessageContext
} from 'vk-io-question-fix';

const questionManager = new QuestionManager();

vk.updates.use(questionManager.middleware);

/**
 * Для получения подсказок обязательно нужно присвоить
 * Интерфейс IQuestionMessageContext данному контексту
 */
vk.updates.hear('/reg', async (context: IQuestionMessageContext) => {
    const answer = await context.question(
        'Согласны-ли Вы на обработку персональных данных?'
    );

    if (!/да|yes|согласен|конечно/i.test(answer.text)) {
        await context.send('Тогда, мы не можем совершить регистрацию');

        return;
    }

    await context.send('Отлично, тогда продолжим');

    const age = await context.question('Введите Ваш возраст');
    const email = await context.question('Введите Ваш имейл');
    const phone = await context.question('Введите Ваш номер телефона');

    await context.send(
        `Возраст: ${age.text}\nЭл. адрес: ${email.text}\nТелефон: ${phone.text}`
    );
});

vk.updates.startPolling();

Метод отправки вопроса

const answer = await context.question(message, params);
ПараметрТипОписание
messagestringЗадаваемый вопрос
paramsObjectПараметры ссобщения

Ответ

ПараметрТипОписание
answerPromise\<Answer>Основной объект ответа
answer.textstringТекст сообщения
answer.payload*payload ответного сообщения (полезно при использовании клавиатуры)
answer.durationnumberВремя ответа в ms
answer.forwardsMessageForwardsCollection[]Пересланные сообщения
answer.attachmentsAttachment[]Вложения ответного сообщения

Специальные возможности

  • targetUserId - задаёт вопрос определённому пользователю

Примеры

Смоделируем ситуцию: в беседе между людьми идёт игра (викторина), и боту нужно задать вопрос одного человека другому

vk.updates.hear('/задать вопрос', async (context) => {
    const questionToUser = await context.question(
        'Напишите свой вопрос следующим сообщением'
    );

    const recipient = await context.question(
        'Теперь отправьте ссылку пользователя, кому нужно задать вопрос'
    );

    const user = await vk.snippets.resolveResource(recipient.text);

    const userAnswer = await context.question(
        `@id${user.id}, Вам вопрос: ${questionToUser.text}\n\nОтвет дайте следующим сообщением`,
        {
            targetUserId: user.id
        }
    );

    await context.send(`Итак, Ваш ответ: ${userAnswer.text}`);

    /*
     * Тут сами придумываете логику, это был лишь грубый и наглядный пример
     */
});

Проще говоря, бот будет ждать ответа именно от пользователя, айди которого был указан в targetUserId.

По умолчанию вопрос задаётся отправителю сообщения (context.senderId)


Ещё можно сделать что-то типа анонимных сообщений с получением реакции:

vk.updates.hear(/^(?:\/anon)\s*(?<text>.*)/i, async (context) => {
    let { text } = context.$match.groups;

    if (!text) {
        text = (await context.question(
            'Напишите текст анонимного сообщения'
        )).text;
    }

    const recipient = await context.question(
        'Теперь отправьте ссылку пользователя, кому нужно отправить анонимное сообщение'
    );

    const user = await vk.snippets.resolveResource(recipient.text);

    const userAnswer = await context.question(
        `Вам анонимное сообщение:\n\n${text}`,
        {
            user_id: user.id, // Отправить сообщение в ЛС этому пользователю
            targetUserId: user.id // Ожидать ответ от него же
        }
    );

    await context.send(
        `@id${user.id} ответил "${userAnswer.text}"`
    );
});
  • Получение payload

Примеры

Давайте на команду /choice давать пользователю выбор из двух цветов, по нажатию на любую из которых, он получит факт о выбранном цвете

const { Keyboard } = require('vk-io');

vk.updates.hear('/choice', async (context) => {
    const answer = await context.question(
        'Зелёный или синий?',
        {
            keyboard: Keyboard.keyboard([
                [
                    Keyboard.textButton({
                        label: 'Зелёный',
                        color: 'positive',
                        payload: {
                            choice: 'green'
                        }
                    }),
                    Keyboard.textButton({
                        label: 'Синий',
                        color: 'positive',
                        payload: {
                            choice: 'blue'
                        }
                    })
                ]
            ]).oneTime()
        }
    );

    if (!answer.payload) {
        await context.send('Отвечать нужно было нажатием на кнопку');

        return;
    }

    if (answer.payload.choice === 'green') {
        await context.send('Человеский глаз наиболее хорошо различает оттенки именно зеленого цвета.');

        return;
    }

    if (answer.payload.choice === 'blue') {
        await context.send('Синий краситель долгое время был одним из самых дорогих, потому что его изготавливали из лазурита.');

        return;
    }
});
  • attachments

Примеры

Мы можем получать в ответ любое вложение. Например давайте сделаем функцию обработки фотографии:

vk.updates.hear('/обработка фото', async (context) => {
    const answer = await context.question(
        'Отправьте фото, которое хотите обработать'
    );

    const filter = await context.question(
        'Теперь название фильтра *список доступных фильтров*'
    );

    const newPhoto = await myAwesomeFunction(
        answer.attachments[0].largePhoto, filter
    );

    await context.sendPhoto(newPhoto, {
        message: 'Вот твоя новая фотография!'
    });
});

Такая же история работает и с Answer.forwards