Как получить выполнение для обоих наборов кода? - PullRequest
0 голосов
/ 27 ноября 2018

Я создаю чат-бота в Dialogflow, который может выполнять различные действия (в основном я следовал нескольким учебникам, которые выпустил Dialogflow, немного переформатировал код и внес некоторые изменения в него для себя).

Код длинный, поэтому я поставлю ссылку на Github ниже.Кроме того, я использую встроенный редактор диалогового потока

Проблема / я не совсем уверен, что делать, у меня есть раздел входа пользователя (строки с 33 по 51), где пользователь может войти в свой гуглсчет через голос.

В уроках, в строке исполнения у них есть (я почти уверен, что это причина того, что это не работает):

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app)

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

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
 ..... Functions under }

Я пытался написать варианты, думая, что это могло бы работать:

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((app, request, response)

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app(request, response) 
// Syntax error

Как я мог заставить две половины кода работать вместе?Можно ли это сделать или мне нужно переформатировать это снова, или мне просто нужно сделать что-то немного другое с линией исполнения?

Спасибо за помощь!

код здесь

Примечание: В коде на Github я не изменил строку выполнения, я просто оставил ее в том виде, чтобы другие мои функции работали. Код был проверен для входа в систему и РАБОТАЕТ, он НЕ РАБОТАЕТ с другими написанными мной функциями.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Проблема в том, что две библиотеки имеют разные способы настройки прослушивателя, который обрабатывает объекты запроса / ответа, и настройки регистрации обработчика намерений.Вы не можете смешать два (как вы обнаружили).Вам нужно выбрать одну и преобразовать функции, зарегистрированные другим способом.

Чтобы сэкономить много времени на наборе текста, я буду ссылаться на библиотеку actions-on-google как aog, а также на библиотекуflowflow-Execution.as df.

Использование библиотеки actions-on-google

Вы могли бы инициализировать слушателя что-то вроде:

const app = dialogflow({
  // REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
  clientId: '<CLIENT ID>',
});

// Intent handler declarations go here

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

Преобразование диалогового потокаОбработчики в стиле -fulfillment относительно просты.Объект aog conv очень похож на объект df agent.Оба, например, имеют метод add(), который ведет себя одинаково при работе с действиями.

Объект conv также имеет свойство parameters, хотя использование второго аргумента в вызове функции является предпочтительным, оно содержит те же вещи.Точно так же у него есть свойство arguments, которое содержит то же самое, что и третий аргумент, передаваемый обработчику.

Стоит также отметить, что app.intent() не обязательно должна иметь свою функцию функции стрелкиили даже указанный в строке, как это.Вы можете написать функцию отдельно и просто передать ее в качестве параметра.

Таким образом, ваша makeAppointment() функция может быть переписана и зарегистрирована как что-то вроде

  function makeAppointment (conv) {
    // Calculate appointment start and end datetimes (end = +1hr from start)
    const dateTimeStart = new Date(Date.parse(conv.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1].split('-')[0] + timeZoneOffset));
    const dateTimeEnd = new Date(new Date(dateTimeStart).setHours(dateTimeStart.getHours() + 1));
    const appointmentTimeString = dateTimeStart.toLocaleString(
      'en-US',
      { month: 'long', day: 'numeric', hour: 'numeric', timeZone: timeZone }
    );

    // Check the availibility of the time, and make an appointment if there is time on the calendar
    return createCalendarEvent(dateTimeStart, dateTimeEnd).then(() => {
      conv.add(`Okay, I have you booked for ${appointmentTimeString}!`);
    }).catch(() => {
      conv.add(`I'm sorry, there are no slots available for ${appointmentTimeString}.`);
    });
  }
  app.intent( 'Make Appointment', makeAppointment );

Использованиебиблиотека выполнения потока диалога

Вы уже настроили слушателя и обработчик таким образом

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });

  // Declare your functions here

  let intentMap = new Map();
  // Map intent name to functions here
  agent.handleRequest(intentMap);
});

, поэтому вопрос заключается в том, как включить обработчики, которые, кажется, имеют специфическую информацию варгументы функции в df-совместимые обработчики.

У объекта df agent есть способ получить (почти) эквивалентный conv объект.Неудивительно, что это agent.getConv().В самом деле.Затем вы можете использовать свойства parameters и arguments, как указано выше, чтобы получить эквивалент второго и третьего аргументов функции.Вы будете использовать agent.add() для добавления сообщения (вы также можете использовать conv, но это немного сложнее).

Для обработчика «Get Signin» это может выглядеть примерно так:

function getSignin (agent){
  let conv = agent.getConv();
  let params = conv.parameters;
  let signin = conv.arguments;
  if (signin.status === 'OK') {
    const payload = conv.user.profile.payload;
    agent.ask(`Welcome back ${payload.name}. What do you want to do next?`);
  } else {
    agent.ask(`I won't be able to save your data, but what do you want to do next?`);
  }
}

и затем убедитесь, что вы зарегистрировали обработчик в соответствующем месте

intentMap.set('Get Signin', getSignin);
0 голосов
/ 27 ноября 2018

Похоже, вы смешиваете 2 разные версии Действия в библиотеке Google.Рекомендуется придерживаться V2, что означает замену Intent-map на намеренные обработчики.

// Intent that starts the account linking flow.
app.intent('Start Signin', conv => {
  conv.ask(new SignIn('To get your account details'));
});

// Create a Dialogflow intent with the `actions_intent_SIGN_IN` event.
app.intent('Get Signin', (conv, params, signin) => {
    if (signin.status === 'OK') {
        const payload = conv.user.profile.payload;
        conv.ask(`Welcome back ${payload.name}. What do you want to do next?`);
  } else {
      conv.ask(`I won't be able to save your data, but what do you want to do next?`);
  }
});

app.intent('Make Appointment', (conv) => {
    /* some code here */
});

app.intent('ReadFromFirestore', (conv) => {
    // Get the database collection 'dialogflow' and document 'agent'
    const dialogflowAgentDoc = db.collection('dialogflow').doc('agent');

    // Get the value of 'entry' in the document and send it to the user
    return dialogflowAgentDoc.get().then(doc => {
        if (!doc.exists) {
          conv.tell('No data found in the database!');
        } else {
          conv.ask(doc.data().entry);
        }
    }).catch(() => {
        conv.ask('Error reading entry from the Firestore database. Please add a entry to the database first by saying, "Write <your phrase> to the database"');
    });
});

app.intent('WriteToFirestore', (conv) => {
    /* some code here */
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

(методы опущены)

Объект "app" (dialogflow) уже упаковывает запроси ответные аргументы, так что вам ничего не нужно делать, чтобы мешать им.

Если вы хотите, чтобы отдельные конечные точки, вне диалогового потока, делали вещи: вы можете добавить дополнительные функции, например:

exports.someOtherFunction = functions.https.onRequest((request, response) => {
    /* do something with the request and response here */
});

Однако это не имеет непосредственного отношения к диалогу.

...