如何从Dialogflow代理修复约会计划

时间:2019-03-29 21:35:00

标签: node.js dialogflow chatbot

我正在尝试使用Node.js创建一个Dialogflow聊天机器人,但在创建“约会建议”步骤时遇到了麻烦。到目前为止,我可以将其分配给在工作时间内的任何时间段的约会,但是当我尝试自动将传入请求调整为在工作时间内时,它可以在代码范围内进行调整,但是无法进行约会

似乎dateTimeStart每次必须与suggested_time一起使用路径时,实际上都无法进行约会。 Times要求在营业时间内正常工作,并且没有任何问题。我将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确认),但是无法安排约会。

0 个答案:

没有答案