Как исправить планирование встреч из агента Dialogflow - PullRequest
0 голосов
/ 30 марта 2019

Я пытаюсь создать чат-бот Dialogflow с помощью Node.js, и у меня возникают проблемы при создании шага предложения о встрече.До сих пор я мог заставить его назначить встречу любому временному интервалу, который попадает в рабочие часы, но когда я пытаюсь автоматически настроить входящие запросы, чтобы они попадали в рабочие часы, он корректируется в пределах кода, но не может назначить встречу.

Кажется, что в любое время dateTimeStart должен использовать путь с suggested_time, он не может назначить встречу.Времена просили, чтобы в рабочие часы работали нормально и без проблем.Я разместил console.logs в разных местах, чтобы указать, где происходит сбой кода, что и привело меня к этому моменту, но теперь все мои console.logs - то, что я получил бы, если бы код работал нормально, ноэто определенно нет.Я не был уверен, где код неисправен, поэтому я включил любую используемую функцию.

function makeAppointment (agent) {
    // Get the contexts
    const contextF = agent.context.get('firstlast');
    const contextS = agent.context.get('serviceneeded');
    const contextD = agent.context.get('datetimemeetingplaceemailphonen-followup');
    // This variable needs to hold an instance of Date object that specifies the start time of the appointment.
    let dateTimeStart;
    let dateTimeStart1;
    console.log('Entered makeAppointment');
    // If the context has 'sugguested_time' parameter, use this value instead of using 'date' and 'time' parameters.
  if (contextD.parameters.hasOwnProperty('suggested_time') && contextD.parameters.suggested_time !== '') {
        // Construct an instance of Date object using the 'suggested_time' parameter.
        console.log("suggested_time is " + contextD.parameters.suggested_time);
        dateTimeStart1 = contextD.parameters.suggested_time;
        dateTimeStart = new Date(dateTimeStart1);
        console.log("The new Date object is " + dateTimeStart);
  } else {
    // The function convertTimestampToDate() returns an instance of Date object that is constructed from 'date' and 'time' parameters.
        dateTimeStart = convertTimestampToDate(contextD.parameters.date, contextD.parameters.time);
        console.log( "Avoided suggested_time; convertTimestamp produced " + dateTimeStart);
    }
    // This variable holds the end time of the appointment, which is calculated by adding an hour to the start time.
    const dateTimeEnd = addHours(dateTimeStart, 1);
    console.log("dateTimeEnd is " + dateTimeEnd)
    // Convert the Date object into human-readable strings.
    const appointmentTimeString = getLocaleTimeString(dateTimeStart);
    const appointmentDateString = getLocaleDateString(dateTimeStart);
// set properties to variables
const appointmentLocationString = contextD.parameters.meetingPlace;
const appointmentEmail = contextD.parameters.email;
const appointmentService = contextS.parameters.ServiceNeeded;
const appointmentFullName = contextF.parameters.givenName + " " + contextF.parameters.lastName;
const appointmentFirstName = contextF.parameters.givenName;
const appointmentPhoneString = contextD.parameters.phoneNumber;
    // Delete the context 'MakeAppointment-followup'; this is the final step of the path.
    agent.context.delete('datetimemeetingplaceemailphonen-followup');
    // The createCalendarEvent() function checks the availability of the time slot and marks the time slot on Google Calendar if the slot is available.
    return createCalendarEvent(dateTimeStart, dateTimeEnd, appointmentFullName, appointmentPhoneString, appointmentLocationString, appointmentEmail, appointmentService).then(() => {
        agent.context.delete('firstlast');
        agent.context.delete('serviceneeded');
        agent.context.delete('schedule');
      agent.add(`You got it! I have your appointment scheduled on ${appointmentDateString} at ${appointmentTimeString}—we'll contact you shortly to confirm the deets! See you soon, ${appointmentFirstName}. Good-bye!`);
    }).catch(() => {
        agent.add(`Sorry, ${appointmentFirstName}, something went wrong! I couldn't book ${appointmentDateString} at ${appointmentTimeString}. Try trying again! Would you like to find the next available slot?`);
        dateTimeStart.setDate(dateTimeStart.getDate() + 1)
        agent.context.set({'name': 'datetimemeetingplaceemailphonen-suggestion', 'lifespan': 3, 'parameters': {'suggested_time': dateTimeStart}});
    });
  }

  // This function receives the date and time values from the context 'MakeAppointment-followup'
  // and calls the checkCalendarAvailablity() function to check the availability of the time slot on Google Calendar.
  function checkAppointment (agent) {
      // Get the contexts
      const contextF = agent.context.get('firstlast');
      const contextS = agent.context.get('serviceneeded');
    // This variable needs to hold an instance of Date object that specifies the start time of the appointment.
    const dateTimeStart = convertTimestampToDate(agent.parameters.date, agent.parameters.time);
    // This variable holds the end time of the appointment, which is calculated by adding an hour to the start time.
    const dateTimeEnd = addHours(dateTimeStart, 1);
    // Convert the Date object into human-readable strings.
    const appointmentTimeString = getLocaleTimeString(dateTimeStart);
    const appointmentDateString = getLocaleDateString(dateTimeStart);
    // set properties into variables
    const appointmentLocationString = agent.parameters.meetingPlace;
    const appointmentEmail = agent.parameters.email;
    const appointmentService = contextS.parameters.ServiceNeeded;
    const appointmentFullName = contextF.parameters.givenName + " " + contextF.parameters.lastName;
    const appointmentFirstName = contextF.parameters.givenName;
    const appointmentPhoneString = agent.parameters.phoneNumber;
    // The checkCalendarAvailablity() function checks the availability of the time slot.
    return checkCalendarAvailablity(dateTimeStart, dateTimeEnd).then(() => {
        // The time slot is available.
       // The function returns a response that asks for the confirmation of the date and time.
         agent.add(`Okay, ${appointmentFullName}, so you've said that you'd like your appointment on ${appointmentDateString} at ${appointmentTimeString}. We'll call ${appointmentPhoneString} and/or email ${appointmentEmail} to confirm this appointment ${appointmentLocationString} about ${appointmentService}. Did I get that right?`);
         agent.context.delete('datetimemeetingplaceemailphonen-suggestion')
     }).catch(() => {
       // The time slot is not available.
         agent.add(`Sorry, ${appointmentFirstName}, we're either booked up on ${appointmentDateString} at ${appointmentTimeString} or it falls outside our appointment hours from 9:00 AM to 5:00 PM, Mon - Fri. Huge bummer, I know =/ But we may have either that same slot available tomorrow or a 1:00pm appointment if you chose outside business hours—would you like me to check?`);
            // Create a new time slot, which is the next day or Monday the same time
            if (dateTimeStart.getDay() == 6) {
            dateTimeStart.setDate(dateTimeStart.getDate() + 2);
            agent.context.delete('datetimemeetingplaceemailphonen-followup');
            agent.context.set({'name': 'datetimemeetingplaceemailphonen-suggestion', 'lifespan': 3, 'parameters': {'suggested_time': dateTimeStart}});
          console.log(dateTimeStart);
        } else if (dateTimeStart.getHours() >= 21) {
            dateTimeStart.setHours(17);
            agent.context.delete('datetimemeetingplaceemailphonen-followup');
            agent.context.set({'name': 'datetimemeetingplaceemailphonen-suggestion', 'lifespan': 3, 'parameters': {'suggested_time': dateTimeStart}});
            console.log(dateTimeStart);
        } else if (dateTimeStart.getHours() <= 13) {
            dateTimeStart.setHours(17);
            agent.context.delete('datetimemeetingplaceemailphonen-followup');
            agent.context.set({'name': 'datetimemeetingplaceemailphonen-suggestion', 'lifespan': 3, 'parameters': {'suggested_time': dateTimeStart}});
            console.log(dateTimeStart);
        } else {
            dateTimeStart.setDate(dateTimeStart.getDate() + 1);
            // Delete the context 'MakeAppointment-followup' to return the flow of conversation to the beginning.
            agent.context.delete('datetimemeetingplaceemailphonen-followup');
            // Include the newly suggested time slot to the parameter 'suggested_time' of the context 'MakeAppointment-suggestion'
            agent.context.set({'name': 'datetimemeetingplaceemailphonen-suggestion', 'lifespan': 3, 'parameters': {'suggested_time': dateTimeStart}});
         console.log(dateTimeStart);
        }
   });
  }

  // This function is called when the user agrees to the newly suggested time slot.
  // The function receives the time slot value from the parameter 'suggested_time' of the context 'MakeAppointment-suggestion'
  // and passes the value to the parameter 'suggested_time' of the context 'MakeAppointment-followup'.
  function suggestAppointment (agent) {
    // Get the context 'MakeAppointment-suggestion'
    const suggestContext = agent.context.get('datetimemeetingplaceemailphonen-suggestion');
        // Construct an instance of Date object using the 'suggested_time' parameter.
        const dateTimeStart1 = suggestContext.parameters.suggested_time;
        const dateTimeStart2 = new Date(dateTimeStart1);
    // Convert the Date object into human-readable strings.
    const appointmentTimeString = getLocaleTimeString(dateTimeStart2);
    const appointmentDateString = getLocaleDateString(dateTimeStart2);
    // Asks for the confirmation of the date and time values.
        agent.add(`Great! How does ${appointmentDateString} at ${appointmentTimeString} sound?`);
    // Include the newly suggested time slot to the parameter 'suggested_time' of the context 'MakeAppointment-followup'.
        agent.context.set({'name': 'datetimemeetingplaceemailphonen-followup', 'lifespan': 3, 'parameters': {'suggested_time': dateTimeStart2}});
    // Delete the context 'MakeAppointment-suggestion'.
    agent.context.delete('datetimemeetingplaceemailphonen-suggestion');
    return;
  }

  // Mapping of the functions to the agent's intents.
  let intentMap = new Map();
  intentMap.set('Date Time MeetingPlace Email PhoneN', checkAppointment);
    intentMap.set('Date Time MeetingPlace Email PhoneN - yes', makeAppointment);
    intentMap.set('Date Time MeetingPlace Email PhoneN - Suggestion - yes', suggestAppointment);
  agent.handleRequest(intentMap);
});

// This function checks for the availability of the time slot, which starts at 'dateTimeStart' and ends at 'dateTimeEnd'.
// 'dateTimeStart' and 'dateTimeEnd' are instances of a Date object.
function checkCalendarAvailablity (dateTimeStart, dateTimeEnd) {
  return new Promise((resolve, reject) => {
    calendar.events.list({
      auth: serviceAccountAuth, // List events for time period
      calendarId: calendarId,
      timeMin: dateTimeStart.toISOString(),
      timeMax: dateTimeEnd.toISOString()
    }, (err, calendarResponse) => {
      // Check if there is an event already on the Calendar
      if (err || calendarResponse.data.items.length > 0) {
                reject(err || new Error('Requested time conflicts with another appointment'));
                console.log('Requested time conflicts with another appointment');
      } else if (err || dateTimeStart.getHours() >= 21) {
                reject(err || new Error('Requested time falls outside business hours'));
                console.log('Hour requested is ' + dateTimeStart.getHours());
      } else if (err || dateTimeStart.getHours() <= 13) {
                reject(err || new Error('Requested time falls outside business hours'));
                console.log('Hour requested is ' + dateTimeStart.getHours());
            } else if (err || dateTimeStart.getDay() == 0) {
                reject(err || new Error('Requested time falls outside business hours'));
                console.log('Day requested is ' + dateTimeStart.getDay());
            } else if (err || dateTimeStart.getDay() == 6) {
                reject(err || new Error('Requested time falls outside business hours'));
                console.log('Day requested is ' + dateTimeStart.getDay());
          }else {
                resolve(calendarResponse);
                console.log('checkAvailibility succeeded with ' + dateTimeStart);
      }
    });
  });
}

// This function marks the time slot on Google Calendar. The time slot on the calendar starts at 'dateTimeStart' and ends at 'dateTimeEnd'.
// 'dateTimeStart' and 'dateTimeEnd' are instances of a Date object.
function createCalendarEvent (dateTimeStart, dateTimeEnd, appointmentFullName, appointmentPhoneString, appointmentLocationString, appointmentEmail, appointmentService) {
  return new Promise((resolve, reject) => {
    console.log('createCalendarEvent has begun');
    calendar.events.list({
      auth: serviceAccountAuth, // List events for time period
      calendarId: calendarId,
        timeMin: dateTimeStart.toISOString(),
        timeMax: dateTimeEnd.toISOString()
    }, (err, calendarResponse) => {
      // Check if there is an event already on the Calendar
      if (err || calendarResponse.data.items.length > 0) {
        reject(err || new Error('Requested time conflicts with another appointment'));
        console.log('Requested time conflicts with another appointment');
        // Check for business hours
    } else if (err || dateTimeStart.getHours() >= 21) {
        reject(err || new Error('Requested time falls outside business hours'));
        console.log('Hour requested is ' + dateTimeStart.getHours());
    } else if (err || dateTimeStart.getHours() <= 13) {
        reject(err || new Error('Requested time falls outside business hours'));
        console.log('Hour requested is ' + dateTimeStart.getHours());
    } else if (err || dateTimeStart.getDay() == 0) {
        reject(err || new Error('Requested time falls outside business hours'));
        console.log('Day requested is ' + dateTimeStart.getDay());
    } else if (err || dateTimeStart.getDay() == 6) {
        reject(err || new Error('Requested time falls outside business hours'));
        console.log('Day requested is ' + dateTimeStart.getDay());
      } else {
        // Create event for the requested time period
        console.log('createCalendarEvent passed hour and day error check, now attempting to create event');
        calendar.events.insert({ auth: serviceAccountAuth,
          calendarId: calendarId,
          resource: {
           summary: 'Appsoft Appointment (Chatbot)',
           start: {
             dateTime: dateTimeStart
           },
           end: {
             dateTime: dateTimeEnd
           },
           attendees:[ {
             displayName: appointmentFullName,
             email: appointmentEmail,
           }],
           location: appointmentLocationString,
           description: 'Phone Number: ' + appointmentPhoneString + '; Service Needed: ' + appointmentService}
        }, (err, event) => {
            err ? reject(err) : resolve(event);
            console.log('The ISO strings timeMin and timeMax are ' + dateTimeStart.toISOString() + ' & ' + dateTimeEnd.toISOString());
        }
        );
      }
    });
    console.log('reached end of createCalendarEvent');
  });
}

Ожидается: неправильно запрошенная дата корректируется с учетом рабочих часов, затем назначается встреча вкалендарь.

Фактически: неправильно запрошенная дата действительно скорректирована (что подтверждается console.log), но она не может назначить встречу.

...